From bde4d4debef355e1794c90b4b531f43c773c61fd Mon Sep 17 00:00:00 2001 From: Jose Marcial Vieira Bisneto Date: Sun, 23 Jul 2017 22:24:14 -0300 Subject: [PATCH] Initial handling of http request structure. --- core/api.c | 77 +++++++++++++++++++++++++++++++++-------- include/ipfs/core/api.h | 29 ++++++++++++++++ 2 files changed, 91 insertions(+), 15 deletions(-) diff --git a/core/api.c b/core/api.c index cb69c6b..dde67fd 100644 --- a/core/api.c +++ b/core/api.c @@ -28,8 +28,11 @@ void *api_connection_thread (void *ptr) { int timeout, s, r; const INT_TYPE i = (INT_TYPE) ptr; - char buf[MAX_READ+1]; + char buf[MAX_READ+1], *p; char client[INET_ADDRSTRLEN]; + struct s_request req; + + req.buf = NULL; // sanity. buf[MAX_READ] = '\0'; @@ -46,23 +49,67 @@ void *api_connection_thread (void *ptr) goto quit; } buf[r] = '\0'; - if (cstrstart(buf, "GET ")) { - // just an error message, because it's not used. - write_cstr (s, "HTTP/1.1 404 Not Found\r\n" - "Content-Type: text/plain; charset=utf-8\r\n" - "X-Content-Type-Options: nosniff\r\n" - "Content-Length: 19\r\n\r\n" - "404 page not found\n"); - //} else if (cstrstart(buf, "POST ")) { - // TODO: Handle chunked/gzip/form-data/json POST requests. + + p = strstr(buf, "\r\n\r\n"); + + if (p) { + req.size = p - buf + 1; + req.buf = malloc(req.size); + if (!req.buf) { + // memory allocation fail. + libp2p_logger_error("api", "malloc fail.\n"); + write_cstr (s, HTTP_500); + goto quit; + } + memcpy(req.buf, buf, req.size - 1); + req.buf[req.size-1] = '\0'; + + req.method = req.buf; + p = strchr(req.method, ' '); + if (!p) { + write_cstr (s, HTTP_400); + goto quit; + } + *p++ = '\0'; // End of method. + req.path = p; + p = strchr(req.path, ' '); + if (!p) { + write_cstr (s, HTTP_400); + goto quit; + } + *p++ = '\0'; // End of path. + req.http_ver = p; + p = strchr(req.http_ver, '\r'); + if (!p) { + write_cstr (s, HTTP_400); + goto quit; + } + *p++ = '\0'; // End of http version. + while (*p == '\r' || *p == '\n') p++; + req.header = p; + req.body = req.buf + req.size; + req.body_size = 0; + + libp2p_logger_error("api", "method = '%s'\n" + "path = '%s'\n" + "http_ver = '%s'\n" + "header {\n%s\n}\n" + "body_size = %d\n", + req.method, req.path, req.http_ver, req.header, req.body_size); + + if (strcmp(req.method, "GET")==0) { + // just an error message, because it's not used. + write_cstr (s, HTTP_404); + //} else if (cstrstart(buf, "POST ")) { + // TODO: Handle chunked/gzip/form-data/json POST requests. + } } else { - write_cstr (s, "HTTP/1.1 400 Bad Request\r\n" - "Content-Type: text/plain\r\n" - "Connection: close\r\n\r\n" - "400 Bad Request"); + write_cstr (s, HTTP_400); } quit: + if (req.buf) + free(req.buf); if (inet_ntop(AF_INET, &(api_list.conns[i]->ipv4), client, INET_ADDRSTRLEN) == NULL) strcpy(client, "UNKNOW"); libp2p_logger_error("api", "Closing client connection %s:%d (%d).\n", client, api_list.conns[i]->port, i+1); @@ -138,7 +185,6 @@ void *api_listen_thread (void *ptr) } if (inet_ntop(AF_INET, &ipv4, client, INET_ADDRSTRLEN) == NULL) strcpy(client, "UNKNOW"); - libp2p_logger_error("api", "Accept connection %s:%d (%d/%d), pthread %d.\n", client, port, conns_count, api_list.max_conns, i+1); api_list.conns[i]->socket = s; api_list.conns[i]->ipv4 = ipv4; api_list.conns[i]->port = port; @@ -151,6 +197,7 @@ void *api_listen_thread (void *ptr) } else { conns_count++; } + libp2p_logger_error("api", "Accept connection %s:%d (%d/%d), pthread %d.\n", client, port, conns_count, api_list.max_conns, i+1); pthread_mutex_unlock(&conns_lock); } api_connections_cleanup (); diff --git a/include/ipfs/core/api.h b/include/ipfs/core/api.h index 1c749eb..663f797 100644 --- a/include/ipfs/core/api.h +++ b/include/ipfs/core/api.h @@ -22,6 +22,35 @@ struct s_list { } **conns; }; +struct s_request { + char *buf; + size_t size; + + char *method; + char *path; + char *http_ver; + char *header; + char *body; + size_t body_size; +}; + +#define HTTP_400 "HTTP/1.1 400 Bad Request\r\n" \ + "Content-Type: text/plain\r\n" \ + "Connection: close\r\n\r\n" \ + "400 Bad Request" + + +#define HTTP_404 "HTTP/1.1 404 Not Found\r\n" \ + "Content-Type: text/plain; charset=utf-8\r\n" \ + "X-Content-Type-Options: nosniff\r\n" \ + "Content-Length: 19\r\n\r\n" \ + "404 page not found\n" + +#define HTTP_500 "HTTP/1.1 500 Internal server error\r\n" \ + "Content-Type: text/plain\r\n" \ + "Connection: close\r\n\r\n" \ + "500 Internal server error" + #define write_cstr(f,s) write(f,s,sizeof(s)-1) #define write_str(f,s) write(f,s,strlen(s))