Initial handling of http request structure.

This commit is contained in:
Jose Marcial Vieira Bisneto 2017-07-23 22:24:14 -03:00
parent f7ddfa0088
commit bde4d4debe
2 changed files with 91 additions and 15 deletions

View file

@ -28,8 +28,11 @@ void *api_connection_thread (void *ptr)
{ {
int timeout, s, r; int timeout, s, r;
const INT_TYPE i = (INT_TYPE) ptr; const INT_TYPE i = (INT_TYPE) ptr;
char buf[MAX_READ+1]; char buf[MAX_READ+1], *p;
char client[INET_ADDRSTRLEN]; char client[INET_ADDRSTRLEN];
struct s_request req;
req.buf = NULL; // sanity.
buf[MAX_READ] = '\0'; buf[MAX_READ] = '\0';
@ -46,23 +49,67 @@ void *api_connection_thread (void *ptr)
goto quit; goto quit;
} }
buf[r] = '\0'; buf[r] = '\0';
if (cstrstart(buf, "GET ")) {
// just an error message, because it's not used. p = strstr(buf, "\r\n\r\n");
write_cstr (s, "HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/plain; charset=utf-8\r\n" if (p) {
"X-Content-Type-Options: nosniff\r\n" req.size = p - buf + 1;
"Content-Length: 19\r\n\r\n" req.buf = malloc(req.size);
"404 page not found\n"); if (!req.buf) {
//} else if (cstrstart(buf, "POST ")) { // memory allocation fail.
// TODO: Handle chunked/gzip/form-data/json POST requests. 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 { } else {
write_cstr (s, "HTTP/1.1 400 Bad Request\r\n" write_cstr (s, HTTP_400);
"Content-Type: text/plain\r\n"
"Connection: close\r\n\r\n"
"400 Bad Request");
} }
quit: quit:
if (req.buf)
free(req.buf);
if (inet_ntop(AF_INET, &(api_list.conns[i]->ipv4), client, INET_ADDRSTRLEN) == NULL) if (inet_ntop(AF_INET, &(api_list.conns[i]->ipv4), client, INET_ADDRSTRLEN) == NULL)
strcpy(client, "UNKNOW"); strcpy(client, "UNKNOW");
libp2p_logger_error("api", "Closing client connection %s:%d (%d).\n", client, api_list.conns[i]->port, i+1); 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) if (inet_ntop(AF_INET, &ipv4, client, INET_ADDRSTRLEN) == NULL)
strcpy(client, "UNKNOW"); 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]->socket = s;
api_list.conns[i]->ipv4 = ipv4; api_list.conns[i]->ipv4 = ipv4;
api_list.conns[i]->port = port; api_list.conns[i]->port = port;
@ -151,6 +197,7 @@ void *api_listen_thread (void *ptr)
} else { } else {
conns_count++; 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); pthread_mutex_unlock(&conns_lock);
} }
api_connections_cleanup (); api_connections_cleanup ();

View file

@ -22,6 +22,35 @@ struct s_list {
} **conns; } **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_cstr(f,s) write(f,s,sizeof(s)-1)
#define write_str(f,s) write(f,s,strlen(s)) #define write_str(f,s) write(f,s,strlen(s))