minimal mime management
authorLaurent Mazet <mazet@softndesign.org>
Wed, 24 May 2023 22:15:06 +0000 (00:15 +0200)
committerLaurent Mazet <mazet@softndesign.org>
Wed, 24 May 2023 22:15:06 +0000 (00:15 +0200)
http.c
http.h
webserver.c

diff --git a/http.c b/http.c
index 403dd1f762b5ef47fa3287a95c5d7d1ea82b46bf..6ce72c05854f61204aba636b0036b5d2f8e5978c 100644 (file)
--- a/http.c
+++ b/http.c
@@ -59,6 +59,51 @@ typedef struct {
     char *www_authenticate;
 } header_t;
 
+typedef struct {
+    char *ext;
+    char *type;
+    char *charset;
+} mime_t;
+
+#define NB_MIMES 8
+
+mime_t mimes[NB_MIMES] = {
+    {"js", "application/javascript", "iso-8859-1"},
+    {"css", "text/css", "iso-8859-1"},
+    {"htm", "text/html", "iso-8859-1"},
+    {"html", "text/html", "iso-8859-1"},
+    {"png", "image/png", NULL},
+    {"jpeg", "image/jpeg", NULL},
+    {"jpg", "image/jpeg", NULL},
+    {"txt", "text/plain", "iso-8859-1"}
+};
+
+/* find mime type */
+
+mime_t *find_mime_type (char *filename)
+{
+    /* find extention */
+    char *ext = filename + strlen (filename);
+    while (--ext > filename) {
+        if (ext[-1] == '.') {
+            break;
+        }
+    }
+    if (ext == filename) {
+        return NULL;
+    }
+
+    /* find mime */
+    int i;
+    for (i = 0; i < NB_MIMES; i++) {
+        if (strcmp (ext, (mimes + i)->ext) == 0) {
+            return mimes + i;
+        }
+    }
+
+    return NULL;
+}
+
 /* print header values */
 
 void print_header_values (header_t *header)
@@ -107,8 +152,8 @@ char *find_sequence (char *data, int len, char *seq, char **pdata)
 
 int add_line (char **buffer, char *str)
 {
-    VERBOSE (DEBUG, PRINT ("add line: %s", str));
-    int len = ((*buffer) ? strlen (*buffer) : 0) + strlen (str) + 1;
+    VERBOSE (DEBUG, PRINT ("add line: %s\n", str));
+    int len = ((*buffer) ? strlen (*buffer) : 0) + strlen (str) + 3;
     VERBOSE (DEBUG, PRINT ("len: %d\n", len));
     if (*buffer) {
         *buffer = (char *)realloc (*buffer, len);
@@ -116,6 +161,7 @@ int add_line (char **buffer, char *str)
         *buffer = (char *)calloc (len, 1);
     }
     strcat (*buffer, str);
+    strcat (*buffer, "\r\n");
     return len;
 }
 
@@ -124,7 +170,7 @@ int add_status_line (char **buffer, code_t code)
     char tmp[BUFFER_SIZE] = {0};
 
     /* Status */
-    sprintf (tmp, "%s %s\r\n", HTTP_VERSION, codes[code]);
+    sprintf (tmp, "%s %s", HTTP_VERSION, codes[code]);
     add_line (buffer, tmp);
 
     return strlen (*buffer);
@@ -136,7 +182,8 @@ int add_general_header (char **buffer)
 
     /* Date */
     time_t ts = time (NULL);
-    sprintf (tmp, "Date: %s\r\n", ctime (&ts));
+    sprintf (tmp, "Date: %s", ctime (&ts));
+    tmp[strlen (tmp) - 1] = 0; // remove last \n
     add_line (buffer, tmp);
 
     /* Pragma */
@@ -149,11 +196,11 @@ int add_response_header (char **buffer, char *uri)
     char tmp[BUFFER_SIZE] = {0};
 
     /* Location */
-    sprintf (tmp, "Location: %s\r\n", uri);
+    sprintf (tmp, "Location: %s", uri);
     add_line (buffer, tmp);
 
     /* Server */
-    sprintf (tmp, "Server: %s\r\n", SERVER_NAME);
+    sprintf (tmp, "Server: %s", SERVER_NAME);
     add_line (buffer, tmp);
 
     /* WWW-Authentificate */
@@ -174,19 +221,19 @@ int add_entity (char **buffer, char *entity, int size, char *type, char *encodin
 
         /* Content-Encoding */
         if (encoding != NULL) {
-            sprintf (tmp, "Content-Encoding: %s\r\n", encoding);
+            sprintf (tmp, "Content-Encoding: %sn", encoding);
             add_line (buffer, tmp);
         }
 
         /* Content-Length */
-        sprintf (tmp, "Content-Length: %d\r\n", size);
+        sprintf (tmp, "Content-Length: %d", size);
         add_line (buffer, tmp);
 
         /* Content-Type */
-        sprintf (tmp, "Content-Type: %s\r\n", type);
+        sprintf (tmp, "Content-Type: %s", type);
         add_line (buffer, tmp);
 
-        add_line (buffer, "\r\n");
+        add_line (buffer, "");
 
         /* Entity */
         len = strlen (*buffer);
@@ -222,9 +269,9 @@ int error_404 (char **buffer, char *uri)
     return add_entity (buffer, response, strlen (response), "text/html", "iso-8859-1");
 }
 
