diff --git a/src/client.c b/src/client.c index 8c04bd8..82c45d9 100644 --- a/src/client.c +++ b/src/client.c @@ -14,18 +14,9 @@ #include "net/http.h" -#define out_1(fmt) fprintf(parent_stdout, "%s" fmt "\n", log_prefix) -#define out_2(fmt, args...) fprintf(parent_stdout, "%s" fmt "\n", log_prefix, args) - -#define out_x(x, arg1, arg2, arg3, arg4, arg5, arg6, arg7, FUNC, ...) FUNC - -#define print(...) out_x(, ##__VA_ARGS__, out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), \ - out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_1(__VA_ARGS__)) - - int keep_alive = 1; char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, - *log_prefix, *log_conn_prefix, *log_req_prefix; + *log_conn_prefix, *log_req_prefix; char *format_duration(unsigned long micros, char *buf) { @@ -54,14 +45,44 @@ int client_websocket_handler() { } int client_request_handler(sock *client, int req_num) { - // TODO implement client_request_handler + struct timespec begin, end; + int ret; + char buf[16]; + char *msg = "HTTP/1.1 501 Not Implemented\r\nConnection: keep-alive\r\nContent-Length: 116\r\n\r\n501 Not Implemented

501 Not Implemented

"; + + fd_set socket_fds; + FD_ZERO(&socket_fds); + FD_SET(client->socket, &socket_fds); + + ret = select(client->socket + 1, &socket_fds, NULL, NULL, NULL); + if (ret < 0) { + return 1; + } + clock_gettime(CLOCK_MONOTONIC, &begin); + + http_req req; + ret = http_receive_request(client, &req); + if (ret != 0) { + return ret; + } + + if (client->enc) { + SSL_write(client->ssl, msg, (int) strlen(msg)); + } else { + send(client->socket, msg, strlen(msg), 0); + } + + clock_gettime(CLOCK_MONOTONIC, &end); + unsigned long micros = (end.tv_nsec - begin.tv_nsec) / 1000 + (end.tv_sec - begin.tv_sec) * 1000000; + print(ERR_STR "501 Not Implemented (%s)" CLR_STR, format_duration(micros, buf)); + return 0; } int client_connection_handler(sock *client) { + struct timespec begin, end; int ret, req_num; char buf[16]; - struct timespec begin, end; clock_gettime(CLOCK_MONOTONIC, &begin); print("Connection accepted from %s (%s) [%s]", client_addr_str, client_addr_str, "N/A"); @@ -100,8 +121,8 @@ int client_connection_handler(sock *client) { } shutdown(client->socket, SHUT_RDWR); close(client->socket); - clock_gettime(CLOCK_MONOTONIC, &end); + clock_gettime(CLOCK_MONOTONIC, &end); unsigned long micros = (end.tv_nsec - begin.tv_nsec) / 1000 + (end.tv_sec - begin.tv_sec) * 1000000; print("Connection closed (%s)", format_duration(micros, buf)); diff --git a/src/necronda-server.c b/src/necronda-server.c index 06f2cfc..8e9d079 100644 --- a/src/necronda-server.c +++ b/src/necronda-server.c @@ -104,6 +104,7 @@ void terminate() { } int status = 0; + int wait_num = 0; int ret; for (int i = 0; i < MAX_CHILDREN; i++) { if (CHILDREN[i] != 0) { @@ -114,10 +115,15 @@ void terminate() { CHILDREN[i] = 0; } else { kill(CHILDREN[i], SIGTERM); + wait_num++; } } } + if (wait_num > 0) { + fprintf(stderr, "Waiting for %i child process(es)...\n", wait_num); + } + for (int i = 0; i < MAX_CHILDREN; i++) { if (CHILDREN[i] != 0) { ret = waitpid(CHILDREN[i], &status, 0); diff --git a/src/necronda-server.h b/src/necronda-server.h index 6523b14..7be404a 100644 --- a/src/necronda-server.h +++ b/src/necronda-server.h @@ -23,6 +23,8 @@ #define LISTEN_BACKLOG 16 #define REQ_PER_CONNECTION 100 +#define CLIENT_MAX_HEADER_SIZE 8192 + #define ERR_STR "\x1B[1;31m" #define CLR_STR "\x1B[0m" #define HTTP_STR "\x1B[1;31m" diff --git a/src/net/http.c b/src/net/http.c index 7300acf..ce10a9e 100644 --- a/src/net/http.c +++ b/src/net/http.c @@ -6,3 +6,30 @@ */ #include "http.h" +#include "utils.h" + + +int http_receive_request(sock *client, http_req *req) { + char *buf = malloc(CLIENT_MAX_HEADER_SIZE); + ssize_t len; + memset(buf, 0, CLIENT_MAX_HEADER_SIZE); + + while (1) { + if (client->enc) { + len = SSL_read(client->ssl, buf, CLIENT_MAX_HEADER_SIZE); + if (len < 0) { + print(ERR_STR "Unable to receive: %s" CLR_STR, ssl_get_error(client->ssl, len)); + continue; + } + } else { + len = recv(client->socket, buf, CLIENT_MAX_HEADER_SIZE, 0); + if (len < 0) { + print(ERR_STR "Unable to receive: %s" CLR_STR, strerror(errno)); + continue; + } + } + break; + } + + return 0; +} diff --git a/src/net/http.h b/src/net/http.h index 41efe22..8a9c87d 100644 --- a/src/net/http.h +++ b/src/net/http.h @@ -8,4 +8,14 @@ #ifndef NECRONDA_SERVER_HTTP_H #define NECRONDA_SERVER_HTTP_H +typedef struct { + char method[8]; + char *uri; + char version[3]; + char field_num; + char *fields[64][2]; +} http_req; + +int http_receive_request(sock *client, http_req *req); + #endif //NECRONDA_SERVER_HTTP_H diff --git a/src/utils.h b/src/utils.h index febf08c..6f3c035 100644 --- a/src/utils.h +++ b/src/utils.h @@ -8,4 +8,14 @@ #ifndef NECRONDA_SERVER_UTILS_H #define NECRONDA_SERVER_UTILS_H +char *log_prefix; + +#define out_1(fmt) fprintf(parent_stdout, "%s" fmt "\n", log_prefix) +#define out_2(fmt, args...) fprintf(parent_stdout, "%s" fmt "\n", log_prefix, args) + +#define out_x(x, arg1, arg2, arg3, arg4, arg5, arg6, arg7, FUNC, ...) FUNC + +#define print(...) out_x(, ##__VA_ARGS__, out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), \ + out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_2(__VA_ARGS__), out_1(__VA_ARGS__)) + #endif //NECRONDA_SERVER_UTILS_H