diff --git a/.gitignore b/httpd/.gitignore similarity index 100% rename from .gitignore rename to httpd/.gitignore diff --git a/Makefile b/httpd/Makefile similarity index 100% rename from Makefile rename to httpd/Makefile diff --git a/src/config/config.c b/httpd/src/config/config.c similarity index 100% rename from src/config/config.c rename to httpd/src/config/config.c diff --git a/src/config/config.h b/httpd/src/config/config.h similarity index 100% rename from src/config/config.h rename to httpd/src/config/config.h diff --git a/src/daemon/daemon.c b/httpd/src/daemon/daemon.c similarity index 98% rename from src/daemon/daemon.c rename to httpd/src/daemon/daemon.c index a918966..0e1008c 100644 --- a/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) diff --git a/src/daemon/daemon.h b/httpd/src/daemon/daemon.h similarity index 94% rename from src/daemon/daemon.h rename to httpd/src/daemon/daemon.h index f1dcae8..5b150ec 100644 --- a/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/src/http/headers.c b/httpd/src/http/headers.c similarity index 86% rename from src/http/headers.c rename to httpd/src/http/headers.c index ce7806c..bf6ba65 100644 --- a/src/http/headers.c +++ b/httpd/src/http/headers.c @@ -42,12 +42,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 +53,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 +73,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/src/http/headers.h b/httpd/src/http/headers.h similarity index 100% rename from src/http/headers.h rename to httpd/src/http/headers.h diff --git a/src/http/http.c b/httpd/src/http/http.c similarity index 86% rename from src/http/http.c rename to httpd/src/http/http.c index 4fb2280..59ad875 100644 --- a/src/http/http.c +++ b/httpd/src/http/http.c @@ -68,15 +68,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; } @@ -192,32 +186,9 @@ static void check_req(struct http_request *req, struct http_response *resp) else if (string_compare_strictly_n_str(req->protocol, "HTTP/1.1", strlen("HTTP/1.1")) != 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); } @@ -246,8 +217,7 @@ 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); @@ -332,17 +302,8 @@ struct http_request *parse_request(struct string *req) 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; + free(res); + return NULL; } // Split path and query @@ -354,8 +315,8 @@ struct http_request *parse_request(struct string *req) nread = parse_headers(res, req, i); if (nread <= 0) { - res->status_code = 400; - return res; + free(res); + return NULL; } return res; @@ -375,11 +336,8 @@ struct http_response *generate_response(struct http_request *req) 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) @@ -401,8 +359,7 @@ struct http_response *generate_response(struct http_request *req) 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(); @@ -424,10 +381,6 @@ struct http_response *generate_response(struct http_request *req) res->status_code = 403; } } - else - { - append_header(&res->headers, create_header("Content-Length", "0")); - } append_header(&res->headers, create_header("Connection", "close")); // Status msg diff --git a/src/http/http.h b/httpd/src/http/http.h similarity index 100% rename from src/http/http.h rename to httpd/src/http/http.h diff --git a/src/logger/errors.c b/httpd/src/logger/errors.c similarity index 96% rename from src/logger/errors.c rename to httpd/src/logger/errors.c index 4bbb369..3f96b65 100644 --- a/src/logger/errors.c +++ b/httpd/src/logger/errors.c @@ -26,7 +26,7 @@ void errlog_init(bool enabled, int logfile_fd, struct server_config *serv_cfg) config.server_cfg = serv_cfg; } -void print_err(void) +void print_err() { print_log_err("%s", get_err()); } @@ -55,7 +55,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/src/logger/errors.h b/httpd/src/logger/errors.h similarity index 93% rename from src/logger/errors.h rename to httpd/src/logger/errors.h index 09b8be2..931a883 100644 --- a/src/logger/errors.h +++ b/httpd/src/logger/errors.h @@ -14,7 +14,7 @@ void errlog_init(bool enabled, int logfile_fd, struct server_config *serv_cfg); /* @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 */ @@ -22,6 +22,6 @@ void print_log_err(char *format, ...); /* @brief Returns the string corresponding to the last error that happened */ -char *get_err(void); +char *get_err(); #endif // ! ERRORS_H diff --git a/src/logger/logs.c b/httpd/src/logger/logs.c similarity index 100% rename from src/logger/logs.c rename to httpd/src/logger/logs.c diff --git a/src/logger/logs.h b/httpd/src/logger/logs.h similarity index 100% rename from src/logger/logs.h rename to httpd/src/logger/logs.h diff --git a/src/main.c b/httpd/src/main.c similarity index 100% rename from src/main.c rename to httpd/src/main.c diff --git a/src/server/server.c b/httpd/src/server/server.c similarity index 100% rename from src/server/server.c rename to httpd/src/server/server.c diff --git a/src/server/server.h b/httpd/src/server/server.h similarity index 100% rename from src/server/server.h rename to httpd/src/server/server.h diff --git a/src/utils/files/files.c b/httpd/src/utils/files/files.c similarity index 100% rename from src/utils/files/files.c rename to httpd/src/utils/files/files.c diff --git a/src/utils/files/files.h b/httpd/src/utils/files/files.h similarity index 100% rename from src/utils/files/files.h rename to httpd/src/utils/files/files.h diff --git a/src/utils/parsing/blanks.c b/httpd/src/utils/parsing/blanks.c similarity index 100% rename from src/utils/parsing/blanks.c rename to httpd/src/utils/parsing/blanks.c diff --git a/src/utils/parsing/blanks.h b/httpd/src/utils/parsing/blanks.h similarity index 100% rename from src/utils/parsing/blanks.h rename to httpd/src/utils/parsing/blanks.h diff --git a/src/utils/parsing/words.c b/httpd/src/utils/parsing/words.c similarity index 100% rename from src/utils/parsing/words.c rename to httpd/src/utils/parsing/words.c diff --git a/src/utils/parsing/words.h b/httpd/src/utils/parsing/words.h similarity index 100% rename from src/utils/parsing/words.h rename to httpd/src/utils/parsing/words.h diff --git a/src/utils/string/string.c b/httpd/src/utils/string/string.c similarity index 100% rename from src/utils/string/string.c rename to httpd/src/utils/string/string.c diff --git a/src/utils/string/string.h b/httpd/src/utils/string/string.h similarity index 100% rename from src/utils/string/string.h rename to httpd/src/utils/string/string.h diff --git a/src/utils/time/fmt_time.c b/httpd/src/utils/time/fmt_time.c similarity index 100% rename from src/utils/time/fmt_time.c rename to httpd/src/utils/time/fmt_time.c diff --git a/src/utils/time/fmt_time.h b/httpd/src/utils/time/fmt_time.h similarity index 100% rename from src/utils/time/fmt_time.h rename to httpd/src/utils/time/fmt_time.h diff --git a/tests/config.txt b/httpd/tests/config.txt similarity index 100% rename from tests/config.txt rename to httpd/tests/config.txt diff --git a/tests/config_reader.sh b/httpd/tests/config_reader.sh similarity index 100% rename from tests/config_reader.sh rename to httpd/tests/config_reader.sh diff --git a/tests/test_root_dir/index.html b/httpd/tests/test_root_dir/index.html similarity index 100% rename from tests/test_root_dir/index.html rename to httpd/tests/test_root_dir/index.html diff --git a/tests/test_suite.py b/httpd/tests/test_suite.py similarity index 74% rename from tests/test_suite.py rename to httpd/tests/test_suite.py index 504f05a..2c7aaf3 100644 --- a/tests/test_suite.py +++ b/httpd/tests/test_suite.py @@ -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/tests/tests_mieux.sh b/tests/tests_mieux.sh deleted file mode 100755 index 6851190..0000000 --- a/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