summaryrefslogtreecommitdiff
path: root/Year_3/TSDWL
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2021-10-22 20:44:24 +0200
committerSanto Cariotti <santo@dcariotti.me>2021-10-22 20:44:24 +0200
commitb809ef430ede600091f79908ea52597d2271f957 (patch)
tree65dd782bb111f7b655ecbfda7a722dfa9b8ec413 /Year_3/TSDWL
parent244f12157c830f91df1ec652215b23cb9a208f46 (diff)
parse the request
Diffstat (limited to 'Year_3/TSDWL')
-rw-r--r--Year_3/TSDWL/webserver/server.c102
1 files changed, 97 insertions, 5 deletions
diff --git a/Year_3/TSDWL/webserver/server.c b/Year_3/TSDWL/webserver/server.c
index 9bf1f7d..e2f6a3e 100644
--- a/Year_3/TSDWL/webserver/server.c
+++ b/Year_3/TSDWL/webserver/server.c
@@ -1,3 +1,7 @@
+/* An example of the work of this file is showed at [1]
+ *
+ * [1] https://it.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Richiesta_GET_e_risposta_di_successo
+ */
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
@@ -8,6 +12,33 @@
#define DEFAULT_WWW "./www"
+typedef enum {
+ GET,
+ /* TODO: types below */
+ HEAD,
+ OPTIONS,
+ POST,
+ PUT,
+ PATCH,
+ DELETE
+} methods;
+
+typedef enum {
+ /* Some of the HTTP versions defined at [1]
+ *
+ * [1] https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#History
+ */
+ HTTP1, /* HTTP/1.0 */
+ HTTP1_1, /* HTTP/1.1 */
+ HTTP2, /* HTTP/2 */
+} http_t;
+
+typedef struct {
+ methods method;
+ char path[256]; /* FIXME: handle path with more than 256 chars */
+ http_t http_version;
+} request_t;
+
/* TODO: Make the parsing of headers */
void
read_headers(int* fd, char** headers, int* headers_num)
@@ -30,7 +61,7 @@ read_headers(int* fd, char** headers, int* headers_num)
exit(1);
}
- *(buffer + i) = ch;
+ buffer[i] = ch;
if (ch == '\n' && (i < 1 || buffer[i - 1] == '\r')) {
break;
}
@@ -38,12 +69,12 @@ read_headers(int* fd, char** headers, int* headers_num)
i++;
}
- buffer[i + 1] = '\0';
+ buffer[i - 1] = '\0';
if (i < 2) {
break;
}
- memcpy(headers[*headers_num], buffer, i + 1);
+ memcpy(headers[*headers_num], buffer, i);
(*headers_num)++;
}
}
@@ -58,6 +89,60 @@ get_client_ip(int fd, char* buffer)
}
int
+parse_first_line(request_t* request, char* header, size_t len)
+{
+ char* token;
+ int i;
+
+ i = 0;
+ token = strtok(header, " ");
+ do {
+ switch (i) {
+ case 0: {
+ if (strcmp(token, "GET") == 0) {
+ request->method = GET;
+ } else {
+ fprintf(stderr, "'%s' method not supported\n", token);
+ goto parse_error;
+ }
+ /* TODO: Handle the other HTTP methods */
+ break;
+ }
+ case 1: {
+ strcpy(request->path, token);
+ break;
+ }
+ case 2: {
+ if (strcmp(token, "HTTP/1.0") == 0) {
+ request->http_version = HTTP1;
+ } else if (strcmp(token, "HTTP/1.1") == 0) {
+ request->http_version = HTTP1_1;
+ } else if (strcmp(token, "HTTP/2") == 0) {
+ request->http_version = HTTP2;
+ } else {
+ fprintf(stderr, "'%s' version not supported\n", token);
+ goto parse_error;
+ }
+ break;
+ }
+ /* If it comes here, it means that the header have more than 3 tokens */
+ default: {
+ fprintf(stderr, "Header does not have a valid syntax\n");
+ goto parse_error;
+ }
+ }
+
+ i++;
+ token = strtok(NULL, " ");
+ } while (token != NULL);
+
+ return 0;
+
+parse_error:
+ return -1;
+}
+
+int
main(int argc, char* argv[])
{
char* www_path;
@@ -68,6 +153,8 @@ main(int argc, char* argv[])
struct sockaddr_in address;
char client_ip[20];
socklen_t address_len;
+ char* buffer;
+ request_t request;
if (argc < 2) {
fprintf(stderr, "Usage: %s <port> [root_path]", argv[0]);
@@ -111,11 +198,16 @@ main(int argc, char* argv[])
read_headers(&clientfd, headers, &headers_num);
+ if (headers_num == 0) {
+ buffer = "You must specify almost one header\n";
+ write(clientfd, buffer, strlen(buffer) + 1);
+ }
+
+ parse_first_line(&request, headers[0], strlen(headers[0]));
+
for (i = 0; i < headers_num; ++i) {
- printf("%s", headers[i]);
free(headers + i);
}
-
printf("[Connection closed]\n\n");
close(clientfd);
}