diff -ruN fnord-1.10-20090620fwb/httpd.c fnord-1.10-20090627fwb/httpd.c --- fnord-1.10-20090620fwb/httpd.c 2009-06-20 18:14:59.000000000 +0200 +++ fnord-1.10-20090627fwb/httpd.c 2009-06-27 19:51:52.000000000 +0200 @@ -99,6 +99,12 @@ #define CGI_TIMEOUT (5*60) /* 5 minutes time-out for CGI to complete */ +/* An Expire-Date can be set by specifying a minute value in + * the mimetab for each file suffix. The Expire-Date will be + * the Request-Time plus the minute value. + * Uncomment if no "Expires:" header should be sent: */ +#define EXPIRESHEADER + /* defining USE_SENDFILE enables zero-copy TCP on Linux for static * files. I measured over 320 meg per second with apache bench over * localhost with sendfile and keep-alive. However, sendfile does not @@ -716,43 +722,44 @@ static char* encoding=0; static char* mimetype="text/plain"; +static uint32_t expires = 480; -static struct mimeentry { const char* name, *type; } mimetab[] = { - { "html", "text/html" }, - { "htm", "text/html" }, - { "css", "text/css" }, - { "dvi", "application/x-dvi" }, - { "ps", "application/postscript" }, - { "pdf", "application/pdf" }, - { "gif", "image/gif" }, - { "png", "image/png" }, - { "jpeg", "image/jpeg" }, - { "bild", "image/jpeg" }, - { "jpg", "image/jpeg" }, - { "mpeg", "video/mpeg" }, - { "mpg", "video/mpeg" }, - { "avi", "video/x-msvideo" }, - { "mov", "video/quicktime" }, - { "qt", "video/quicktime" }, - { "mp3", "audio/mpeg" }, - { "ogg", "audio/x-oggvorbis" }, - { "wav", "audio/x-wav" }, - { "pac", "application/x-ns-proxy-autoconfig" }, - { "sig", "application/pgp-signature" }, - { "torrent", "application/x-bittorrent" }, - { "class", "application/octet-stream" }, - { "js", "application/x-javascript" }, - { "tar", "application/x-tar" }, - { "zip", "application/zip" }, - { "dtd", "text/xml" }, - { "xml", "text/xml" }, - { "xbm", "image/x-xbitmap" }, - { "xpm", "image/x-xpixmap" }, - { "xwd", "image/x-xwindowdump" }, - { "ico", "image/x-icon" }, - { "rpm", "application/x-rpm" }, - { "gz", "application/x-gzip" }, - { "tgz", "application/x-gzip" }, +static struct mimeentry { const char* name, *type; uint32_t expireminutes; } mimetab[] = { + { "html", "text/html", 240 }, + { "htm", "text/html", 240 }, + { "css", "text/css", 240 }, + { "dvi", "application/x-dvi", 240 }, + { "ps", "application/postscript", 240 }, + { "pdf", "application/pdf", 240 }, + { "gif", "image/gif", 10000 }, + { "png", "image/png", 10000 }, + { "jpeg", "image/jpeg", 10000 }, + { "bild", "image/jpeg", 10000 }, + { "jpg", "image/jpeg", 10000 }, + { "mpeg", "video/mpeg", 240 }, + { "mpg", "video/mpeg", 240 }, + { "avi", "video/x-msvideo", 240 }, + { "mov", "video/quicktime", 240 }, + { "qt", "video/quicktime", 240 }, + { "mp3", "audio/mpeg", 240 }, + { "ogg", "audio/x-oggvorbis", 240 }, + { "wav", "audio/x-wav", 240 }, + { "pac", "application/x-ns-proxy-autoconfig", 240 }, + { "sig", "application/pgp-signature", 240 }, + { "torrent", "application/x-bittorrent", 240 }, + { "class", "application/octet-stream", 240 }, + { "js", "application/x-javascript", 240 }, + { "tar", "application/x-tar", 240 }, + { "zip", "application/zip", 240 }, + { "dtd", "text/xml", 240 }, + { "xml", "text/xml", 240 }, + { "xbm", "image/x-xbitmap", 240 }, + { "xpm", "image/x-xpixmap", 240 }, + { "xwd", "image/x-xwindowdump", 240 }, + { "ico", "image/x-icon", 240 }, + { "rpm", "application/x-rpm", 240 }, + { "gz", "application/x-gzip", 240 }, + { "tgz", "application/x-gzip", 240 }, { 0 } }; /* try to find out MIME type and content encoding. @@ -784,6 +791,7 @@ for (i=0; mimetab[i].name; ++i) if (str_equal(mimetab[i].name,url+ext)) { mimetype=(char*)mimetab[i].type; + expires = mimetab[i].expireminutes; break; } } @@ -1672,6 +1680,31 @@ buffer_puts(buffer_1,"HTTP/1.0 200 OK\r\nServer: "FNORD"\r\nContent-Type: "); buffer_puts(buffer_1,mimetype); buffer_puts(buffer_1,"\r\n"); +#ifdef EXPIRESHEADER + buffer_puts(buffer_1,"Expires: "); + { + time_t t=time(0); + t += (expires * 60); + /* struct tm* x=localtime(&t); */ + struct tm* x=gmtime(&t); + /* "Sun, 06 Nov 1994 08:49:37 GMT" */ + buffer_put(buffer_1,days+3*x->tm_wday,3); + buffer_puts(buffer_1,", "); + buffer_put2digits(buffer_1,x->tm_mday); + buffer_puts(buffer_1," "); + buffer_put(buffer_1,months+3*x->tm_mon,3); + buffer_puts(buffer_1," "); + buffer_put2digits(buffer_1,(x->tm_year+1900)/100); + buffer_put2digits(buffer_1,(x->tm_year+1900)%100); + buffer_puts(buffer_1," "); + buffer_put2digits(buffer_1,x->tm_hour); + buffer_puts(buffer_1,":"); + buffer_put2digits(buffer_1,x->tm_min); + buffer_puts(buffer_1,":"); + buffer_put2digits(buffer_1,x->tm_sec); + buffer_puts(buffer_1," GMT\r\n"); + } +#endif #ifdef KEEPALIVE switch (keepalive) { case -1: buffer_puts(buffer_1,"Connection: close\r\n"); break;