From 80ed6dea3ebffe22ff43602ae85662cecacf4a45 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Wed, 16 Dec 2020 18:35:11 +0100 Subject: [PATCH] Added http header strict and not strict mode --- src/client.c | 4 ++-- src/http.c | 12 ++++++------ src/http.h | 7 +++++-- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/client.c b/src/client.c index 0ea80f5..50368ce 100644 --- a/src/client.c +++ b/src/client.c @@ -79,9 +79,9 @@ int client_request_handler(sock *client, int req_num) { goto respond; } - hdr_connection = http_get_header_field(&req.hdr, "Connection"); + hdr_connection = http_get_header_field(&req.hdr, "Connection", HTTP_NOT_STRICT); client_keep_alive = hdr_connection != NULL && strncmp(hdr_connection, "keep-alive", 10) == 0; - host = http_get_header_field(&req.hdr, "Host"); + host = http_get_header_field(&req.hdr, "Host", HTTP_NOT_STRICT); if (host == NULL || strchr(host, '/') != NULL) { res.status = http_get_status(400); sprintf(err_msg, "The client provided no or an invalid Host header field."); diff --git a/src/http.c b/src/http.c index 2bdce14..35a3aa7 100644 --- a/src/http.c +++ b/src/http.c @@ -9,14 +9,14 @@ #include "utils.h" -void http_to_camel_case(char *str) { +void http_to_camel_case(char *str, int strict) { char last = '-'; char ch; for (int i = 0; i < strlen(str); i++) { ch = str[i]; if (last == '-' && ch >= 'a' && ch <= 'z') { str[i] = (char) ((int) ch & 0x5F); - } else if (last != '-' && ch >= 'A' && ch <= 'Z') { + } else if (last != '-' && ch >= 'A' && ch <= 'Z' && strict == HTTP_STRICT) { str[i] = (char) ((int) ch | 0x20); } last = str[i]; @@ -132,7 +132,7 @@ int http_receive_request(sock *client, http_req *req) { len = pos1 - ptr; req->hdr.fields[req->hdr.field_num][0] = malloc(len + 1); sprintf(req->hdr.fields[req->hdr.field_num][0], "%.*s", (int) len, ptr); - http_to_camel_case(req->hdr.fields[req->hdr.field_num][0]); + http_to_camel_case(req->hdr.fields[req->hdr.field_num][0], HTTP_NOT_STRICT); pos1++; pos2 = pos0 - 1; @@ -153,11 +153,11 @@ int http_receive_request(sock *client, http_req *req) { } } -char *http_get_header_field(http_hdr *hdr, const char *field_name) { +char *http_get_header_field(http_hdr *hdr, const char *field_name, int strict) { size_t len = strlen(field_name); char *_field_name = malloc(len + 1); strcpy(_field_name, field_name); - http_to_camel_case(_field_name); + http_to_camel_case(_field_name, strict); for (int i = 0; i < hdr->field_num; i++) { if (strncmp(hdr->fields[i][0], _field_name, len) == 0) { free(_field_name); @@ -175,7 +175,7 @@ void http_add_header_field(http_hdr *hdr, const char *field_name, const char *fi char *_field_value = malloc(len_value + 1); strcpy(_field_name, field_name); strcpy(_field_value, field_value); - http_to_camel_case(_field_name); + http_to_camel_case(_field_name, HTTP_NOT_STRICT); hdr->fields[hdr->field_num][0] = _field_name; hdr->fields[hdr->field_num][1] = _field_value; hdr->field_num++; diff --git a/src/http.h b/src/http.h index bcbb9a5..da19bad 100644 --- a/src/http.h +++ b/src/http.h @@ -8,6 +8,9 @@ #ifndef NECRONDA_SERVER_HTTP_H #define NECRONDA_SERVER_HTTP_H +#define HTTP_STRICT 1 +#define HTTP_NOT_STRICT 0 + typedef struct { unsigned short code; char type[16]; @@ -151,7 +154,7 @@ const char *http_error_icon = "eTonQXJpYWwnLHNhbnMtc2VyaWYiPjooPC90ZXh0Pjwvc3ZnPgo=\"/>\n"; -void http_to_camel_case(char *str); +void http_to_camel_case(char *str, int strict); void http_free_hdr(http_hdr *hdr); @@ -161,7 +164,7 @@ void http_free_res(http_res *res); int http_receive_request(sock *client, http_req *req); -char *http_get_header_field(http_hdr *hdr, const char *field_name); +char *http_get_header_field(http_hdr *hdr, const char *field_name, int strict); void http_add_header_field(http_hdr *hdr, const char *field_name, const char *field_value);