-/* response html */
+/* generic response */
 
-int response_html (char **buffer, char *location, char *response)
+int generic_response (char **buffer, char *location, char *response, int size)
 {
     int len = 0;
     VERBOSE (DEBUG, PRINT ("add_status_line %d\n", len));
@@ -233,9 +280,10 @@ int response_html (char **buffer, char *location, char *response)
     len = add_general_header (buffer);
     VERBOSE (DEBUG, PRINT ("add_response_header %d\n", len));
     len = add_response_header (buffer, location);
+    mime_t *mime = find_mime_type (location);
 
     VERBOSE (DEBUG, PRINT ("add_entity %d\n", len));
-    return add_entity (buffer, response, strlen (response), "text/html", "iso-8859-1");
+    return add_entity (buffer, response, size, mime->type, mime->charset);
 }
 
 /* trim string */
@@ -252,8 +300,9 @@ char *trim (char *str)
 
 /* main HTTP processing */
 
-int processing (char *data, int len, char *root, char **pdata)
+int processing (char *data, int len, conf_t *conf, char **pdata)
 {
+    char location[BUFFER_SIZE] = {0};
     VERBOSE (DEBUG, PRINT ("Start processing\n"));
 
     /* check method */
@@ -284,9 +333,9 @@ int processing (char *data, int len, char *root, char **pdata)
     VERBOSE (INFO, PRINT ("%s %s (%s)\n", (type == get_e) ? "Get" : (type == head_e) ? "Head" : "Post", uri, version));
 
     /* analyse uri */
-    char *filename = (char *)calloc (strlen (root) + strlen (uri) + 2, 1);
-    //sprintf (filename, "%s%s%s", root, ((root[strlen (root) - 1] != '/') && (uri[0] != '/')) ? "/" : "", uri);
-    sprintf (filename, "%s/%s", root, uri);
+    char *filename = (char *)calloc (strlen (conf->root) + strlen (uri) + 2, 1);
+    //sprintf (filename, "%s%s%s", conf->root, ((conf->root[strlen (conf->root) - 1] != '/') && (uri[0] != '/')) ? "/" : "", uri);
+    sprintf (filename, "%s/%s", conf->root, uri);
 
     /* check header */
     header_t header = {0};
@@ -345,9 +394,11 @@ int processing (char *data, int len, char *root, char **pdata)
         VERBOSE (DEBUG, PRINT ("Read file %s\n", filename));
         len = readfile (&buffer, filename);
         if (len == 0) {
-            len = error_404 (pdata, "http://localhost/");
+            sprintf (location, "http://%s/", conf->servername);
+            len = error_404 (pdata, location);
         } else {
-            len = response_html (pdata, "http://localhost/", buffer);
+            sprintf (location, "http://%s%s", conf->servername, filename);
+            len = generic_response (pdata, location, buffer, len);
             free (buffer);
         }
         break;
diff --git a/http.h b/http.h
index 4e6307fef043054037c39865b9ca2730d38bc8cd..d25fa692de118510cf1438b9224c6ba50d257fb3 100644 (file)
--- a/http.h
+++ b/http.h
@@ -1,7 +1,17 @@
 #ifndef __HTTP_H__
 #define __HTTP_H__
 
-int processing (char *data, int len, char *root, char **pdata);
+/* type */
+
+typedef struct {
+    char *root;
+    char *servername;
+    char *charset;
+} conf_t;
+
+/* functions */
+
+int processing (char *data, int len, conf_t *conf, char **pdata);
 
 #endif /* __HTTP_H__ */
 
index 99e2d20f3ec740effd4759884aa4f521faaaf711..e0128e66aa243485633890fd4a6693d00876c33d 100644 (file)
@@ -18,6 +18,8 @@
 
 #define BUFFER_SIZE 4096
 #define ROOT_DIR "webroot"
+#define SERVER_NAME "localhost"
+#define CHARSET "iso-8859-1"
 
 /* macros */
 
@@ -26,6 +28,8 @@
 char *progname = NULL;
 int port = 8080;
 char *root = ROOT_DIR;
+char *servername = SERVER_NAME;
+char *charset = CHARSET;
 
 /* help function */
 
@@ -112,6 +116,9 @@ int main (int argc, char *argv[])
     }
     closedir (pdir);
 
+    /* configuration */
+    conf_t conf = {root, servername, charset};
+
     /* init network stack */
     VERBOSE (DEBUG, PRINT ("Initializing socket\n"));
     init_network_context ();
@@ -143,7 +150,7 @@ int main (int argc, char *argv[])
 
             // processing
             VERBOSE (DEBUG, PRINT ("Processing %s\n", data));
-            len = processing (data, len, root, &output);
+            len = processing (data, len, &conf, &output);
 
             VERBOSE (DEBUG, PRINT ("Sending data (%d)\n%s\n", len, data));
             int rc = send_data (output, len);