From cadbed7b3b1051ebeb64a244fd72dd779fca2083 Mon Sep 17 00:00:00 2001 From: Heejin Kim Date: Wed, 19 Jul 2017 14:26:39 +0900 Subject: [PATCH] Revert the some changes #284 To clarify the function's meaning, some changes is reverted from #284. --- apps/netutils/webserver/http_client.c | 161 +++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 51 deletions(-) diff --git a/apps/netutils/webserver/http_client.c b/apps/netutils/webserver/http_client.c index 979950b..f5b0ca1 100644 --- a/apps/netutils/webserver/http_client.c +++ b/apps/netutils/webserver/http_client.c @@ -45,7 +45,7 @@ pthread_addr_t http_handle_client(pthread_addr_t arg) 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; } @@ -113,6 +113,7 @@ pthread_addr_t http_handle_client(pthread_addr_t arg) 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)); @@ -120,6 +121,8 @@ struct http_client_t *http_client_init(struct http_server_t *server, int sock_fd return NULL; } + memset(p, 0, sizeof(struct http_client_t)); + p->client_fd = sock_fd; p->server = server; @@ -138,7 +141,13 @@ int http_client_release(struct http_client_t *client) 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; @@ -168,11 +177,26 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo */ 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); @@ -189,7 +213,6 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo 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); @@ -212,7 +235,7 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo 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; @@ -222,6 +245,7 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo return HTTP_ERROR; } *enc = HTTP_CHUNKED_ENCODING; + req->encoding = *enc; *body = entity; HTTP_LOGD("This request contains chunked encoding contents\n"); } else { @@ -238,6 +262,10 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo 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"); @@ -262,13 +290,14 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo /* 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; } @@ -286,9 +315,16 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo 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) { @@ -301,10 +337,13 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo 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) { @@ -314,6 +353,8 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo } 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; } @@ -322,7 +363,6 @@ int http_parse_message(char *buf, int buf_len, int *method, char *url, char **bo break; } } - return read_finish; } @@ -331,7 +371,7 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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, }; @@ -340,7 +380,7 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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; @@ -353,6 +393,15 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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"); @@ -376,7 +425,7 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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; } @@ -385,19 +434,11 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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) { @@ -416,12 +457,15 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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; } @@ -437,16 +481,13 @@ int http_recv_and_handle_request(struct http_client_t *client, struct http_keyva 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; } @@ -454,7 +495,8 @@ void http_handle_file(struct http_client_t *client, int method, const char *url, { 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: @@ -480,10 +522,12 @@ void http_handle_file(struct http_client_t *client, int method, const char *url, /* 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"); } @@ -503,8 +547,11 @@ void http_handle_file(struct http_client_t *client, int method, const char *url, } 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"); } @@ -541,9 +588,7 @@ void http_handle_file(struct http_client_t *client, int method, const char *url, 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); @@ -553,31 +598,48 @@ int http_send_response(struct http_client_t *client, int status, const char *bod } #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); } } } @@ -603,8 +665,5 @@ int http_send_response(struct http_client_t *client, int status, const char *bod } } HTTP_FREE(buf); - return HTTP_OK; } - - -- 2.7.4