Thanks for posting your solution Sean. I have done it slightly differently but your guide helped me a lot. As I wanted a mixture of compressed and uncompressed I created two new file extension .js_gz and .css_gz then after gzipping I just replace the last '.' with an '_' so my code is as follows:
typedef enum httpsrv_content_type
{
HTTPSRV_CONTENT_TYPE_OCTETSTREAM = 1,
HTTPSRV_CONTENT_TYPE_PLAIN,
HTTPSRV_CONTENT_TYPE_HTML,
HTTPSRV_CONTENT_TYPE_CSS,
HTTPSRV_CONTENT_TYPE_GIF,
HTTPSRV_CONTENT_TYPE_JPG,
HTTPSRV_CONTENT_TYPE_PNG,
HTTPSRV_CONTENT_TYPE_SVG,
HTTPSRV_CONTENT_TYPE_JS,
HTTPSRV_CONTENT_TYPE_ZIP,
HTTPSRV_CONTENT_TYPE_XML,
HTTPSRV_CONTENT_TYPE_PDF,
HTTPSRV_CONTENT_TYPE_CSS_GZ, //Adrian Rockall
HTTPSRV_CONTENT_TYPE_JS_GZ, //Adrian Rockall
} HTTPSRV_CONTENT_TYPE;
static const HTTPSRV_TABLE_ROW content_type[] = {
{ HTTPSRV_CONTENT_TYPE_PLAIN, "text/plain" },
{ HTTPSRV_CONTENT_TYPE_HTML, "text/html" },
{ HTTPSRV_CONTENT_TYPE_CSS, "text/css" },
{ HTTPSRV_CONTENT_TYPE_GIF, "image/gif" },
{ HTTPSRV_CONTENT_TYPE_JPG, "image/jpeg" },
{ HTTPSRV_CONTENT_TYPE_PNG, "image/png" },
{ HTTPSRV_CONTENT_TYPE_SVG, "image/svg+xml"},
{ HTTPSRV_CONTENT_TYPE_JS, "application/javascript" },
{ HTTPSRV_CONTENT_TYPE_XML, "application/xml" },
{ HTTPSRV_CONTENT_TYPE_ZIP, "application/zip" },
{ HTTPSRV_CONTENT_TYPE_PDF, "application/pdf" },
{ HTTPSRV_CONTENT_TYPE_OCTETSTREAM, "application/octet-stream" },
{ HTTPSRV_CONTENT_TYPE_CSS_GZ, "text/css" }, //New css_gz file extension
{ HTTPSRV_CONTENT_TYPE_JS_GZ, "application/javascript" }, //New js_gz file extension
{ 0, 0}
};
static const HTTPSRV_CONTENT_TABLE_ROW content_tbl[] = {
/* Size, extension, MIME type, Cache? */
{sizeof("js")-1 , "js", HTTPSRV_CONTENT_TYPE_JS, TRUE},
{sizeof("css")-1, "css", HTTPSRV_CONTENT_TYPE_CSS, TRUE},
{sizeof("gif")-1, "gif", HTTPSRV_CONTENT_TYPE_GIF, TRUE},
{sizeof("htm")-1, "htm", HTTPSRV_CONTENT_TYPE_HTML, TRUE},
{sizeof("jpg")-1, "jpg", HTTPSRV_CONTENT_TYPE_JPG, TRUE},
{sizeof("pdf")-1, "pdf", HTTPSRV_CONTENT_TYPE_PDF, FALSE},
{sizeof("png")-1, "png", HTTPSRV_CONTENT_TYPE_PNG, TRUE},
{sizeof("svg")-1, "svg", HTTPSRV_CONTENT_TYPE_SVG, TRUE},
{sizeof("txt")-1, "txt", HTTPSRV_CONTENT_TYPE_PLAIN, FALSE},
{sizeof("xml")-1, "xml", HTTPSRV_CONTENT_TYPE_XML, FALSE},
{sizeof("zip")-1, "zip", HTTPSRV_CONTENT_TYPE_ZIP, FALSE},
{sizeof("html")-1, "html", HTTPSRV_CONTENT_TYPE_HTML, TRUE},
{sizeof("shtm")-1, "shtm", HTTPSRV_CONTENT_TYPE_HTML, FALSE},
{sizeof("shtml")-1, "shtml", HTTPSRV_CONTENT_TYPE_HTML, FALSE},
{sizeof("js_gz")-1 ,"js_gz", HTTPSRV_CONTENT_TYPE_JS_GZ, TRUE}, //New js_gz file extension
{sizeof("css_gz")-1,"css_gz",HTTPSRV_CONTENT_TYPE_CSS_GZ, TRUE}, //New css_gz file extension
/* Following row MUST have length set to zero so we have proper array termination */
{0, "", HTTPSRV_CONTENT_TYPE_OCTETSTREAM, FALSE}
};
if (has_entity)
{
httpsrv_print(session, "Content-Type: %s\r\n", httpsrv_get_table_str((HTTPSRV_TABLE_ROW*)content_type, session->response.content_type));
//If we are serving a GZIP file then add the required header so the browser knows to decompress it
if(session->response.content_type == HTTPSRV_CONTENT_TYPE_JS_GZ ||
session->response.content_type == HTTPSRV_CONTENT_TYPE_CSS_GZ)
{
httpsrv_print(session, "Content-Encoding: gzip\r\n");
}
}
I have one large JavaScript library that gzips from 400k down to 80k so serving the gzip version is much faster. My slowest page, that has two large .js files and two large .css files, was taking about 15 seconds to serve and now only takes about 3 seconds with the gzip in place so definitely worth the effort.
Adrian.