. Content-Type is now derived from mime_map

. Reordered default_extension_map[] for search speed
. Added uri_content_type()
. process_get() calls uri_content_type() when needed
. Removed a couple of debugf()s from process_request
This commit is contained in:
Emil Mikulic 2003-03-08 08:33:24 +00:00
parent 7a2daecf22
commit 5c0c18798c

View File

@ -18,7 +18,7 @@
* . Keep-alive connections. * . Keep-alive connections.
* . Chroot, set{uid|gid}. * . Chroot, set{uid|gid}.
* . Port to Win32. * . Port to Win32.
* . Detect Content-Type from a list of content types. * x Detect Content-Type from a list of content types.
* x Log Referer, User-Agent. * x Log Referer, User-Agent.
* . Ensure URIs requested are safe. * . Ensure URIs requested are safe.
*/ */
@ -124,12 +124,15 @@ static FILE *logfile = NULL;
static int want_chroot = 0; static int want_chroot = 0;
static const char *default_extension_map[] = { static const char *default_extension_map[] = {
"audio/mpeg mp2 mp3 mpga", /* Linear search used - order affects speed significantly.
"image/gif gif", * This could be done in a better way.
"image/jpeg jpeg jpe jpg", */
"image/png png",
"text/css css",
"text/html html htm", "text/html html htm",
"image/png png",
"image/jpeg jpeg jpe jpg",
"image/gif gif",
"audio/mpeg mp2 mp3 mpga",
"text/css css",
"text/plain txt asc", "text/plain txt asc",
"text/xml xml", "text/xml xml",
"video/mpeg mpeg mpe mpg", "video/mpeg mpeg mpe mpg",
@ -296,6 +299,29 @@ static void parse_extension_map_file(const char *filename)
/* ---------------------------------------------------------------------------
* Uses the mime_map to determines a Content-Type: for a requested URI.
*/
static const char *uri_content_type(const char *uri)
{
struct mime_mapping *mapping;
int urilen = strlen(uri);
LIST_FOREACH(mapping, &mime_map, entries)
{
int extlen = strlen(mapping->extension);
if (urilen >= extlen+3) /* "/a." + "ext" */
{
if (uri[urilen-1-extlen] == '.' &&
strcmp(uri+urilen-extlen, mapping->extension) == 0)
return mapping->mimetype;
}
}
return default_mimetype;
}
/* --------------------------------------------------------------------------- /* ---------------------------------------------------------------------------
* Initialize the sockin global. This is the socket that we accept * Initialize the sockin global. This is the socket that we accept
* connections from. * connections from.
@ -741,6 +767,7 @@ static void parse_request(struct connection *conn)
static void process_get(struct connection *conn) static void process_get(struct connection *conn)
{ {
char *decoded_url, *target, *tmp; char *decoded_url, *target, *tmp;
const char *mimetype = NULL;
struct stat filestat; struct stat filestat;
/* work out path of file being requested */ /* work out path of file being requested */
@ -749,17 +776,19 @@ static void process_get(struct connection *conn)
if (decoded_url[strlen(decoded_url)-1] == '/') if (decoded_url[strlen(decoded_url)-1] == '/')
{ {
asprintf(&target, "%s%s%s", wwwroot, decoded_url, index_name); asprintf(&target, "%s%s%s", wwwroot, decoded_url, index_name);
mimetype = uri_content_type(index_name);
} }
else else
{ {
asprintf(&target, "%s%s", wwwroot, decoded_url); asprintf(&target, "%s%s", wwwroot, decoded_url);
mimetype = uri_content_type(decoded_url);
} }
free(decoded_url); free(decoded_url);
debugf(">>>%s<<<\n", target); debugf(">>>%s<<<\n", target);
free(target);
conn->reply_file = fopen(target, "rb"); conn->reply_file = fopen(target, "rb");
free(target);
if (conn->reply_file == NULL) if (conn->reply_file == NULL)
{ {
/* fopen() failed */ /* fopen() failed */
@ -787,21 +816,26 @@ static void process_get(struct connection *conn)
conn->reply_length = filestat.st_size; conn->reply_length = filestat.st_size;
asprintf(&tmp, asprintf(&tmp,
"HTTP/1.1 200 OK\r\n" "HTTP/1.1 200 OK\r\n"
"Date: %s\r\n" "Date: %s\r\n"
"Server: %s\r\n" "Server: %s\r\n"
"Connection: close\r\n" "Connection: close\r\n"
"Content-Length: %d\r\n" "Content-Length: %d\r\n"
"Content-Type: text/plain\r\n" /* FIXME */ "Content-Type: %s\r\n"
, rfc1123_date(time(NULL)), pkgname, conn->reply_length ,
rfc1123_date(time(NULL)), pkgname, conn->reply_length,
mimetype
); );
if (tmp == NULL) errx(1, "out of memory in asprintf()"); if (tmp == NULL) errx(1, "out of memory in asprintf()");
debugf("uri=%s, content-type=%s\n", conn->uri, mimetype);
conn->header_length = asprintf(&(conn->header), conn->header_length = asprintf(&(conn->header),
"%s" "%s"
"Last-Modified: %s\r\n" "Last-Modified: %s\r\n"
"\r\n" "\r\n"
, tmp, rfc1123_date(filestat.st_mtime) ,
tmp, rfc1123_date(filestat.st_mtime)
); );
free(tmp); free(tmp);
if (conn->header == NULL) errx(1, "out of memory in asprintf()"); if (conn->header == NULL) errx(1, "out of memory in asprintf()");
@ -816,7 +850,6 @@ static void process_get(struct connection *conn)
static void process_request(struct connection *conn) static void process_request(struct connection *conn)
{ {
parse_request(conn); parse_request(conn);
debugf("method=``%s'', url=``%s''\n", conn->method, conn->uri);
if (strcmp(conn->method, "GET") == 0) if (strcmp(conn->method, "GET") == 0)
process_get(conn); process_get(conn);
@ -841,11 +874,9 @@ static void process_request(struct connection *conn)
/* advance state */ /* advance state */
conn->state = SEND_HEADER; conn->state = SEND_HEADER;
/* request, method, url not needed anymore */ /* request not needed anymore */
debugf("%s", conn->request);
free(conn->request); free(conn->request);
conn->request = NULL; conn->request = NULL;
debugf("%s-=-\n", conn->header);
} }