add response (with html + css)
This commit is contained in:
2
.idea/cws.iml
generated
Normal file
2
.idea/cws.iml
generated
Normal 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
8
.idea/modules.xml
generated
Normal 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>
|
||||
@@ -1,11 +1,7 @@
|
||||
#ifndef CWS_HTTP_H
|
||||
#define CWS_HTTP_H
|
||||
|
||||
#include <stdio.h> /* Debug */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
/**
|
||||
* @brief Hash map struct
|
||||
*
|
||||
*
|
||||
*/
|
||||
typedef struct bucket {
|
||||
int sockfd; /**< Client socket descriptor */
|
||||
|
||||
@@ -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
|
||||
<HTML>
|
||||
```
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#include "http/http.h"
|
||||
|
||||
#include <stdio.h> /* Debug */
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#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"
|
||||
"<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); }
|
||||
|
||||
@@ -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[] =
|
||||
"<!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);
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>cws</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
4
www/style.css
Normal file
4
www/style.css
Normal file
@@ -0,0 +1,4 @@
|
||||
body {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
Reference in New Issue
Block a user