diff --git a/httpd/.gitignore b/httpd/.gitignore index 85e1c00..035927b 100644 --- a/httpd/.gitignore +++ b/httpd/.gitignore @@ -7,4 +7,3 @@ *.core httpd __pycache__ -env/ diff --git a/httpd/Makefile b/httpd/Makefile index 0682316..70108ef 100644 --- a/httpd/Makefile +++ b/httpd/Makefile @@ -31,14 +31,8 @@ TARGET=httpd $(TARGET): $(OBJS) $(CC) -o $@ $(OBJS) $(LDFLAGS) $(LDLIBS) -check: $(TARGET) - cp $(TARGET) tests/$(TARGET) - cd tests - python3 -m venv env - env/bin/python -m pip install requests - env/bin/python -m pip install pytest - env/bin/python -m pip install pytest-timeout - - env/bin/pytest +check: + dash tests/run.sh debug: CFLAGS += $(CFLAGS_DBG) debug: $(OBJS) @@ -51,7 +45,5 @@ asan: $(OBJS) $(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LDLIBS) clean: - - pkill -9 $(TARGET) - $(RM) tests/$(TARGET) tests/out.log $(RM) $(TARGET) $(RM) $(OBJS) diff --git a/httpd/src/config/config.c b/httpd/src/config/config.c index c8edde6..d910424 100644 --- a/httpd/src/config/config.c +++ b/httpd/src/config/config.c @@ -5,8 +5,8 @@ #include #include -// #include "../utils/string/string.h" -// #include "bits/getopt_ext.h" +#include "../utils/string/string.h" +#include "bits/getopt_ext.h" #define ARG_VALID 0 #define ARG_INVALID 1 @@ -180,19 +180,6 @@ static void print_arg_error(int err, char **argv, struct option options[], } } -// static void apply_default_values(struct config *cfg) -// { -// // Default file -// if (cfg->servers->default_file == NULL) -// { -// char *default_df = DEFAULT_DF; -// cfg->servers->default_file = -// malloc((strlen(default_df) + 1) * sizeof(char)); -// // TODO handle error -// strcpy(cfg->servers->default_file, default_df); -// } -// } - // == Main functions struct config *parse_configuration(int argc, char *argv[]) @@ -240,12 +227,10 @@ struct config *parse_configuration(int argc, char *argv[]) } } - // apply_default_values(config); - // Check config validity if (check_config(config) != 0) { - printf("%s: Missing mandatory flags, cannot continue.\n", argv[0]); + printf("%s: Missing mandatory flags, cannot continue.", argv[0]); config_destroy(config); return NULL; } diff --git a/httpd/src/config/config.h b/httpd/src/config/config.h index 72be5a8..c1ba197 100644 --- a/httpd/src/config/config.h +++ b/httpd/src/config/config.h @@ -6,9 +6,6 @@ #include -// Default values -#define DEFAULT_DF "index.html" - /* ** @brief Enum daemon ** NO_OPTION if the '--daemon' option is not given diff --git a/httpd/src/daemon/daemon.c b/httpd/src/daemon/daemon.c index a918966..3ceb251 100644 --- a/httpd/src/daemon/daemon.c +++ b/httpd/src/daemon/daemon.c @@ -17,7 +17,7 @@ void daemon_init(struct config *cfg) config = cfg; } -int get_pid(void) +int get_pid() { FILE *stream = fopen(config->pid_file, "r"); if (stream == NULL) @@ -48,7 +48,7 @@ int start_daemon(void) pid_t pid = fork(); if (!pid) // Daemon { - start_server(config); + start_server(config->servers->ip, config->servers->port); } else // Parent { diff --git a/httpd/src/daemon/daemon.h b/httpd/src/daemon/daemon.h index f1dcae8..5b150ec 100644 --- a/httpd/src/daemon/daemon.h +++ b/httpd/src/daemon/daemon.h @@ -7,7 +7,7 @@ * * @return */ -int get_pid(void); +int get_pid(); /* @brief */ diff --git a/httpd/src/http/headers.c b/httpd/src/http/headers.c index ce7806c..5463d92 100644 --- a/httpd/src/http/headers.c +++ b/httpd/src/http/headers.c @@ -5,15 +5,12 @@ #include #include "../utils/parsing/words.h" -#include "../utils/string/string.h" void destroy_headers(struct http_header *headers) { while (headers != NULL) { struct http_header *next = headers->next; - string_destroy(headers->field); - string_destroy(headers->value); free(headers); headers = next; } @@ -42,12 +39,6 @@ ssize_t read_value(struct string *str, size_t offset, struct string **res) if (str->size <= offset + nread || str->data[offset + nread] != '\n') return ERR_HTTP_INVALID_INPUT; - // Trim trailing \r - if ((*res)->size > 0 && (*res)->data[(*res)->size - 1] == '\r') - { - (*res)->size--; - } - return nread; } @@ -59,8 +50,7 @@ ssize_t parse_headers(struct http_request *res, struct string *req, // Yes I know I do one useless allocation but I really don't care at this // point - while (i < req->size && req->data[i] != '\n' - && req->data[i] != '\r') // ! Blank line + while (req->data[i] != '\n') // ! Blank line { if (header == NULL) { @@ -80,26 +70,21 @@ ssize_t parse_headers(struct http_request *res, struct string *req, return ERR_HTTP_OUT_OF_MEMORY; // Read field - ssize_t nread = read_field(req, i, &header->field); + ssize_t nread = read_field(req, offset, &header->field); if (nread <= 0) return nread; // Contains error code when negative - i += nread + 1; + i += nread; // Read value - nread = read_value(req, i, &header->value); + nread = read_value(req, offset, &header->value); if (nread <= 0) return nread; // Contains error code when negative i += nread + 1; } - if (i < req->size && req->data[i] == '\r') - i++; - if (i < req->size && req->data[i] == '\n') - i++; - - return i; + return i + 1; } struct http_header *get_header(struct http_header *headers, const char *field) diff --git a/httpd/src/http/http.c b/httpd/src/http/http.c index 4fb2280..896866b 100644 --- a/httpd/src/http/http.c +++ b/httpd/src/http/http.c @@ -2,14 +2,13 @@ #include #include -// #include +#include #include #include #include #include #include -#include "../config/config.h" #include "../logger/logs.h" #include "../utils/files/files.h" #include "../utils/parsing/words.h" @@ -31,16 +30,16 @@ static ssize_t parse_reqline(struct http_request *res, struct string *req) ssize_t i = 0; ssize_t skipped; - if (res == NULL || req == NULL) + if (res == NULL) return ERR_HTTP_INTERNAL_ERROR; // Method - if (string_compare_n_str(req, "GET", strlen("GET")) == 0) + if (strncmp(req->data, "GET", strlen("GET")) == 0) { res->method = GET; i += strlen("GET"); } - else if (string_compare_n_str(req, "HEAD", strlen("HEAD")) == 0) + else if (strncmp(req->data, "HEAD", strlen("HEAD")) == 0) { res->method = HEAD; i += strlen("HEAD"); @@ -68,15 +67,9 @@ static ssize_t parse_reqline(struct http_request *res, struct string *req) return ERR_HTTP_INVALID_INPUT; i += skipped; - // CRLF (EOL) oh qu'il est casse couilles celui-là - ssize_t req_size = req->size; // aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah - if (i < req_size && req->data[i] == '\r') - i++; - if (i >= req_size || req->data[i] != '\n') + // CRLF (EOL) + if (req->data[i++] != '\r' && req->data[i++] != '\n') return ERR_HTTP_INVALID_INPUT; - i++; - // Donc 2h de debug pour ça là ? Plutot envie de me tirer une balle si vous - // voulez mon avis return i; } @@ -98,19 +91,21 @@ static void split_target(struct http_request *req) } } -// Finds a valid path based on the client input and returns the corresponding -// FILES return value (see files.h) -static int find_target(struct http_request *req) +// Finds a valid path based on the client input +static bool find_target(struct http_request *req) { // Check filename if (!check_filename(req->target)) - return ERR_FILES_FORBIDDEN; + return false; char *target = string_to_charptr(req->target); int err = is_directory(target); free(target); + err = 0; // TODO fix that bug - if (err == FILES_DIR) // Is a directory + if (err == -1) // Doesn't exists + return false; + else if (err == 1) { // Append default file if directory if (req->target->data[req->target->size - 1] != '/') @@ -122,10 +117,11 @@ static int find_target(struct http_request *req) target = string_to_charptr(req->target); err = is_directory(target); free(target); - return err; + return err == 0; } - return err; + // Exists + return true; } // WARNING allocates result on the heap @@ -183,42 +179,10 @@ static void check_req(struct http_request *req, struct http_response *resp) resp->status_code = 405; // Protocol - // Oui il y a plus beau, mais on a le temps ou on l'a pas, moi je l'ai pas, - // alors si t'es pas content t'as qu'à le modifier toi même vu que tu as - // visiblement le code source. <3 - if (string_compare_strictly_n_str(req->protocol, "HTTP/", strlen("HTTP/")) - != 0) - resp->status_code = 400; - else if (string_compare_strictly_n_str(req->protocol, "HTTP/1.1", - strlen("HTTP/1.1")) - != 0) + char *protocol = string_to_charptr(req->protocol); + if (strcmp(protocol, HTTP_VERSION) != 0) resp->status_code = 505; - - // Host - if (resp->status_code != 400 && resp->status_code != 505) - { - int host_count = 0; - struct http_header *cur = req->headers; - while (cur != NULL) - { - if (cur->field->size == 4 - && string_compare_n_str(cur->field, "host", 4) == 0) - { - host_count++; - if (cur->value == NULL || cur->value->size == 0) - { - resp->status_code = 400; - break; - } - } - cur = cur->next; - } - - if (host_count != 1) - resp->status_code = 400; - } - - // printf("%s %d\n", req->protocol->data, resp->status_code); + free(protocol); } // === Functions @@ -246,39 +210,27 @@ void handle_request(int client_fd, char *client_ip) { string_concat_str(str, buffer, nread); } - if (nread > 0) - string_concat_str(str, buffer, nread); + string_concat_str(str, buffer, nread); // Parse request struct http_request *req = parse_request(str); if (req == NULL) - { - free(str); return; - } char *method = get_http_method(req->method); char *target = string_to_charptr(req->target); - print_log_request(method, target, client_ip); + log_request(method, target, client_ip); free(method); free(target); // Generate response struct http_response *resp = generate_response(req); if (resp == NULL) - { - free(str); - free(req); return; - } // Format response to string struct string *res = format_response(resp); if (res == NULL) - { - free(str); - free(req); return; - } // Send response ssize_t nsent; @@ -301,15 +253,12 @@ void handle_request(int client_fd, char *client_ip) int fd = open(target, O_RDONLY); if (fd > 0) sendfile(client_fd, fd, 0, atoi(cl_str)); - - free(target); - free(cl_str); } // Log response method = get_http_method(req->method); target = string_to_charptr(req->target); - print_log_response(resp->status_code, method, target, client_ip); + log_response(resp->status_code, method, target, client_ip); free(method); free(target); @@ -331,19 +280,7 @@ struct http_request *parse_request(struct string *req) size_t i = 0; ssize_t nread = parse_reqline(res, req); if (nread <= 0) - { - if (nread == ERR_HTTP_NOT_IMPLEMENTED) - res->status_code = 501; - else - res->status_code = 400; - - if (res->target == NULL) - res->target = string_create("", 0); - if (res->protocol == NULL) - res->protocol = string_create("HTTP/1.1", 8); - - return res; - } + return NULL; // Split path and query split_target(res); @@ -353,10 +290,7 @@ struct http_request *parse_request(struct string *req) // Headers nread = parse_headers(res, req, i); if (nread <= 0) - { - res->status_code = 400; - return res; - } + return NULL; return res; } @@ -370,39 +304,23 @@ struct http_response *generate_response(struct http_request *req) return NULL; // Protocol - // char *protocol = HTTP_VERSION; - char *protocol = "HTTP/1.1"; + char *protocol = HTTP_VERSION; res->protocol = string_create(protocol, strlen(protocol)); // Target - if (req->status_code == 0) - { - str_concat_string(config->servers->root_dir, - strlen(config->servers->root_dir), req->target); - } + str_concat_string(config->servers->root_dir, + strlen(config->servers->root_dir), req->target); // Status code if (req->status_code == 0) { - switch (find_target(req)) - { - case FILES_REG: - res->status_code = 200; - break; - case ERR_FILES_NOT_FOUND: + if (!find_target(req)) res->status_code = 404; - break; - default: - res->status_code = 403; - break; - } + else + res->status_code = 200; } - else - res->status_code = req->status_code; - // Check protocol and method - if (req->status_code == 0) - check_req(req, res); + check_req(req, res); // Headers char *time = get_time(); @@ -421,13 +339,10 @@ struct http_response *generate_response(struct http_request *req) } else { - res->status_code = 403; + res->status_code = + 404; // TODO replace by 403 once find_target is fixed } } - else - { - append_header(&res->headers, create_header("Content-Length", "0")); - } append_header(&res->headers, create_header("Connection", "close")); // Status msg diff --git a/httpd/src/http/http.h b/httpd/src/http/http.h index 8c3565c..c3df90c 100644 --- a/httpd/src/http/http.h +++ b/httpd/src/http/http.h @@ -73,7 +73,7 @@ void http_init(struct config *cfg); * * @param client_fd */ -void handle_request(int client_fd, char *client_ip); +void handle_request(int client_fd, char* client_ip); /* @brief Parses the HTTP request and splits it into a request structure * diff --git a/httpd/src/logger/errors.c b/httpd/src/logger/errors.c index 4bbb369..c49a0a7 100644 --- a/httpd/src/logger/errors.c +++ b/httpd/src/logger/errors.c @@ -6,7 +6,6 @@ #include #include #include -#include #include "../utils/time/fmt_time.h" #include "logs.h" @@ -17,16 +16,13 @@ static struct logs_config config; // === Functions -void errlog_init(bool enabled, int logfile_fd, struct server_config *serv_cfg) +void errlog_init(bool enabled, int logfile_fd) { config.enabled = enabled; - if (logfile_fd == STDOUT_FILENO) - config.logfile_fd = STDERR_FILENO; config.logfile_fd = logfile_fd; - config.server_cfg = serv_cfg; } -void print_err(void) +void print_err() { print_log_err("%s", get_err()); } @@ -55,7 +51,7 @@ void print_log_err(char *format, ...) fprintf(stderr, "Error: %s", get_err()); } -char *get_err(void) +char *get_err() { return strerror(errno); } diff --git a/httpd/src/logger/errors.h b/httpd/src/logger/errors.h index 09b8be2..bc225d8 100644 --- a/httpd/src/logger/errors.h +++ b/httpd/src/logger/errors.h @@ -4,24 +4,22 @@ #include #include -#include "../config/config.h" - /* @brief Initialize the error logging submodule * @warning Do not use 'as is', use log_init() instead */ -void errlog_init(bool enabled, int logfile_fd, struct server_config *serv_cfg); +void errlog_init(bool enabled, int logfile_fd); /* @brief Retrieves the last error with errno and prints the corresponding * error message in the logs and stderr */ -void print_err(void); +void print_err(); -/* @brief Prints error logs, just like print_log() but for errors +/* @brief Prints error logs, just like print_log(), and also to stderr */ void print_log_err(char *format, ...); -/* @brief Returns the string corresponding to the last error that happened +/* @brief Prints error logs, just like print_log() */ -char *get_err(void); +char *get_err(); #endif // ! ERRORS_H diff --git a/httpd/src/logger/logs.c b/httpd/src/logger/logs.c index f82f706..f01cde6 100644 --- a/httpd/src/logger/logs.c +++ b/httpd/src/logger/logs.c @@ -5,7 +5,6 @@ #include #include #include -#include #include "../utils/time/fmt_time.h" #include "errors.h" @@ -21,21 +20,13 @@ int log_init(struct config *global_config) int return_value = 0; config.enabled = global_config->log; config.server_cfg = global_config->servers; - if (global_config->log_file != NULL) + config.logfile_fd = open(global_config->log_file, O_WRONLY); + if (config.logfile_fd <= 0) { - config.logfile_fd = open(global_config->log_file, O_WRONLY); - if (config.logfile_fd <= 0) - { - config.enabled = false; - return_value = 1; - } + config.enabled = false; + return_value = 1; } - else - { - config.logfile_fd = STDOUT_FILENO; - } - - errlog_init(config.enabled, config.logfile_fd, config.server_cfg); + errlog_init(config.enabled, config.logfile_fd); return return_value; } @@ -60,20 +51,14 @@ void print_log(char *format, ...) dprintf(config.logfile_fd, "\n"); } -void print_log_request(char *request_type, char *target, char *client_ip) +void log_request(char *request_type, char *target, char *client_ip) { print_log("received %s, on '%s' from %s", request_type, target, client_ip); } -void print_log_response(int status_code, char *request_type, char *target, - char *client_ip) +void log_response(int status_code, char *request_type, char *target, + char *client_ip) { print_log("responding with %d to %s for %s on '%s'", status_code, client_ip, request_type, target); } - -void log_terminate(void) -{ - if (config.logfile_fd != 0 && config.logfile_fd != STDOUT_FILENO) - close(config.logfile_fd); -} diff --git a/httpd/src/logger/logs.h b/httpd/src/logger/logs.h index f18a6d4..1e81ea3 100644 --- a/httpd/src/logger/logs.h +++ b/httpd/src/logger/logs.h @@ -35,7 +35,7 @@ void print_log(char *format, ...); * @param target * @param client_ip */ -void print_log_request(char *request_type, char *target, char *client_ip); +void log_request(char *request_type, char *target, char *client_ip); /* @brief Prints response logs with the adequate format in the logfile * @@ -44,11 +44,7 @@ void print_log_request(char *request_type, char *target, char *client_ip); * @param target * @param client_ip */ -void print_log_response(int status_code, char *request_type, char *target, - char *client_ip); - -/* @brief Gracefully exits the logs module - */ -void log_terminate(void); +void log_response(int status_code, char *request_type, char *target, + char *client_ip); #endif // ! LOGS_H diff --git a/httpd/src/main.c b/httpd/src/main.c index 6f2c5b2..f03aaeb 100644 --- a/httpd/src/main.c +++ b/httpd/src/main.c @@ -24,7 +24,7 @@ int main(int argc, char **argv) switch (config->daemon) { case NO_OPTION: - start_server(config); + start_server(config->servers->ip, config->servers->port); break; case START: @@ -43,6 +43,5 @@ int main(int argc, char **argv) return 2; } - config_destroy(config); return 0; } diff --git a/httpd/src/server/server.c b/httpd/src/server/server.c index 56c0c53..e772298 100644 --- a/httpd/src/server/server.c +++ b/httpd/src/server/server.c @@ -1,31 +1,23 @@ // === Definitions +#include #define _POSIX_C_SOURCE 200112L #define BUFFER_SIZE 1024 // === Includes -#include "server.h" - #include #include -#include #include #include -#include #include #include #include "../http/http.h" #include "../logger/errors.h" -#include "../logger/logs.h" +#include "server.h" // #include "../logger/logs.h" -// === Static variables - -static int server_socket = 0; -static struct config *config; - // === Static functions // Creates and bind the server communication socket @@ -110,31 +102,11 @@ static void get_ip(struct sockaddr *client_addr, char *res) inet_ntop(AF_INET, &ipAddr, res, INET_ADDRSTRLEN); } -static void signal_handler(int signal) -{ - print_log("EVENT Signal received: %d", signal); - switch (signal) - { - case SIGINT: { - print_log("STOPPING Stopping server..."); - stop_server(); - config_destroy(config); - exit(0); - } - default: - return; - } -} - // === Functions -void start_server(struct config *cfg) +void start_server(const char *host, const char *port) { - config = cfg; - const char *host = config->servers->ip; - const char *port = config->servers->port; - - server_socket = get_socket(host, port); + int server_socket = get_socket(host, port); if (server_socket == -1) // TODO log that return; @@ -143,24 +115,11 @@ void start_server(struct config *cfg) if (err == -1) return; - // Signal handling - struct sigaction siga; - siga.sa_flags = 0; - siga.sa_handler = signal_handler; - // initialize mask - if (sigemptyset(&siga.sa_mask) < 0) - // TODO log that - return; - if (sigaction(SIGINT, &siga, NULL) == -1 - || sigaction(SIGPIPE, &siga, NULL) == -1) - return; - // Main loop while (1) { struct sockaddr client_addr; - socklen_t client_addr_len = sizeof(struct sockaddr); - int client_fd = accept(server_socket, &client_addr, &client_addr_len); + int client_fd = accept(server_socket, &client_addr, NULL); if (client_fd == -1) continue; @@ -175,10 +134,5 @@ void start_server(struct config *cfg) close(client_fd); } - stop_server(); -} - -void stop_server(void) -{ close(server_socket); } diff --git a/httpd/src/server/server.h b/httpd/src/server/server.h index 0c441ac..fe95e52 100644 --- a/httpd/src/server/server.h +++ b/httpd/src/server/server.h @@ -1,19 +1,13 @@ #ifndef SERVER_H #define SERVER_H -#include "../config/config.h" +// #define _POSIX_C_SOURCE 200112L -/* @brief Starts the HTTP server +/* @brief * - * @warn Make sure to initialize modules before calling - * - * @param hostname + * @param hpstname * @param port */ -void start_server(struct config *cfg); - -/* @brief Stops the currently running HTTP server - */ -void stop_server(void); +void start_server(const char *host, const char *port); #endif // ! SERVER_H diff --git a/httpd/src/utils/files/files.c b/httpd/src/utils/files/files.c index 0f08c25..0daea41 100644 --- a/httpd/src/utils/files/files.c +++ b/httpd/src/utils/files/files.c @@ -2,7 +2,6 @@ #include "files.h" -#include #include #include @@ -14,22 +13,10 @@ int is_directory(const char *path) { struct stat path_stat; - if (lstat(path, &path_stat) == 0) - { - if (S_ISDIR(path_stat.st_mode)) // Directory - return FILES_DIR; - else if (S_ISREG(path_stat.st_mode)) // Regular file - return FILES_REG; - else - return FILES_OTHER; - } + if (lstat(path, &path_stat) != 0) + return S_ISDIR(path_stat.st_mode); else - { - if (errno == ENOENT) // File not found - return ERR_FILES_NOT_FOUND; - else // Other errors - return ERR_FILES_FORBIDDEN; - } + return -1; } // TODO handle logging diff --git a/httpd/src/utils/files/files.h b/httpd/src/utils/files/files.h index 0c2cdcc..ed0f133 100644 --- a/httpd/src/utils/files/files.h +++ b/httpd/src/utils/files/files.h @@ -5,15 +5,6 @@ #define BUFFER_SIZE 1024 -// Return codes -#define FILES_REG 0 -#define FILES_DIR 1 -#define FILES_OTHER 8 - -// Errors -#define ERR_FILES_NOT_FOUND -1 -#define ERR_FILES_FORBIDDEN -2 - // === Includes #include @@ -38,8 +29,7 @@ * * @param path * - * @return Returns the corresponding return value / error code (see header - * definitions) + * @return 1 if path is a directory, 0 if it is not and -1 if path is not valid */ int is_directory(const char *path); diff --git a/httpd/src/utils/string/string.c b/httpd/src/utils/string/string.c index 5a28b5a..d02d9de 100644 --- a/httpd/src/utils/string/string.c +++ b/httpd/src/utils/string/string.c @@ -114,7 +114,6 @@ void str_concat_string(const char *str, size_t size, struct string *to_concat) memcpy(to_concat->data, str, size); memcpy(to_concat->data + size, tmp, tmp_size); - free(tmp); } } @@ -154,22 +153,3 @@ char *string_to_charptr(struct string *str) return res; } - -// WARNING takes n as valid, will not stop on '\0' -int string_compare_strictly_n_str(const struct string *str1, const char *str2, - size_t n) -{ - if (str1->size < n) - return -1; - - size_t i = 0; - int res = 0; - while (i < n) - { - res += str1->data[i]; - res -= str2[i]; - i++; - } - - return res; -} diff --git a/httpd/src/utils/string/string.h b/httpd/src/utils/string/string.h index a69f47c..0d01688 100644 --- a/httpd/src/utils/string/string.h +++ b/httpd/src/utils/string/string.h @@ -75,15 +75,4 @@ void string_destroy(struct string *str); */ char *string_to_charptr(struct string *str); -/* - ** @brief TODO - ** - ** @param str1 - ** @param str2 - ** @param n - ** - ** @return - */ -int string_compare_strictly_n_str(const struct string *str1, const char *str2, - size_t n); #endif /* ! STRING_H */ diff --git a/httpd/tests/test_suite.py b/httpd/tests/test_suite.py index 504f05a..37388e2 100644 --- a/httpd/tests/test_suite.py +++ b/httpd/tests/test_suite.py @@ -12,7 +12,7 @@ executable = "./httpd" def spawn_httpd(stdout_filename, args=[]): with open(stdout_filename,"w") as f: - httpd_proc = sp.Popen([executable,"--pid_file","/tmp/HTTPd.pid","--ip",host,"--port", port, "--root_dir","test_root_dir/","--server_name","httpd"] if args == [] else [executable] + args, stdout=f,stderr=sp.PIPE,bufsize=0) + httpd_proc = sp.Popen([executable,"--pid_file","/tmp/HTTPd.pid","--ip",host,"--port", port, "--root_dir","./test_root_dir/","--server_name","httpd"] if args == [] else [executable] + args, stdout=f,stderr=sp.PIPE,bufsize=0) time.sleep(0.2) return httpd_proc @@ -21,7 +21,7 @@ def kill_httpd(proc): #proc.send_signal(sp.SIGINT) proc.kill() -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_bad_config(): proc = spawn_httpd("out.log", ["hello","world"]) proc.wait(1) @@ -30,7 +30,7 @@ def test_bad_config(): finally: kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_get_index(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/index.html") @@ -41,7 +41,7 @@ def test_get_index(): finally: kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_get_default(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/") @@ -52,13 +52,13 @@ def test_get_default(): finally: kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_no_file(): proc = spawn_httpd("out.log") req = requests.get(f"http://{host}:{port}/notindex.html") assert req.status_code == 404 -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_bad_request(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) @@ -76,7 +76,7 @@ def test_bad_request(): finally: kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_invalid_method(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) @@ -95,7 +95,7 @@ def test_invalid_method(): kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_invalid_version(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) @@ -113,7 +113,7 @@ def test_invalid_version(): finally: kill_httpd(proc) -# @pytest.mark.timeout(2) +@pytest.mark.timeout(2) def test_bad_request(): proc = spawn_httpd("out.log") sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) @@ -130,49 +130,3 @@ def test_bad_request(): assert response.status == 400 finally: kill_httpd(proc) - -@pytest.mark.timeout(2) -def test_head_index(): - proc = spawn_httpd("out.log") - try: - req = requests.head(f"http://{host}:{port}/index.html") - assert req.status_code == 200 - assert req.text == "" - finally: - kill_httpd(proc) - -@pytest.mark.timeout(2) -def test_missing_host(): - proc = spawn_httpd("out.log") - sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) - sock.connect((host,int(port))) - - request = f"GET /index.html HTTP/1.1\r\nConnection: close\r\n\r\n" - - sock.sendall(request.encode()) - - response = http.client.HTTPResponse(sock) - response.begin() - - try: - assert response.status == 400 - finally: - kill_httpd(proc) - -@pytest.mark.timeout(2) -def test_directory_traversal(): - proc = spawn_httpd("out.log") - sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) - sock.connect((host,int(port))) - - request = f"GET /../test_suite.py HTTP/1.1\r\nHOST: {host}:{port}\r\nConnection: close\r\n\r\n" - - sock.sendall(request.encode()) - - response = http.client.HTTPResponse(sock) - response.begin() - - try: - assert response.status in [400, 403, 404] - finally: - kill_httpd(proc) diff --git a/httpd/tests/tests_mieux.sh b/httpd/tests/tests_mieux.sh deleted file mode 100755 index 6851190..0000000 --- a/httpd/tests/tests_mieux.sh +++ /dev/null @@ -1,40 +0,0 @@ -#!/bin/sh - -# Simple test script for HTTP/1.1 Host header compliance -# Usage: ./test_host_compliance.sh [IP] [PORT] - -IP=${1:-"127.0.0.1"} -PORT=${2:-"6996"} - -echo "Targeting server at $IP:$PORT" - -test_req() { - NAME="$1" - PAYLOAD="$2" - EXPECTED="$3" - - echo -n "Test: $NAME ... " - # Send payload, wait max 1s for response - RESP=$(printf "$PAYLOAD" | nc -w 1 $IP $PORT 2>/dev/null | head -n 1) - - if echo "$RESP" | grep -q "$EXPECTED"; then - echo "PASS" - else - echo "FAIL (Expected '$EXPECTED', got '$RESP')" - fi -} - -# 1. Valid Request -test_req "Valid Request" "GET / HTTP/1.1\r\nHost: localhost\r\n\r\n" "200 OK" - -# 2. Missing Host Header -test_req "Missing Host" "GET / HTTP/1.1\r\n\r\n" "400 Bad Request" - -# 3. Empty Host Header -test_req "Empty Host" "GET / HTTP/1.1\r\nHost:\r\n\r\n" "400 Bad Request" - -# 4. Multiple Host Headers -test_req "Multiple Hosts" "GET / HTTP/1.1\r\nHost: a\r\nHost: b\r\n\r\n" "400 Bad Request" - -# 5. Bad Protocol Version (Should be 505 now with the fix) -test_req "Bad Protocol (HTTP/1.0)" "GET / HTTP/1.0\r\nHost: localhost\r\n\r\n" "505" \ No newline at end of file