diff --git a/example.c b/example.c index 4052864..79d2f5f 100644 --- a/example.c +++ b/example.c @@ -1,4 +1,5 @@ #include "serwer.h" +#include "ws_error.h" #include "ws_handlers.h" #include "help.h" #include @@ -6,6 +7,14 @@ int hello_world(webserver_t server, method_t method, const char* host, const char* path, headers_t requestHeaders, headers_t* responseHeaders, stream_t request, stream_t response) { + // we are just using response + (void) server; + (void) method; + (void) host; + (void) path; + (void) requestHeaders; + (void) responseHeaders; + (void) request; fprintf(response, "Hello World!\n"); @@ -13,18 +22,12 @@ int hello_world(webserver_t server, method_t method, const char* host, const cha } int main(int argc, char** argv) { + // we are not using these + (void) argc; + (void) argv; + help_init(NULL, "test"); - - handle_t hello_handle = { - .host = ANY, - .path = "/world", - .handler = &hello_world - }; - handle_t test_handle = { - .host = ANY, - .path = "/info", - .handler = &info_handler - }; + srvoptions_t options = { .mode = LINEAR, .timeout = 30, @@ -34,8 +37,18 @@ int main(int argc, char** argv) { webserver_t server = ws_create("test_server", ANY , "8080", stderr, options); - ws_handle_add(&server, hello_handle); - ws_handle_add(&server, test_handle); + ws_handle_add(&server, (handle_t) { + .host = ANY, + .path = "/world", + .handler = &hello_world + }); + ws_handle_add(&server, (handle_t) { + .host = ANY, + .path = "/info", + .handler = &info_handler + }); - ws_run(&server); + if (ws_run(&server) < 0) { + bail_out(EXIT_FAILURE, "ws_run: %s", ws_strerror()); + } } diff --git a/help.c b/help.c index 38c4269..738bc93 100644 --- a/help.c +++ b/help.c @@ -14,6 +14,7 @@ #include #include #include +#include /** * @see help.h @@ -28,53 +29,49 @@ const char* progname = ""; static free_t freeFunction = NULL; void help_init(free_t function, const char* name) { - freeFunction = function; - progname = name; + freeFunction = function; + progname = name; } -void bail_out(int exitcode, const char* module) { +void bail_out(int exitcode, const char* format, ...) { + (void) fprintf(stderr, "%s: ", progname); - if (module != NULL) { - // output is not split into smaller quantities to - // ensure error messages of child and parent - // don't get mixed + va_list arg; + va_start(arg, format); + (void) vfprintf(stderr, format, arg); + va_end(arg); - if (errno == 0) { - (void) fprintf(stderr, "%s: %s\n", progname, module); - } else { - (void) fprintf(stderr, "%s: %s: %s\n", progname, module, strerror(errno)); - } - } + (void) fprintf(stderr, "\n"); - if (freeFunction != NULL) - (*freeFunction)(); - exit(exitcode); + if (freeFunction != NULL) + (*freeFunction)(); + exit(exitcode); } void usage(const char* arguments, const char* description, const char* error, int exitcode) { - if (error != NULL) { - (void) fprintf(stderr, "%s\n\n", error); - } - (void) fprintf(stderr, "Usage: %s %s\n", progname, arguments); - if (description != NULL) { - (void) fprintf(stderr, "\n%s\n", description); - } + if (error != NULL) { + (void) fprintf(stderr, "%s\n\n", error); + } + (void) fprintf(stderr, "Usage: %s %s\n", progname, arguments); + if (description != NULL) { + (void) fprintf(stderr, "\n%s\n", description); + } - if (freeFunction != NULL) - (*freeFunction)(); + if (freeFunction != NULL) + (*freeFunction)(); - exit(exitcode); + exit(exitcode); } void setup_signal_handler(const int signal, sighandler_t handler) { - struct sigaction s; + struct sigaction s; - s.sa_handler = handler; - s.sa_flags = 0; - if(sigfillset(&s.sa_mask) < 0) { - bail_out(EXIT_FAILURE, "sigfillset"); - } - if (sigaction(signal, &s, NULL) < 0) { - bail_out(EXIT_FAILURE, "sigaction"); - } + s.sa_handler = handler; + s.sa_flags = 0; + if(sigfillset(&s.sa_mask) < 0) { + bail_out(EXIT_FAILURE, "sigfillset"); + } + if (sigaction(signal, &s, NULL) < 0) { + bail_out(EXIT_FAILURE, "sigaction"); + } } diff --git a/help.h b/help.h index 7efc12d..4f29b92 100644 --- a/help.h +++ b/help.h @@ -58,7 +58,7 @@ void help_init(free_t, const char*); * prints strerror() (if errno is not 0), executes the free-function (if set), * and exits the program with the given exit code. */ -void bail_out(int, const char*); +void bail_out(int, const char*, ...); /** * @brief displays a usage message diff --git a/serwer.c b/serwer.c index 798ad7f..94d0550 100644 --- a/serwer.c +++ b/serwer.c @@ -1,6 +1,7 @@ #include "serwer.h" #include "ws_types.h" #include "ws_utils.h" +#include "ws_error.h" #include "ws_modes.h" #include "help.h" @@ -33,18 +34,26 @@ handler_t* ws_handler_find(webserver_t* server, const char* path, const char* ho headers_t ws_headers_create(void) { headers_t headers; - headers.fields = malloc(0 * sizeof(header_t)); + headers.fields = NULL; headers.nrfields = 0; return headers; } -void ws_headers_add(headers_t* headers, const char* key, const char* value) { - headers->fields = realloc(headers->fields, ++(headers->nrfields) * sizeof(header_t)); +int ws_headers_add(headers_t* headers, const char* key, const char* value) { + header_t* array = realloc(headers->fields, ++(headers->nrfields) * sizeof(header_t)); + if (array == NULL) { + free(headers->fields); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + headers->fields = array; headers->fields[headers->nrfields - 1].key = key; headers->fields[headers->nrfields - 1].value = value; + return 0; } -void ws_headers_convert(headers_t* headers, char* line) { +int ws_headers_convert(headers_t* headers, char* line) { const char* key = line; const char* value = NULL; bool foundSeperator = false; @@ -69,7 +78,9 @@ void ws_headers_convert(headers_t* headers, char* line) { } if (value != NULL) - ws_headers_add(headers, key, value); + if (ws_headers_add(headers, key, value) < 0) + return -1; + return 0; } void ws_headers_free(headers_t* headers) { @@ -90,8 +101,9 @@ int ws_listen(webserver_t* server) { s = getaddrinfo(server->host, server->port, &hints, &result); if (s != 0) { - fprintf(stderr, "%s: ws_bind: getaddrinfo: %s\n", progname, gai_strerror(s)); - bail_out(EXIT_FAILURE, NULL); + ws_error.type = GAI; + ws_error.no = s; + return -1; } for (rp = result; rp != NULL; rp = rp->ai_next) { @@ -117,9 +129,17 @@ int ws_listen(webserver_t* server) { return 0; } -void ws_handle_add(webserver_t* server, handle_t handle) { - server->handles = realloc(server->handles, ++(server->nrhandles) * sizeof(handle_t)); +int ws_handle_add(webserver_t* server, handle_t handle) { + handle_t* tmp = realloc(server->handles, ++(server->nrhandles) * sizeof(handle_t)); + if (tmp == NULL) { + free(server->handles); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + server->handles = tmp; server->handles[server->nrhandles - 1] = handle; + return 0; } webserver_t ws_create(const char* name, const char* host, const char* port, FILE* logfile, srvoptions_t options) { @@ -129,7 +149,7 @@ webserver_t ws_create(const char* name, const char* host, const char* port, FILE server.port = port; server.logfile = logfile; server.nrhandles = 0; - server.handles = malloc(0); + server.handles = NULL; server.options.mode = LINEAR; server.options.timeout = 30; diff --git a/serwer.h b/serwer.h index 03b2e56..f1228da 100644 --- a/serwer.h +++ b/serwer.h @@ -21,11 +21,11 @@ #define LOG_ERROR 0 headers_t ws_headers_create(void); -void ws_headers_add(headers_t*, const char*, const char*); -void ws_headers_convert(headers_t*, char*); +int ws_headers_add(headers_t*, const char*, const char*); +int ws_headers_convert(headers_t*, char*); void ws_headers_free(headers_t*); -void ws_handle_add(webserver_t*, handle_t); +int ws_handle_add(webserver_t*, handle_t); handler_t* ws_handler_find(webserver_t*, const char*, const char*); size_t ws_send(int, int, headers_t, int); diff --git a/ws_error.c b/ws_error.c new file mode 100644 index 0000000..da12447 --- /dev/null +++ b/ws_error.c @@ -0,0 +1,21 @@ +#include "ws_error.h" + +#include +#include + +error_t ws_error = { + .type = WS, + .no = 0 +}; + +const char* ws_strerror(void) { + if (ws_error.type == ERRNO || ws_error.no == EWS_SUC) + return strerror(ws_error.no); + + if (ws_error.type == GAI) + return gai_strerror(ws_error.no); + + // TODO + + return "undefined"; +} diff --git a/ws_error.h b/ws_error.h new file mode 100644 index 0000000..46ab0f5 --- /dev/null +++ b/ws_error.h @@ -0,0 +1,22 @@ +#ifndef WS_ERROR_H +#define WS_ERROR_H + +#define EWS_SUC 0 +// TODO + +enum error_type { + ERRNO, + GAI, + WS +}; + +typedef struct error { + enum error_type type; + int no; +} error_t; + +extern error_t ws_error; + +const char* ws_strerror(void); + +#endif diff --git a/ws_handlers/info.c b/ws_handlers/info.c index 75aac42..c7452eb 100644 --- a/ws_handlers/info.c +++ b/ws_handlers/info.c @@ -6,6 +6,9 @@ int info_handler(webserver_t server, method_t method, const char* host, const char* path, headers_t requestHeaders, headers_t* responseHeaders, stream_t request, stream_t response) { + (void) responseHeaders; + (void) request; + fprintf(response, "\n"); fprintf(response, "Test-Page"); fprintf(response, "
"); @@ -18,8 +21,8 @@ int info_handler(webserver_t server, method_t method, const char* host, const ch fprintf(response, "This server is running %s (%s Version %s) on %s:%s since %s.

