Revert the some changes #284
authorHeejin Kim <hj_elena.kim@samsung.com>
Wed, 19 Jul 2017 05:26:39 +0000 (14:26 +0900)
committerHeejin Kim <hj_elena.kim@samsung.com>
Thu, 20 Jul 2017 05:30:50 +0000 (14:30 +0900)
To clarify the function's meaning, some changes is reverted from #284.

apps/netutils/webserver/http_client.c

index 979950b..f5b0ca1 100644 (file)
@@ -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;
 }
-
-