minimal mime management
[webserver.git] / http.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;