code not working
authorLaurent Mazet <mazet@softndesign.org>
Sun, 21 May 2023 13:23:26 +0000 (15:23 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Sun, 21 May 2023 13:23:26 +0000 (15:23 +0200)
http.c
http.h
webserver.c

diff --git a/http.c b/http.c
index 288d7b09190be9b9e3e6646d1d172e733bb8a834..614d934142de41980fece95190e894759b02dbbc 100644 (file)
--- a/http.c
+++ b/http.c
@@ -5,9 +5,237 @@
 
 #include "http.h"
 
-int processing (unsigned char *data, int len, unsigned char **pdata) {
-    *pdata = data;
+#define HTTP_VERSION "HTTP/1.0"
+#define SERVER_NAME "Webserver/0.0.1"
+
+char **codes = {
+    "200 OK",
+    "201 Created",
+    "202 Accepted",
+    "204 No Content",
+    "301 Moved Permanently",
+    "302 Moved Temporarily",
+    "304 Not Modified",
+    "400 Bad Request",
+    "401 Unauthorized",
+    "403 Forbidden",
+    "404 Not Found",
+    "500 Internal Server Error",
+    "501 Not Implemented",
+    "502 Bad Gateway",
+    "503 Service Unavailable"};
+
+typedef enum {
+    c200 = 0, c201, c202, c204,
+    c301, c302, c304, c400,
+    c401, c403, c404, c500,
+    c501, c502, c503
+} code_t;
+
+typedef enum {
+    not_supported_e = 0, get_e, head_e, post_e
+} method_t;
+
+typedef struct {
+    char *allow;
+    char *authorization;
+    char *content_encoding;
+    char *content_length;
+    char *content_type;
+    char *date;
+    char *expires;
+    char *from;
+    char *if_modified_since;
+    char *last_modified;
+    char *location;
+    char *pragma;
+    char *referer;
+    char *server;
+    char *user_agent;
+    char *www_authenticate;
+} header_t;
+
+/* print header values */
+
+void print_header_values (header_t *header)
+{
+    printf ("allow = '%s'\n", header->allow);
+    printf ("authorization = '%s'\n", header->authorization);
+    printf ("content_encoding = '%s'\n", header->content_encoding);
+    printf ("content_length = '%s'\n", header->content_length);
+    printf ("content_type = '%s'\n", header->content_type);
+    printf ("date = '%s'\n", header->date);
+    printf ("expires = '%s'\n", header->expires);
+    printf ("from = '%s'\n", header->from);
+    printf ("if_modified_since = '%s'\n", header->if_modified_since);
+    printf ("last_modified = '%s'\n", header->last_modified);
+    printf ("location = '%s'\n", header->location);
+    printf ("pragma = '%s'\n", header->pragma);
+    printf ("referer = '%s'\n", header->referer);
+    printf ("server = '%s'\n", header->server);
+    printf ("user_agent = '%s'\n", header->user_agent);
+    printf ("www_authenticate = '%s'\n", header->www_authenticate);
+}
+
+/* find sequence*/
+
+char *find_sequence (char *data, int len, char *seq, char **pdata)
+{
+
+    int size = strlen (seq);
+
+    int i;
+    for (i = 0; i < len - size + 1; i++) {
+        if (strncmp (data + i, seq, size) == 0) {
+            data[i] = 0;
+            if (pdata != NULL) {
+                *pdata = data + i + size;
+            }
+            return data;
+        }
+    }
+
+    return NULL;
+}
+
+/* response entity */
+
+int add_status_line (char **buffer, int len)
+{
     return len;
 }
 
+int add_general_header (char **buffer, int len)
+{
+    return len;
+}
+
+int add_response_header (char **buffer, int len)
+{
+    return len;
+}
+
+int add_entity (char **buffer, int len, unsigned char *entity, int size, char *type)
+{
+    return len;
+}
+
+/* error 400 */
+
+int error_400 (char **buffer)
+{
+    
+}
+
+/* trim string */
+
+char *trim (char *str)
+{
+    if (str != NULL) {
+        while ((*str == ' ') || (*str == '\t')) {
+            str++;
+        }
+    }
+    return str;
+}
+
+/* main HTTP processing */
+
+int processing (char *data, int len, char **pdata)
+{
+    char *saved_data = data;
+    VERBOSE (DEBUG, PRINT ("Start processing\n"));
+
+    /* check method */
+    char *line = find_sequence (data, len, "\r\n", &data);
+    if (line == NULL) {
+        VERBOSE (WARNING, PRINT ("Unknown received data\n"));
+        if (pdata != NULL) {
+            *pdata = NULL;
+        }
+        return 0;
+    }
+    VERBOSE (DEBUG, PRINT ("Command line: '%s'\n", line));
+
+    char *method = strtok (line, " ");
+    char *uri = strtok (NULL, " ");
+    char *version = strtok (NULL, " ");
+    method_t type = not_supported_e;
+    if (strcmp (method, "GET") == 0) {
+        type = get_e;
+    } else if (strcmp ("HEAD", method) == 0) {
+        type = head_e;
+    } else if (strcmp ("POST", method) == 0) {
+        type = post_e;
+    } else {
+        VERBOSE (WARNING, PRINT ("Unkown method: %s\n", method));
+    } else {
+        free (saved_data);
+        return error_400 (pdata);
+    }
+    VERBOSE (INFO, PRINT ("%s %s (%s)\n", (type == get_e) ? "Get" : (type == head_e) ? "Head" : "Post", uri, version));
+
+    /* check header */
+    header_t header = {0};
+    while (strcmp (line = find_sequence (data, len, "\r\n", &data), "") != 0) {
+        VERBOSE (DEBUG, PRINT ("Header line: '%s'\n", line));
+        char *field = strtok (line, ":");
+        char *value = trim (strtok (NULL, "\r"));
+        VERBOSE (DEBUG, PRINT ("Field: %s\nValue: %s\n", field, value));
+        if (*line == 0) {
+            break;
+        }
+        
+        VERBOSE (DEBUG, PRINT ("Analyse field\n"));
+        if (strcmp (field, "Allow") == 0) {
+            header.allow = value;
+        } else if (strcmp (field, "Authorization") == 0) {
+            header.authorization = value;
+        } else if (strcmp (field, "Content-Encoding") == 0) {
+            header.content_encoding = value;
+        } else if (strcmp (field, "Content-Length") == 0) {
+            header.content_length = value;
+        } else if (strcmp (field, "Content-Type") == 0) {
+            header.content_type = value;
+        } else if (strcmp (field, "Date") == 0) {
+            header.date = value;
+        } else if (strcmp (field, "Expires") == 0) {
+            header.expires = value;
+        } else if (strcmp (field, "From") == 0) {
+            header.from = value;
+        } else if (strcmp (field, "If-Modified-Since") == 0) {
+            header.if_modified_since = value;
+        } else if (strcmp (field, "Last-Modified") == 0) {
+            header.last_modified = value;
+        } else if (strcmp (field, "Location") == 0) {
+            header.location = value;
+        } else if (strcmp (field, "Pragma") == 0) {
+            header.pragma = value;
+        } else if (strcmp (field, "Referer") == 0) {
+            header.referer = value;
+        } else if (strcmp (field, "Server") == 0) {
+            header.server = value;
+        } else if (strcmp (field, "User-Agent") == 0) {
+            header.user_agent = value;
+        } else if (strcmp (field, "WWW-Authenticate") == 0) {
+            header.www_authenticate = value;
+        } else {
+            VERBOSE (WARNING, PRINT ("Unknown header field: '%s'\n", field));
+        }
+    }
+    VERBOSE (DEBUG, print_header_values (&header));
+
+    /* processing data */
+    if (data) {
+        VERBOSE (DEBUG, PRINT ("Processing data: %s\n", data));
+    }
+
+    /* cleaning */
+    free (saved_data);
+
+    /* response */
+    *pdata = strdup ("HTTP/1.0 200 OK\r\nDate: Sat, 20 May 2023 16:37:46 GMT\r\nServer: Webserver/0.0.1 (Debian)\r\nLocation: http://localhost/\r\nContent-Length: 77\r\nContent-Type: text/html; charset=iso-8859-1\r\n\r\n<html><head><title>Test</title></head><body><p>This a test</p></body></html>");
+    return strlen (*pdata);
+}
+
 /* vim: set ts=4 sw=4 et: */
diff --git a/http.h b/http.h
index 3ec7d5c781b094e3e3276f290686f820d84a4231..17db432b769eaf92c222a21f71910a91ad816934 100644 (file)
--- a/http.h
+++ b/http.h
@@ -1,7 +1,7 @@
 #ifndef __HTTP_H__
 #define __HTTP_H__
 
-int processing (unsigned char *data, int len, unsigned char **pdata);
+int processing (char *data, int len, char **pdata);
 
 #endif /* __HTTP_H__ */
 
index 8209ab86432233c0559f50ca55e6ca58a840dc81..366973f9ae607636f498fd55c15e963640f06c02 100644 (file)
@@ -120,7 +120,7 @@ int main (int argc, char *argv[])
 
             // processing
             VERBOSE (DEBUG, PRINT ("Processing %s\n", data));
-            len = processing (data, len, &data);
+            len = processing ((char *)data, len, (char **)&data);
 
             int rc = send_data (data, len);
             if (rc == 0) {