From 3a6c8ad9a3a9f81188855bd49bf7482638260d00 Mon Sep 17 00:00:00 2001 From: Francesco Date: Wed, 27 Nov 2024 11:33:14 +0100 Subject: [PATCH] add response (with html + css) --- .idea/cws.iml | 2 ++ .idea/modules.xml | 8 +++++ include/http/http.h | 10 +++--- include/server/server.h | 5 --- include/utils/hashmap.h | 2 +- notes/http-request.md | 2 +- src/http/http.c | 68 ++++++++++++++++++++++++++++++++++++++++- src/server/server.c | 34 +-------------------- src/utils/hashmap.c | 3 +- www/index.html | 1 + www/style.css | 4 +++ 11 files changed, 91 insertions(+), 48 deletions(-) create mode 100644 .idea/cws.iml create mode 100644 .idea/modules.xml create mode 100644 www/style.css diff --git a/.idea/cws.iml b/.idea/cws.iml new file mode 100644 index 0000000..55d7baf --- /dev/null +++ b/.idea/cws.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2ce65a9 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/include/http/http.h b/include/http/http.h index eb69d8b..fc30b02 100644 --- a/include/http/http.h +++ b/include/http/http.h @@ -1,11 +1,7 @@ #ifndef CWS_HTTP_H #define CWS_HTTP_H -#include /* Debug */ -#include -#include - -#define WWW "../www/" /**< Directory used to get html files */ +#define WWW "../www" /**< Directory used to get html files */ /** In the future I'll move conf stuff under a server struct, I can skip just because I want something that works */ #define LOCATION_LEN 1024 #define HTTP_VERSION_LEN 8 @@ -25,6 +21,7 @@ enum http_method { typedef struct http { enum http_method method; /**< HTTP request method */ char location[LOCATION_LEN]; /**< Resource requested */ + char location_path[LOCATION_LEN]; /**< Resource path */ char http_version[HTTP_VERSION_LEN]; /**< HTTP version */ char user_agent[USER_AGENT_LEN]; /**< User-Agent */ char host[HOST_LEN]; /**< Host */ @@ -42,7 +39,8 @@ typedef struct http { http_t *http_parse(char *request_str); void http_parse_method(http_t *request, const char *method); +void http_send_response(http_t *request, int sockfd); +void http_get_content_type(http_t *request, char *content_type); void http_free(http_t *request); -void http_send_response(http_t *request); #endif \ No newline at end of file diff --git a/include/server/server.h b/include/server/server.h index 7b77c3c..f41c04e 100644 --- a/include/server/server.h +++ b/include/server/server.h @@ -16,9 +16,6 @@ #include "utils/hashmap.h" -/* On which port the server will run */ -#define PORT 3030 - /* Clients max queue */ #define BACKLOG 10 @@ -94,6 +91,4 @@ int handle_new_client(int sockfd, struct sockaddr_storage *their_sa, socklen_t * */ void close_fds(bucket_t *bucket); -void send_html_test(int sockfd); - #endif diff --git a/include/utils/hashmap.h b/include/utils/hashmap.h index 5a13287..c4f2c91 100644 --- a/include/utils/hashmap.h +++ b/include/utils/hashmap.h @@ -11,7 +11,7 @@ /** * @brief Hash map struct - * + * */ typedef struct bucket { int sockfd; /**< Client socket descriptor */ diff --git a/notes/http-request.md b/notes/http-request.md index b35e8f8..6d53c58 100644 --- a/notes/http-request.md +++ b/notes/http-request.md @@ -25,7 +25,7 @@ The first line is a *request line*. It has: HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n Content-Length: 88\r\n -Connection: closed\r\n +Connection: close\r\n \r\n ``` diff --git a/src/http/http.c b/src/http/http.c index 93b7aa8..3c273d4 100644 --- a/src/http/http.c +++ b/src/http/http.c @@ -1,5 +1,10 @@ #include "http/http.h" +#include /* Debug */ +#include +#include +#include + #include "utils/colors.h" http_t *http_parse(char *request_str) { @@ -16,6 +21,15 @@ http_t *http_parse(char *request_str) { printf("[http] location: %s\n", pch); strncpy(request->location, pch, LOCATION_LEN); + /* Parse location path */ + /* TODO: fix warnings */ + if (strcmp(request->location, "/") == 0) { + snprintf(request->location_path, LOCATION_LEN, "%s/index.html", WWW); + } else { + snprintf(request->location_path, LOCATION_LEN, "%s%s", WWW, request->location); + } + fprintf(stdout, "[http] location path: %s\n", request->location_path); + /* Parse HTTP version */ pch = strtok(NULL, " \r\n"); printf("[http] version: %s\n", pch); @@ -39,6 +53,58 @@ void http_parse_method(http_t *request, const char *method) { } } -void http_send_response(http_t *request) { /* TODO */ } +void http_send_response(http_t *request, int sockfd) { + FILE *file = fopen(request->location_path, "r"); + if (file == NULL) { + /* 404 */ + /* TODO: improve error handling */ + char response[1024] = + "HTTP/1.1 404 Not Found\r\n" + "Content-Type: text/html\r\n" + "Content-Length: 216\r\n" + "\r\n" + "\n" + "\n" + " Resource Not Found\n" + "\n" + "\n" + "

