Better handling of gzip compressed files
This commit is contained in:
@@ -66,19 +66,6 @@ static const MimeMap mimeTypes[]={
|
||||
{NULL, "text/html"}, //default value
|
||||
};
|
||||
|
||||
// The static files with the following extensions from the HTML folder will be compressed and served with GZIP compression
|
||||
// Add any other file types you want compressed here (and don't forget to modify the Makefile too)
|
||||
#ifdef GZIP_COMPRESSION
|
||||
static const char * gzippedFileTypes[] = {
|
||||
"js",
|
||||
"html",
|
||||
"css",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char gzipNonSupportedMessage[] = "<html><head></head><body>Your browser does not accept gzip-compressed data.</body></html>";
|
||||
#endif
|
||||
|
||||
//Returns a static char* to a mime type for a given url to a file.
|
||||
const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) {
|
||||
int i=0;
|
||||
@@ -92,39 +79,6 @@ const char ICACHE_FLASH_ATTR *httpdGetMimetype(char *url) {
|
||||
return mimeTypes[i].mimetype;
|
||||
}
|
||||
|
||||
|
||||
#ifdef GZIP_COMPRESSION
|
||||
//Sends Content-encoding header if the requested file was GZIP compressed
|
||||
//If the client does not sent the Accept-encoding, send out a static html message.
|
||||
const char* sendGZIPEncodingIfNeeded(HttpdConnData *connData) {
|
||||
int i=0;
|
||||
char acceptEncodingBuffer[64];
|
||||
//Go find the extension
|
||||
char *ext=connData->url+(strlen(connData->url)-1);
|
||||
while (ext!=connData->url && *ext!='.') ext--;
|
||||
if (*ext=='.') ext++;
|
||||
|
||||
//ToDo: os_strcmp is case sensitive; we may want to do case-intensive matching here...
|
||||
while (gzippedFileTypes[i]!=NULL) {
|
||||
if (os_strcmp(ext, gzippedFileTypes[i])==0) {
|
||||
//when serving gzipped files check the browser's "Accept-Encoding" header
|
||||
//if the client does not advertises that he accepts GZIP send a warning message (telnet users for e.g.)
|
||||
httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64);
|
||||
if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) {
|
||||
//No Accept-Encoding: gzip header present
|
||||
return gzipNonSupportedMessage;
|
||||
} else {
|
||||
httpdHeader(connData, "Content-Encoding", "gzip");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//Looks up the connData info for a specific esp connection
|
||||
static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) {
|
||||
int i;
|
||||
|
||||
@@ -56,9 +56,6 @@ int httpdUrlDecode(char *val, int valLen, char *ret, int retLen);
|
||||
int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen);
|
||||
void ICACHE_FLASH_ATTR httpdInit(HttpdBuiltInUrl *fixedUrls, int port);
|
||||
const char *httpdGetMimetype(char *url);
|
||||
#ifdef GZIP_COMPRESSION
|
||||
const char* sendGZIPEncodingIfNeeded(HttpdConnData *connData);
|
||||
#endif
|
||||
void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code);
|
||||
void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const char *val);
|
||||
void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn);
|
||||
|
||||
+37
-10
@@ -14,6 +14,11 @@ Connector to let httpd use the espfs filesystem to serve the files in it.
|
||||
#include <esp8266.h>
|
||||
#include "httpdespfs.h"
|
||||
#include "espfs.h"
|
||||
#include "espfsformat.h"
|
||||
|
||||
// The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression.
|
||||
// If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.)
|
||||
static const char *gzipNonSupportedMessage = "HTTP/1.0 501 Not implemented\r\nServer: esp8266-httpd/"HTTPDVER"\r\nContent-Type: text/plain\r\nContent-Length: 52\r\n\r\nYour browser does not accept gzip-compressed data.\r\n";
|
||||
|
||||
|
||||
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
|
||||
@@ -23,9 +28,8 @@ int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
|
||||
EspFsFile *file=connData->cgiData;
|
||||
int len;
|
||||
char buff[1024];
|
||||
#ifdef GZIP_COMPRESSION
|
||||
const char *gzipSendResult = NULL;
|
||||
#endif
|
||||
char acceptEncodingBuffer[64];
|
||||
int isGzip;
|
||||
|
||||
if (connData->conn==NULL) {
|
||||
//Connection aborted. Clean up.
|
||||
@@ -39,17 +43,32 @@ int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
|
||||
if (file==NULL) {
|
||||
return HTTPD_CGI_NOTFOUND;
|
||||
}
|
||||
|
||||
// The gzip checking code is intentionally without #ifdefs because checking
|
||||
// for FLAG_GZIP (which indicates gzip compressed file) is very easy, doesn't
|
||||
// mean additional overhead and is actually safer to be on at all times.
|
||||
// If there are no gzipped files in the image, the code bellow will not cause any harm.
|
||||
|
||||
// Check if requested file was GZIP compressed
|
||||
isGzip = espFsFlags(file) & FLAG_GZIP;
|
||||
if (isGzip) {
|
||||
// Check the browser's "Accept-Encoding" header. If the client does not
|
||||
// advertise that he accepts GZIP send a warning message (telnet users for e.g.)
|
||||
httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64);
|
||||
if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) {
|
||||
//No Accept-Encoding: gzip header present
|
||||
httpdSend(connData, gzipNonSupportedMessage, -1);
|
||||
espFsClose(file);
|
||||
return HTTPD_CGI_DONE;
|
||||
}
|
||||
}
|
||||
|
||||
connData->cgiData=file;
|
||||
httpdStartResponse(connData, 200);
|
||||
httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
|
||||
#ifdef GZIP_COMPRESSION
|
||||
gzipSendResult = sendGZIPEncodingIfNeeded(connData);
|
||||
if (gzipSendResult != NULL) {
|
||||
httpdEndHeaders(connData);
|
||||
httpdSend(connData, gzipSendResult, os_strlen(gzipSendResult));
|
||||
return HTTPD_CGI_DONE;
|
||||
if (isGzip) {
|
||||
httpdHeader(connData, "Content-Encoding", "gzip");
|
||||
}
|
||||
#endif
|
||||
httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate");
|
||||
httpdEndHeaders(connData);
|
||||
return HTTPD_CGI_MORE;
|
||||
@@ -101,6 +120,14 @@ int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) {
|
||||
tpd->tplArg=NULL;
|
||||
tpd->tokenPos=-1;
|
||||
if (tpd->file==NULL) {
|
||||
espFsClose(tpd->file);
|
||||
os_free(tpd);
|
||||
return HTTPD_CGI_NOTFOUND;
|
||||
}
|
||||
if (espFsFlags(tpd->file) & FLAG_GZIP) {
|
||||
os_printf("cgiEspFsTemplate: Trying to use gzip-compressed file %s as template!\n", connData->url);
|
||||
espFsClose(tpd->file);
|
||||
os_free(tpd);
|
||||
return HTTPD_CGI_NOTFOUND;
|
||||
}
|
||||
connData->cgiData=tpd;
|
||||
|
||||
Reference in New Issue
Block a user