add response (with html + css)

This commit is contained in:
2024-11-27 11:33:14 +01:00
parent dc4ef7c7d5
commit 3a6c8ad9a3
11 changed files with 91 additions and 48 deletions

2
.idea/cws.iml generated Normal file
View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<module classpath="External" external.linked.project.id="cws" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="Meson" type="CPP_MODULE" version="4" />

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/cws.iml" filepath="$PROJECT_DIR$/.idea/cws.iml" />
</modules>
</component>
</project>

View File

@@ -1,11 +1,7 @@
#ifndef CWS_HTTP_H #ifndef CWS_HTTP_H
#define CWS_HTTP_H #define CWS_HTTP_H
#include <stdio.h> /* Debug */ #define WWW "../www" /**< Directory used to get html files */
#include <stdlib.h>
#include <string.h>
#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 */ /** 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 LOCATION_LEN 1024
#define HTTP_VERSION_LEN 8 #define HTTP_VERSION_LEN 8
@@ -25,6 +21,7 @@ enum http_method {
typedef struct http { typedef struct http {
enum http_method method; /**< HTTP request method */ enum http_method method; /**< HTTP request method */
char location[LOCATION_LEN]; /**< Resource requested */ char location[LOCATION_LEN]; /**< Resource requested */
char location_path[LOCATION_LEN]; /**< Resource path */
char http_version[HTTP_VERSION_LEN]; /**< HTTP version */ char http_version[HTTP_VERSION_LEN]; /**< HTTP version */
char user_agent[USER_AGENT_LEN]; /**< User-Agent */ char user_agent[USER_AGENT_LEN]; /**< User-Agent */
char host[HOST_LEN]; /**< Host */ char host[HOST_LEN]; /**< Host */
@@ -42,7 +39,8 @@ typedef struct http {
http_t *http_parse(char *request_str); http_t *http_parse(char *request_str);
void http_parse_method(http_t *request, const char *method); 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_free(http_t *request);
void http_send_response(http_t *request);
#endif #endif

View File

@@ -16,9 +16,6 @@
#include "utils/hashmap.h" #include "utils/hashmap.h"
/* On which port the server will run */
#define PORT 3030
/* Clients max queue */ /* Clients max queue */
#define BACKLOG 10 #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 close_fds(bucket_t *bucket);
void send_html_test(int sockfd);
#endif #endif

View File

@@ -25,7 +25,7 @@ The first line is a *request line*. It has:
HTTP/1.1 200 OK\r\n HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n Content-Type: text/html\r\n
Content-Length: 88\r\n Content-Length: 88\r\n
Connection: closed\r\n Connection: close\r\n
\r\n \r\n
<HTML> <HTML>
``` ```

View File

@@ -1,5 +1,10 @@
#include "http/http.h" #include "http/http.h"
#include <stdio.h> /* Debug */
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include "utils/colors.h" #include "utils/colors.h"
http_t *http_parse(char *request_str) { http_t *http_parse(char *request_str) {
@@ -16,6 +21,15 @@ http_t *http_parse(char *request_str) {
printf("[http] location: %s\n", pch); printf("[http] location: %s\n", pch);
strncpy(request->location, pch, LOCATION_LEN); 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 */ /* Parse HTTP version */
pch = strtok(NULL, " \r\n"); pch = strtok(NULL, " \r\n");
printf("[http] version: %s\n", pch); 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"
"<html>\n"
"<head>\n"
" <title>Resource Not Found</title>\n"
"</head>\n"
"<body>\n"
"<p>Resource not found.</p>\n"
"</body>\n"
"</html>";
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); } void http_free(http_t *request) { free(request); }

View File

@@ -108,8 +108,7 @@ void handle_clients(int sockfd) {
/* Parse HTTP request */ /* Parse HTTP request */
http_t *request = http_parse(data); http_t *request = http_parse(data);
send_html_test(client_fd); http_send_response(request, client_fd);
// http_send_response(request);
http_free(request); http_free(request);
/* Clear str */ /* Clear str */
@@ -186,34 +185,3 @@ void close_fds(bucket_t *bucket) {
} }
} }
} }
void send_html_test(int sockfd) {
char html[] =
"<!DOCTYPE html>\n"
"<html lang=\"en\">\n"
"\n"
"<head>\n"
" <meta charset=\"UTF-8\">\n"
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
" <title>cws</title>\n"
"</head>\n"
"\n"
"<body>\n"
"<h1>Hello from cws!</h1>\n"
"</body>\n"
"\n"
"</html>";
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);
}

View File

@@ -38,7 +38,8 @@ bucket_t *hm_lookup(bucket_t *bucket, int sockfd) {
if (bucket[index].sockfd != sockfd) { if (bucket[index].sockfd != sockfd) {
bucket_t *p; 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; return p;
} else { } else {
return &bucket[index]; return &bucket[index];

View File

@@ -5,6 +5,7 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>cws</title> <title>cws</title>
<link rel="stylesheet" href="style.css">
</head> </head>
<body> <body>

4
www/style.css Normal file
View File

@@ -0,0 +1,4 @@
body {
background-color: black;
color: white;
}