Skip to content

ESP8266WebServerSecure.serveStatic() and BearSSL failed with "ERR_CONTENT_LENGTH_MISMATCH" #4908

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
6 tasks done
antiFetzen opened this issue Jul 9, 2018 · 1 comment · Fixed by #5982
Closed
6 tasks done
Assignees

Comments

@antiFetzen
Copy link

Basic Infos

  • This issue complies with the issue POLICY doc.
  • I have read the documentation at readthedocs and the issue is not addressed there.
  • I have tested that the issue is present in current master branch (aka latest git).
  • I have searched the issue tracker for a similar issue.
  • If there is a stack dump, I have decoded it.
  • I have filled out all fields below.

Platform

  • Hardware: ESP8266
  • Core Version: e486887
  • Development Env: Platformio
  • Operating System: Windows 10

Settings in IDE

  • Module: Wemos D1 mini
  • Flash Mode: [qio|dio|other]
  • Flash Size: 4MB
  • lwip Variant: v1.4
  • Reset Method: ck
  • Flash Frequency: 40Mhz
  • CPU Frequency: 160Mhz
  • Upload Using: SERIAL
  • Upload Speed: 115200

Problem Description

When using .serveStatic () I always get the error message in the browser "ERR_CONTENT_LENGTH_MISMATCH"
If I use the server.on () function, the file will be sent correctly.

server.on("/", [](){
   File file = SPIFFS.open("/index.html", "r");
   server.streamFile(file, "text/html");
   file.close();
});

I tried to find the cause
ESP8266WebServer.cpp

void ESP8266WebServer::_handleRequest() {
  ...
  handled = _currentHandler->handle(*this, _currentMethod, _currentUri);
  ...
}

RequestHandlersImpl.h

bool handle(ESP8266WebServer& server, HTTPMethod requestMethod, String requestUri) override {
  ...
  if (_cache_header.length() != 0)
    server.sendHeader("Cache-Control", _cache_header);

  server.streamFile(f, contentType);  //<-- this function will be called
  return true;
}

it is called
ESP8266WebServer.h

  template<typename T> 
  size_t streamFile(T &file, const String& contentType) {
    _streamFileCore(file.size(), file.name(), contentType);
    return _currentClient.write(file);
  }

instead of
ESP8266WebServerSecure.h

  template<typename T>
  size_t streamFile(T &file, const String& contentType) {
    _streamFileCore(file.size(), file.name(), contentType);
    return _currentClientSecure.write(file);
  }

The pointer * this should be refer to BearSSL::ESP8266WebServerSecure server (443)?
I think that's it but I do not know how to fix it.

MCVE Sketch

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServerSecure.h>
#include <ESP8266mDNS.h>

#include <ESP8266httpUpdate.h>
#include <FS.h>

const char* ssid = "wifi";
const char* password = "1234";

BearSSL::ESP8266WebServerSecure server(443);
static const char serverCert[] PROGMEM = R"EOF(...)EOF";
static const char serverKey[] PROGMEM =  R"EOF(...)EOF";

void setup() { 
  SPIFFS.begin();
  WiFi.begin(ssid, password);

  server.serveStatic("/", SPIFFS, "/index.html");

  server.begin();
}

void loop() {
  server.handleClient();
}

Debug Messages

New secure client
method: GET url: / search:
headerName: Host
headerValue: littledroid1
headerName: Connection
headerValue: keep-alive
headerName: Cache-Control
headerValue: max-age=0
headerName: Upgrade-Insecure-Requests
headerValue: 1
headerName: User-Agent
headerValue: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
headerName: Accept
headerValue: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
headerName: Accept-Encoding
headerValue: gzip, deflate, br
headerName: Accept-Language
headerValue: de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7
args:
Request: /
 Arguments:

StaticRequestHandler::handle: request=/ _uri=/
StaticRequestHandler::handle: path=/index.html, isFile=1
@earlephilhower
Copy link
Collaborator

Good debugging!

Ah, the joys of templates and non-virtual functions combined with Arduino's love of passing copies of objects instead of references. At first glance your description looks good and there's probably not a simple way to make it work (can't do virtual templates in C++), but we can figure something out.

@earlephilhower earlephilhower self-assigned this Jul 9, 2018
earlephilhower added a commit to earlephilhower/Arduino that referenced this issue Apr 12, 2019
Supercedes esp8266#4912

Refactor the three versions of ESP8266WebServer and *WebServerSecure to a
single templated class. Use "using" to enable old, non-templated names to b
used (so no user changes required to compile or run).

Fixes esp8266#4908 and clean up the code base a lot.

Basic tests run (the ones in the example code).

No code changes are required in userland except for setting the SSL
certificates which now use a cleaner "getServer()" accessor and lets the
app use the native BearSSL calls on the WiFiClientSecure object.

@devyte should be proud, it removes virtuals and even has template specialization...
d-a-v pushed a commit that referenced this issue Jul 4, 2019
* Convert ESP8266WebServer* into templatized model

Supercedes #4912

Refactor the three versions of ESP8266WebServer and *WebServerSecure to a
single templated class. Use "using" to enable old, non-templated names to b
used (so no user changes required to compile or run).

Fixes #4908 and clean up the code base a lot.

Basic tests run (the ones in the example code).

No code changes are required in userland except for setting the SSL
certificates which now use a cleaner "getServer()" accessor and lets the
app use the native BearSSL calls on the WiFiClientSecure object.

@devyte should be proud, it removes virtuals and even has template specialization...

* Fix HTTPUpdate templates and examples

* Fix HTTPUpdateServer library build

Need to remove dot-a linkage since there are no .cpp files in the
directory anymore due to templates.

* Provide backward-compat names for updt template

Allow existing code to use the same well known names for
HTTPUpdateSecure.

* Remove ClientType from all templates, auto-infer

Remove the ClientType template parameter from all objects.  Simplifies
the code and makes it more foolproof.

Add a "using" in each server to define the type of connection returned
by all servers, which is then used in the above templates automatically.

* Can safely include FS.h now that SD/SPIFFS unified

* Move the templates/objects to their own namespaces

* Fix merge issues with untemplated methods

* Address review comments

* Fix mock test, remove warnings inside test dir

Make the simple mock test CI job pass and clean up
any spurious warnings in the test directory.

There still are warnings in the libraries and core, but they
should be addressed in a separate PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants