From: Laurent Mazet Date: Wed, 24 May 2023 22:15:06 +0000 (+0200) Subject: minimal mime management X-Git-Url: https://secure.softndesign.org/git/?a=commitdiff_plain;h=2bec4aa77cff1669f0c29d1ca426e4fa714b0928;p=webserver.git minimal mime management --- diff --git a/http.c b/http.c index 403dd1f..6ce72c0 100644 --- 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 4e6307f..d25fa69 100644 --- 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__ */ diff --git a/webserver.c b/webserver.c index 99e2d20..e0128e6 100644 --- a/webserver.c +++ b/webserver.c @@ -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);