mqd_t msg_q;
struct mq_attr mqattr;
- if ((msg_q = http_server_mq_open(server->port)) < 0) {
+ if ((msg_q = http_server_mq_open(server->port)) == NULL) {
HTTP_LOGE("msg queue open fail in http_handle_client\n");
return NULL;
}
return NULL;
}
+
struct http_client_t *http_client_init(struct http_server_t *server, int sock_fd)
{
struct http_client_t *p = (struct http_client_t *)HTTP_MALLOC(sizeof(struct http_client_t));
return NULL;
}
+ memset(p, 0, sizeof(struct http_client_t));
+
p->client_fd = sock_fd;
p->server = server;
return HTTP_OK;
}
-int http_parse_message(char *buf, int buf_len, int *method, char *url, char **body, int *enc, int *state, struct http_message_len_t *len, struct http_keyvalue_list_t *params, struct http_client_t *client, struct http_client_response_t *response)
+int http_parse_message(char *buf, int buf_len, int *method, char *url,
+ char **body, int *enc, int *state,
+ struct http_message_len_t *len,
+ struct http_keyvalue_list_t *params,
+ struct http_client_t *client,
+ struct http_client_response_t *response,
+ struct http_req_message *req)
{
int protocol = 0;
int sentence_end = 0;
*/
http_separate_header(buf + len->sentence_start, method, url, &protocol);
- HTTP_LOGD("Request Method : %s\n", (*method == HTTP_METHOD_GET) ? "GET" : (*method == HTTP_METHOD_PUT) ? "PUT" : (*method == HTTP_METHOD_POST) ? "POST" : (*method == HTTP_METHOD_DELETE) ? "DELETE" : "UNKNOWN");
+ HTTP_LOGD(
+ "Request Method : %s\n",
+ (*method == HTTP_METHOD_GET) ? "GET" :
+ (*method == HTTP_METHOD_PUT) ? "PUT" :
+ (*method == HTTP_METHOD_POST) ? "POST" :
+ (*method == HTTP_METHOD_DELETE) ?
+ "DELETE" : "UNKNOWN");
+ req->method = *method;
HTTP_LOGD("Request URI : %s\n", url);
- HTTP_LOGD("Request Protocol : %d\n", protocol);
- } else { /* If this is called by webclient */
-
+ HTTP_LOGD("Request Protocol : ");
+ if (protocol == HTTP_HTTP_VERSION_09) {
+ HTTP_LOGD("HTTP/0.9\n");
+ } else if (protocol == HTTP_HTTP_VERSION_10) {
+ HTTP_LOGD("HTTP/1.0\n");
+ } else if (protocol == HTTP_HTTP_VERSION_11) {
+ HTTP_LOGD("HTTP/1.1\n");
+ } else {
+ HTTP_LOGD("unknown version\n");
+ }
+ } else { /* If this is called by webclient */
http_separate_status_line(buf + len->sentence_start, &protocol, &response->status, response->phrase);
HTTP_LOGD("Response Status : %d\n", response->status);
HTTP_LOGD("Response Phrase : %s\n", response->phrase);
sentence_end = http_find_first_crlf(buf, buf_len, len->sentence_start);
if (sentence_end >= 0) {
buf[sentence_end] = '\0';
-
if (strlen(buf + len->sentence_start) > 0) {
/* Read parameters */
http_separate_keyvalue(buf + len->sentence_start, key, value);
HTTP_LOGD("This request contains contents, length : %d\n", len->content_len);
}
- if ((strcmp(key, "Transfer-Encoding") == 0) && (strcmp(value, "chunked") == 0)) {
+ if (strcmp(key, "Transfer-Encoding") == 0 && strcmp(value, "chunked") == 0) {
if (client) {
len->chunked_remain = 0;
len->entity_len = 0;
return HTTP_ERROR;
}
*enc = HTTP_CHUNKED_ENCODING;
+ req->encoding = *enc;
*body = entity;
HTTP_LOGD("This request contains chunked encoding contents\n");
} else {
break;
case HTTP_REQUEST_BODY:
+ if (client && *method != HTTP_METHOD_POST && *method != HTTP_METHOD_PUT) {
+ read_finish = true;
+ return read_finish;
+ }
/* Content length */
if (len->sentence_start < 0 || sentence_end < 0) {
HTTP_LOGE("Error: Wrong sentence arrange\n");
/* Chunked encoding */
else {
int i, j, cha;
-
if (!len->chunked_remain) {
len->content_len = 0;
sentence_end = http_find_first_crlf(buf, buf_len, len->sentence_start);
if (sentence_end < 0) {
HTTP_LOGE("Error: Cannot find body\n");
+ process_finish = true;
+ read_finish = true;
break;
}
len->content_len += cha;
}
len->chunked_remain = len->content_len;
+ if (!len->chunked_remain) {
+ HTTP_LOGD("Chunked size is zero\n");
+ entity[len->entity_len] = '\0';
+ req->entity = entity + len->entity_len;
+ http_dispatch_url(client, req);
+ read_finish = true;
+ return read_finish;
+ }
len->sentence_start = sentence_end + 2;
}
-
i = 0;
if (len->chunked_remain > 0) {
for (i = 0; len->chunked_remain > 0; ++i) {
entity[i + len->entity_len] = *(buf + len->sentence_start++);
--len->chunked_remain;
}
+ len->entity_len += i;
}
if (!len->chunked_remain) {
- entity[i + len->entity_len] = '\0';
+ entity[len->entity_len] = '\0';
+ req->entity = entity + len->entity_len - len->content_len;
+ http_dispatch_url(client, req);
len->sentence_start += 2;
sentence_end = http_find_first_crlf(buf, buf_len + len->message_len, len->sentence_start);
if (sentence_end < 0) {
}
len->sentence_start = sentence_end + 2;
if (*(buf + sentence_end - 1) == '0') {
+ req->entity = entity + len->entity_len;
+ http_dispatch_url(client, req);
process_finish = true;
read_finish = true;
}
break;
}
}
-
return read_finish;
}
char *buf;
int len = 0;
char *body = NULL;
- bool read_finish = false;
+ int read_finish = false;
int method = HTTP_METHOD_UNKNOWN;
char url[HTTP_CONF_MAX_REQUEST_HEADER_URL_LENGTH] = { 0, };
int enc = HTTP_CONTENT_LENGTH;
struct http_req_message req;
int state = HTTP_REQUEST_HEADER;
- struct http_message_len_t mlen = { 0, };
+ struct http_message_len_t mlen = {0,};
struct sockaddr_in addr;
socklen_t addr_len;
return HTTP_ERROR;
}
+ if (getpeername(client->client_fd, (struct sockaddr *)&addr, &addr_len) < 0) {
+ HTTP_LOGE("Error: Fail to getpeername\n");
+ goto errout;
+ }
+ req.req_msg = buf;
+ req.url = url;
+ req.headers = request_params;
+ req.client_ip = addr.sin_addr.s_addr;
+
while (!read_finish) {
if (remain <= 0) {
HTTP_LOGE("Error: Request size is too large!!\n");
buf_len += len;
remain -= len;
- read_finish = http_parse_message(buf, len, &method, url, &body, &enc, &state, &mlen, request_params, client, NULL);
+ read_finish = http_parse_message(buf, len, &method, url, &body, &enc, &state, &mlen, request_params, client, NULL, &req);
if (read_finish == HTTP_ERROR) {
goto errout;
}
goto errout;
}
- if (getpeername(client->client_fd, (struct sockaddr *)&addr, &addr_len) < 0) {
- HTTP_LOGE("Error: Fail to getpeername\n");
- goto errout;
+ if (enc == HTTP_CONTENT_LENGTH) {
+ req.entity = body;
+ http_dispatch_url(client, &req);
}
- req.req_msg = buf;
- req.method = method;
- req.client_ip = addr.sin_addr.s_addr;
- req.url = url;
- req.headers = request_params;
- req.entity = body;
- http_dispatch_url(client, &req);
-
#ifdef CONFIG_NETUTILS_WEBSOCKET
/* open websocket */
if (client->ws_state >= MIN_WS_HEADER_FIELD) {
ws->tls_ssl = (mbedtls_ssl_context *)malloc(sizeof(mbedtls_ssl_context));
memcpy(ws->tls_ssl, &client->tls_ssl, sizeof(mbedtls_ssl_context));
ws->tls_conf = &client->server->tls_conf;
+ mbedtls_ssl_set_bio(ws->tls_ssl, &ws->tls_net, mbedtls_net_send, mbedtls_net_recv, NULL);
}
#endif
pthread_attr_init(&ws->thread_attr);
pthread_attr_setstacksize(&ws->thread_attr, WEBSOCKET_STACKSIZE);
pthread_attr_setschedpolicy(&ws->thread_attr, SCHED_RR);
- if (pthread_create(&ws->thread_id, &ws->thread_attr, (pthread_startroutine_t)websocket_server_init, (pthread_addr_t)ws) != 0) {
+ if (pthread_create(&ws->thread_id, &ws->thread_attr,
+ (pthread_startroutine_t)websocket_server_init,
+ (pthread_addr_t)ws) != 0) {
HTTP_LOGE("Error: Cannot create websocket thread!!\n");
goto errout;
}
if (enc == HTTP_CHUNKED_ENCODING) {
HTTP_FREE(body);
}
-
return HTTP_OK;
-
- errout:
+errout:
close(client->client_fd);
HTTP_FREE(buf);
if (enc == HTTP_CHUNKED_ENCODING) {
HTTP_FREE(body);
}
-
return HTTP_ERROR;
}
{
FILE *f;
char path[HTTP_CONF_MAX_REQUEST_HEADER_URL_LENGTH + 1] = ".";
- int ref, valid = 1;
+ int ref;
+ int valid = 1;
switch (method) {
case HTTP_METHOD_GET:
/* Need to create file with unique file name */
strncat(path, url, HTTP_CONF_MAX_REQUEST_HEADER_URL_LENGTH);
strncat(path, "index.shtml", HTTP_CONF_MAX_REQUEST_HEADER_URL_LENGTH);
-
if (valid && (f = fopen(path, "w"))) {
- fputs(entity, f);
-
+ if (fputs(entity, f) < 0) {
+ HTTP_LOGE("Error: Fail to execute fputs\n");
+ fclose(f);
+ break;
+ }
if (http_send_response(client, 200, path, NULL) == HTTP_ERROR) {
HTTP_LOGE("Error: Fail to send response\n");
}
} else
valid = 1;
if (valid && (f = fopen(strncat(path, url, HTTP_CONF_MAX_REQUEST_HEADER_URL_LENGTH), "w"))) {
- fputs(entity, f);
-
+ if (fputs(entity, f) < 0) {
+ HTTP_LOGE("Error: Fail to execute fputs\n");
+ fclose(f);
+ break;
+ }
if (http_send_response(client, 200, url, NULL) == HTTP_ERROR) {
HTTP_LOGE("Error: Fail to send response\n");
}
int http_send_response(struct http_client_t *client, int status, const char *body, struct http_keyvalue_list_t *headers)
{
char *buf;
- int buflen = 0;
- int ret;
- int sndlen;
+ int buflen = 0, ret, sndlen;
struct http_keyvalue_t *cur = NULL;
buf = HTTP_MALLOC(HTTP_CONF_MAX_REQUEST_LENGTH);
}
#ifdef CONFIG_NETUTILS_WEBSOCKET
if (client->ws_state >= MIN_WS_HEADER_FIELD) {
- unsigned char accept_key[WEBSOCKET_ACCEPT_KEY_LEN] = { 0, };
+ unsigned char accept_key[WEBSOCKET_ACCEPT_KEY_LEN] = {0, };
websocket_create_accept_key(accept_key, WEBSOCKET_ACCEPT_KEY_LEN, client->ws_key, WEBSOCKET_CLIENT_KEY_LEN);
- buflen = snprintf(buf, HTTP_CONF_MAX_REQUEST_LENGTH, "HTTP/1.1 101 Switching Protocols\r\n" "Upgrade: websocket\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Accept: %s\r\n\r\n", accept_key);
+ buflen = snprintf(buf, HTTP_CONF_MAX_REQUEST_LENGTH,
+ "HTTP/1.1 101 Switching Protocols\r\n"
+ "Upgrade: websocket\r\n"
+ "Connection: Upgrade\r\n"
+ "Sec-WebSocket-Accept: %s\r\n\r\n",
+ accept_key);
} else
#endif
{
- buflen = snprintf(buf, HTTP_CONF_MAX_REQUEST_LENGTH, "HTTP/1.1 %d %s\r\n", status, (status == 200) ? "OK" : body);
+ buflen = snprintf(buf, HTTP_CONF_MAX_REQUEST_LENGTH, "HTTP/1.1 %d %s\r\n",
+ status, (status == 200) ? "OK" : body);
if (headers) {
cur = headers->head->next;
while (cur != headers->tail) {
- buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen, "%s: %s\r\n", cur->key, cur->value);
+ buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen,
+ "%s: %s\r\n", cur->key, cur->value);
cur = cur->next;
}
}
if (status == 200) {
if (headers == NULL) {
- buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen, "Content-type: text/html\r\n" "Connection: close\r\n");
+ buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen,
+ "Content-type: text/html\r\n"
+ "Connection: close\r\n");
if (body) {
- buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen, "Content-Length: %d\r\n" "\r\n" "%s", strlen(body), body);
+ buflen += snprintf(buf + buflen,
+ HTTP_CONF_MAX_REQUEST_LENGTH - buflen,
+ "Content-Length: %d\r\n"
+ "\r\n"
+ "%s",
+ strlen(body), body);
} else {
- buflen += snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen, "\r\n");
+ buflen += snprintf(buf + buflen,
+ HTTP_CONF_MAX_REQUEST_LENGTH - buflen,
+ "\r\n");
}
} else {
- snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen, "\r\n%s", body);
+ snprintf(buf + buflen, HTTP_CONF_MAX_REQUEST_LENGTH - buflen,
+ "\r\n%s", body);
}
}
}
}
}
HTTP_FREE(buf);
-
return HTTP_OK;
}
-
-