- Notifications
You must be signed in to change notification settings - Fork21
Sending GZIP HTML ~ 120kb+ (suggested enhancement) #3
Description
Before I start out, would just like to say thanks for this library it has helped me very quickly port a lot of work from the ESP to the STM32 platform where I can keep both systems fairly in sync!
I also do not know if this is a generic enhancment for both this repo and the non STM32 repo, that's up to you.
I have a HTML build process using GULP which Inlines, uglifies, minifies all of my HTML, CSS and JS . The output file is a single header file that puts the entire thing into PROGMEM.
#define index_html_gz_len 129855const char PROGMEM index_html_gz[] = { 0x1f,0x8b,0x08,0x00,0x00,0x00,0x00,0x00,....
In both the ESP32 / 8266 the following is used to send this as the index:
server.on(String(F("/index.html")).c_str(), HTTP_GET, [](AsyncWebServerRequest *request){ if(authenticate(request)){ return request->requestAuthentication(); } //webPage setup char lastModified[50]; // Variable to hold the last modification datetime of website sprintf_P(lastModified, PSTR("%s %s GMT"), __DATE__, __TIME__); // Populate the last modification date based on build datetime if (request->header(F("If-Modified-Since")).equals(lastModified)) { request->send(304); } else { // Dump the byte array in PROGMEM with a 200 HTTP code (OK) AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/html"), index_html_gz, index_html_gz_len); // Tell the browswer the contemnt is Gzipped response->addHeader(F("Content-Encoding"), F("gzip")); // And set the last-modified datetime so we can check if we need to send it again next time or not response->addHeader(F("Last-Modified"), lastModified); request->send(response); } WiFi.scanNetworks(true); //they might request wifi networks at some point });
Unforunately, this did not work with this library using the send_P command as I expected, the headers were send but no content. I have finally come up with a solution, I doubt that it is optimal, but for me it is working.
void EthernetWebServer::sendContent_P(PGM_P content, size_t size) { const char * footer = "\r\n"; if (_chunked) { char * chunkSize = (char *) malloc(11); if (chunkSize) { sprintf(chunkSize, "%x%s", size, footer); _currentClient.write(chunkSize, strlen(chunkSize)); free(chunkSize); } } uint16_t bufSize = 4096; uint8_t buffer[bufSize]; uint16_t count = size / bufSize; uint16_t remainder = size % bufSize; uint16_t i = 0; for (i = 0; i < count; i++) { /* code */ memcpy_P(buffer, &content[i*bufSize], bufSize); _currentClient.write(buffer, bufSize); } memcpy_P(buffer, &content[i*bufSize], remainder); _currentClient.write(buffer, remainder); if (_chunked) { _currentClient.write(footer, 2); }}
If there is a better way of doing this I would love to know, but for now I can carry on with my development, happy to offer a PR for something to work from if needed?
Now I can have my fully bootstrapped web interface that I use with my ESP devices. 👍