Resource not found.

\n" + "\n" + ""; + send(sockfd, response, 1024, 0); + return; + } + + char content_type[1024]; + http_get_content_type(request, content_type); + + /* Don't care about numbers, they are random */ + char line[1024] = {0}; + char html_code[32000] = {0}; + char response[65535] = {0}; + + while (fgets(line, 1024, file)) { + strncat(html_code, line, 32000); + } + fclose(file); + + const size_t content_length = strlen(html_code); + snprintf(response, sizeof response, + "%s 200 OK\r\n" + "Content-Type: %s\r\n" + "Content-Length: %zu\r\n" + "Connection: close\r\n" + "\r\n" + "%s", + request->http_version, content_type, content_length, html_code); + + send(sockfd, response, strlen(response), 0); +} + +void http_get_content_type(http_t *request, char *content_type) { + char *ptr = strrchr(request->location_path, '.'); + /* TODO: improve content_type (used to test) */ + snprintf(content_type, 1024, "text/%s", ptr + 1); +} void http_free(http_t *request) { free(request); } diff --git a/src/server/server.c b/src/server/server.c index ac48cc8..832db39 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -108,8 +108,7 @@ void handle_clients(int sockfd) { /* Parse HTTP request */ http_t *request = http_parse(data); - send_html_test(client_fd); - // http_send_response(request); + http_send_response(request, client_fd); http_free(request); /* Clear str */ @@ -186,34 +185,3 @@ void close_fds(bucket_t *bucket) { } } } - -void send_html_test(int sockfd) { - char html[] = - "\n" - "\n" - "\n" - "\n" - " \n" - " \n" - " cws\n" - "\n" - "\n" - "\n" - "

Hello from cws!

\n" - "\n" - "\n" - ""; - - const size_t content_length = strlen(html); - char response[65535] = {0}; - snprintf(response, sizeof response, - "HTTP/1.1 200 OK\r\n" - "Content-Type: text/html\r\n" - "Content-Length: %zu\r\n" - "Connection: close\r\n" - "\r\n" - "%s", - content_length, html); - - send(sockfd, response, strlen(response), 0); -} diff --git a/src/utils/hashmap.c b/src/utils/hashmap.c index c25718e..1916fb3 100644 --- a/src/utils/hashmap.c +++ b/src/utils/hashmap.c @@ -38,7 +38,8 @@ bucket_t *hm_lookup(bucket_t *bucket, int sockfd) { if (bucket[index].sockfd != sockfd) { bucket_t *p; - for (p = bucket[index].next; p != NULL && p->sockfd != sockfd; p = p->next); + for (p = bucket[index].next; p != NULL && p->sockfd != sockfd; p = p->next) + ; return p; } else { return &bucket[index]; diff --git a/www/index.html b/www/index.html index b6992b7..b41deea 100644 --- a/www/index.html +++ b/www/index.html @@ -5,6 +5,7 @@ cws + diff --git a/www/style.css b/www/style.css new file mode 100644 index 0000000..79a3e7e --- /dev/null +++ b/www/style.css @@ -0,0 +1,4 @@ +body { + background-color: black; + color: white; +} \ No newline at end of file