", server.name, WS_NAME, WS_VERSION, server.host == NULL ? "0.0.0.0" : server.host, server.port, buffer); fprintf(response, "There are %i handles registered:
    ", server.nrhandles); for (int i = 0; i < server.nrhandles; i++) { - char* hhost = server.handles[i].host; - char* hpath = server.handles[i].path; + const char* hhost = server.handles[i].host; + const char* hpath = server.handles[i].path; fprintf(response, "
  • %s %s
  • ", hhost == NULL ? "(null)" : hhost, hpath = NULL ? "(null)" : hpath); } fprintf(response, "
"); diff --git a/ws_modes/linear.c b/ws_modes/linear.c index dbd3518..5bfa4ab 100644 --- a/ws_modes/linear.c +++ b/ws_modes/linear.c @@ -1,4 +1,5 @@ #include "../serwer.h" +#include "../ws_error.h" #include #include @@ -17,10 +18,23 @@ int ws_run_linear(webserver_t* server) { int connfd; char* buffer = malloc(BUFFER_SIZE * sizeof(char)); + if (buffer == NULL) { + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + int buffersize = 0; int nb = 1; char* header = malloc(BUFFER_SIZE * sizeof(char)); + if (header == NULL) { + free(buffer); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + int headersize = 0; int nhb = 1; @@ -56,7 +70,15 @@ int ws_run_linear(webserver_t* server) { if (buffersize > nb * BUFFER_SIZE - 1) { nb++; - buffer = realloc(buffer, nb * BUFFER_SIZE * sizeof(char)); + char* tmp = realloc(buffer, nb * BUFFER_SIZE * sizeof(char)); + if (tmp == NULL) { + free(buffer); + free(header); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + buffer = tmp; } buffer[buffersize] = '\0'; @@ -155,7 +177,15 @@ int ws_run_linear(webserver_t* server) { ws_log(server, LOG_TESTING, "enlarging header buffer"); while (headersize + buffersize + 1 > nhb * BUFFER_SIZE) { nhb++; - header = realloc(header, nhb * BUFFER_SIZE * sizeof(char)); + char* tmp = realloc(header, nhb * BUFFER_SIZE * sizeof(char)); + if (tmp == NULL) { + free(header); + free(buffer); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + header = tmp; } memcpy(header + headersize, buffer, buffersize + 1); @@ -181,13 +211,30 @@ int ws_run_linear(webserver_t* server) { headersize += buffersize + 1; ws_log(server, LOG_TESTING, "reset buffer"); - buffer = realloc(buffer, BUFFER_SIZE * sizeof(char)); + char* tmp = realloc(buffer, BUFFER_SIZE * sizeof(char)); + if (tmp == NULL) { + free(header); + free(buffer); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + buffer = tmp; nb = 1; buffersize = 0; } } - header = realloc(header, BUFFER_SIZE * sizeof(char)); + char* tmp = realloc(header, BUFFER_SIZE * sizeof(char)); + if (tmp == NULL) { + free(header); + free(buffer); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + header = tmp; + nhb = 1; headersize = 0; @@ -200,11 +247,22 @@ int ws_run_linear(webserver_t* server) { host = NULL; } - buffer = realloc(buffer, BUFFER_SIZE * sizeof(char)); + tmp = realloc(buffer, BUFFER_SIZE * sizeof(char)); + if (tmp == NULL) { + free(header); + free(buffer); + ws_error.type = ERRNO; + ws_error.no = errno; + return -1; + } + buffer = tmp; + nb = 1; buffersize = 0; } free(buffer); free(header); + + return 0; } diff --git a/ws_utils.c b/ws_utils.c index c39d4dd..a7cb259 100644 --- a/ws_utils.c +++ b/ws_utils.c @@ -1,9 +1,12 @@ #include "serwer.h" +#include "ws_error.h" #include #include #include #include +#include + method_t ws_method(const char* string) { if (strcmp(string, "OPTIONS") == 0) @@ -316,6 +319,11 @@ char* ws_host_find(const char** path, headers_t headers) { header_t header = headers.fields[i]; if (strcmp(header.key, "Host") == 0) { host = malloc(strlen(header.value) + 1); + if (host == NULL) { + ws_error.type = ERRNO; + ws_error.no = errno; + return NULL; + } memcpy(host, header.value, strlen(header.value) + 1); return host; } @@ -331,6 +339,11 @@ char* ws_host_find(const char** path, headers_t headers) { if (host == NULL) { setHost = true; host = malloc(strlen(*path) + 1); + if (host == NULL) { + ws_error.type = ERRNO; + ws_error.no = errno; + return NULL; + } } int hposition = 0; @@ -360,6 +373,11 @@ char* ws_host_find(const char** path, headers_t headers) { if (setHost) { host[hposition] = '\0'; host = realloc(host, strlen(host) + 1); + if (host == NULL) { + ws_error.type = ERRNO; + ws_error.no = errno; + return NULL; + } } return host;