espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
13.52k stars 7.39k forks source link

HTTP/1.0 issue with httpUpdate on https reverse proxy #7863

Open ThingEngineer opened 1 year ago

ThingEngineer commented 1 year ago

Board

ESP23-CAM

Device Description

Plain ESP23-CAM on an ESP32-CAM-MB connected to Mac with a 3.3' USB C to Micro USB cable. Two Dallas DS18B20 temperature sensors are connected via DuPont cables plugged into extra headers soldered onto the ESP32-CAM-MB.

Hardware Configuration

The ONE_WIRE_BUS for Dallas comms is on GPIO 2.

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

macOS 10.15.7

Flash frequency

40MHz

PSRAM enabled

yes

Upload speed

921600

Description

Calling httpUpdate.update() produces the debug message/error below. The version check and update DO proceed despite the error. If I comment http.useHTTP10(true); on line 189 of HTTPUpdate.cpp this error is no longer thrown.

I worry that this may be breaking the server verification similar to setInsecure(). All other secure https GET/POST requests and responses work without error.

My firmware update server is reverse proxied via Cloudflare with the encryption mode set to Full (strict) which encrypts end-to-end, but requires a trusted CA or Cloudflare Origin CA certificate on the server. I used the generated Cloudflare Origin Certificate on the server. On Cloudflare I have the minimum TLS version set to 1.2, HSTS enabled, Opportunistic Encryption enabled, TLS 1.3 enabled, and Automatic HTTPS Rewrites enabled.

It seems the https proxy is not HTTP/1.0 compliant, but requires HTTP/1.1.

It would be nice to have a real fix for this but an arg to disable forcing HTTP/1.0 seems that it would satisfy the issue.

Sketch

#include <Arduino.h>                    // Compatibility library for Arduino functions
#include <WiFi.h>                       // WiFi library for network connectivity
#include <WiFiClientSecure.h>           // Secure WiFi communication library
#include <HTTPClient.h>                 // HTTP requests and responses library
#include <HTTPUpdate.h>                 // OTA over http library

#include "env.h"                        // Secret values

WiFiClientSecure client;

void setup() {
  client.setCACert(rootCACertificate);
}

/**
 * Check for a new firmware version and flash OTA if one is available
 */
void checkForUpdate() {
  DEBUG_MSG("Checking for firmware update\n");

  client.setTimeout(12);
  httpUpdate.setLedPin(BUILT_IN_LED, HIGH);

  t_httpUpdate_return ret = httpUpdate.update(client, serverName, serverPort, serverFirmwarePath, (String)currentVersion);

  switch (ret) {
    case HTTP_UPDATE_FAILED:
      DEBUG_MSG("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());
      break;

    case HTTP_UPDATE_NO_UPDATES:
      DEBUG_MSG("No Update\n");
      break;

    case HTTP_UPDATE_OK:
      DEBUG_MSG("Update Ok\n");
      break;
  }

}

Debug Message

Checking for firmware update
[  7937][E][ssl_client.cpp:37] _handle_error(): [data_to_read():366]: (-76) UNKNOWN ERROR CODE (004C)
No Update

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

SuGlider commented 1 year ago

http.useHTTP10() has to do with HTTP encoding (HTTP Header Accept-Encoding) and not with security. It is the content encoding (usually a compression algorithm) that the client can understand. By default it is false and therefore, it uses Accept-Encoding: identity, which means without modification or compression.

I worry that this may be breaking the server verification similar to setInsecure(). I worry that this may be breaking the server verification similar to setInsecure().

If commenting it out makes the application work fine, you can go with it.