From dd81336b79ddf15925876b983af13816d9d5807e Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Fri, 3 Jun 2016 16:11:44 +0800 Subject: [PATCH] ESP8266HTTPClient: fix duplicate Content-Length headers (#1902) --- .../src/ESP8266HTTPClient.cpp | 14 +++- .../ESP8266HTTPClient/src/ESP8266HTTPClient.h | 2 +- .../test_config/test_config.h.template | 1 + .../test_http_client/test_http_client.ino | 66 ++++--------------- .../test_http_client/test_http_client.py | 7 +- 5 files changed, 31 insertions(+), 59 deletions(-) diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp index d426105852..7f8671fbf0 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.cpp @@ -706,19 +706,27 @@ String HTTPClient::errorToString(int error) * @param value * @param first */ -void HTTPClient::addHeader(const String& name, const String& value, bool first) +void HTTPClient::addHeader(const String& name, const String& value, bool first, bool replace) { - // not allow set of Header handled by code if(!name.equalsIgnoreCase(F("Connection")) && !name.equalsIgnoreCase(F("User-Agent")) && !name.equalsIgnoreCase(F("Host")) && !(name.equalsIgnoreCase(F("Authorization")) && _base64Authorization.length())){ + String headerLine = name; headerLine += ": "; + + if (replace) { + int headerStart = _headers.indexOf(headerLine); + if (headerStart != -1) { + int headerEnd = _headers.indexOf('\n', headerStart); + _headers = _headers.substring(0, headerStart) + _headers.substring(headerEnd + 1); + } + } + headerLine += value; headerLine += "\r\n"; - if(first) { _headers = headerLine + _headers; } else { diff --git a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h index 1619a3b58a..53a5d98844 100644 --- a/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h +++ b/libraries/ESP8266HTTPClient/src/ESP8266HTTPClient.h @@ -160,7 +160,7 @@ class HTTPClient int sendRequest(const char * type, uint8_t * payload = NULL, size_t size = 0); int sendRequest(const char * type, Stream * stream, size_t size = 0); - void addHeader(const String& name, const String& value, bool first = false); + void addHeader(const String& name, const String& value, bool first = false, bool replace = true); /// Response handling void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); diff --git a/tests/device/libraries/test_config/test_config.h.template b/tests/device/libraries/test_config/test_config.h.template index f318f91f01..740884dba9 100644 --- a/tests/device/libraries/test_config/test_config.h.template +++ b/tests/device/libraries/test_config/test_config.h.template @@ -6,3 +6,4 @@ #define AP_SSID "test_wifi_ap" #define AP_PASS "test_wifi_ap_pass" +#define SERVER_IP "192.168.10.1" diff --git a/tests/device/test_http_client/test_http_client.ino b/tests/device/test_http_client/test_http_client.ino index 85a30fc192..32e5613715 100644 --- a/tests/device/test_http_client/test_http_client.ino +++ b/tests/device/test_http_client/test_http_client.ino @@ -21,7 +21,7 @@ void setup() const char* fp = "40 A3 6C E3 8A DF A2 D4 13 B0 32 5C 87 44 54 28 0B CE C5 A4"; -TEST_CASE("HTTP GET request", "[HTTPClient]") +TEST_CASE("HTTP GET & POST requests", "[HTTPClient]") { { // small request @@ -47,7 +47,20 @@ TEST_CASE("HTTP GET request", "[HTTPClient]") } } } + { + // can do two POST requests with one HTTPClient object (#1902) + HTTPClient http; + http.begin(SERVER_IP, 8088, "/"); + http.addHeader("Content-Type", "text/plain"); + auto httpCode = http.POST("foo"); + Serial.println(httpCode); + REQUIRE(httpCode == HTTP_CODE_OK); + http.end(); + httpCode = http.POST("bar"); + REQUIRE(httpCode == HTTP_CODE_OK); + http.end(); + } } @@ -79,57 +92,6 @@ TEST_CASE("HTTPS GET request", "[HTTPClient]") } } -// TEST_CASE("HTTP GET request", "[HTTPClient]") -// { -// const int repeatCount = 10; - -// String url = createBin(false); -// int heapBefore = ESP.getFreeHeap(); -// for (int i = 0; i < repeatCount; ++i) { -// HTTPClient http; -// http.begin(url); -// auto httpCode = http.GET(); -// REQUIRE(httpCode == HTTP_CODE_OK); -// String payload = http.getString(); -// payload.replace("\n", "\\n"); -// String quotedPayload; -// quotedPayload.reserve(payload.length() + 3); -// quotedPayload += "\""; -// quotedPayload += payload; -// quotedPayload += "\""; -// Serial.println("----payload:"); -// Serial.println(quotedPayload); -// Serial.println("----"); -// Serial.println("----test_payload:"); -// Serial.println(test_payload); -// Serial.println("----"); -// CHECK(quotedPayload == test_payload); -// http.end(); -// delay(100); -// } -// int heapAfter = ESP.getFreeHeap(); -// CHECK(heapBefore - heapAfter <= 8); -// } - -// TEST_CASE("HTTPS GET request", "[HTTPClient]") -// { -// const int repeatCount = 10; - -// String url = createBin(true); -// int heapBefore = ESP.getFreeHeap(); -// for (int i = 0; i < repeatCount; ++i) { -// HTTPClient http; -// http.begin(url, mockbin_fingerprint); -// auto httpCode = http.GET(); -// REQUIRE(httpCode == HTTP_CODE_OK); -// String payload = http.getString(); -// CHECK(payload == test_payload); -// http.end(); -// delay(100); -// } -// int heapAfter = ESP.getFreeHeap(); -// CHECK(heapBefore - heapAfter <= 8); -// } void loop() { diff --git a/tests/device/test_http_client/test_http_client.py b/tests/device/test_http_client/test_http_client.py index 32c70d2d26..ac9f065bf2 100644 --- a/tests/device/test_http_client/test_http_client.py +++ b/tests/device/test_http_client/test_http_client.py @@ -5,7 +5,7 @@ import os import ssl -@setup('HTTP GET request') +@setup('HTTP GET & POST requests') def setup_http_get(e): app = Flask(__name__) def shutdown_server(): @@ -17,8 +17,9 @@ def shutdown_server(): def shutdown(): shutdown_server() return 'Server shutting down...' - @app.route("/") + @app.route("/", methods = ['GET', 'POST']) def root(): + print('Got data: ' + request.data); return 'hello!!!' @app.route("/data") def get_data(): @@ -29,7 +30,7 @@ def flaskThread(): th = Thread(target=flaskThread) th.start() -@teardown('HTTP GET request') +@teardown('HTTP GET & POST requests') def teardown_http_get(e): response = urllib2.urlopen('http://localhost:8088/shutdown') html = response.read()