mirror of
https://github.com/esp8266/Arduino.git
synced 2025-06-13 13:01:55 +03:00
Add WiFiClient parameter to HTTPClient (#4980)
Make HTTPClient take a WiFiClient parameter, allowing you to pass in a simple HTTP WiFiClient or a BearSSL or axTLS WiFiClientSecure with any desired verification options. Deprecate the older, TLSTraits methods. Add basic HttpsClient example. Add optional LED feedback to the Update class
This commit is contained in:
committed by
Earle F. Philhower, III
parent
9bc8ea1b58
commit
13f374666d
@ -12,22 +12,22 @@
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
#include <WiFiClient.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
void setup() {
|
||||
|
||||
USE_SERIAL.begin(115200);
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@ -40,41 +40,43 @@ void loop() {
|
||||
// wait for WiFi connection
|
||||
if ((WiFiMulti.run() == WL_CONNECTED)) {
|
||||
|
||||
WiFiClient client;
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
USE_SERIAL.print("[HTTP] begin...\n");
|
||||
Serial.print("[HTTP] begin...\n");
|
||||
// configure traged server and url
|
||||
|
||||
|
||||
http.begin("http://user:password@192.168.1.12/test.html");
|
||||
http.begin(client, "http://guest:guest@jigsaw.w3.org/HTTP/Basic/");
|
||||
|
||||
/*
|
||||
// or
|
||||
http.begin("http://192.168.1.12/test.html");
|
||||
http.setAuthorization("user", "password");
|
||||
http.begin(client, "http://jigsaw.w3.org/HTTP/Basic/");
|
||||
http.setAuthorization("guest", "guest");
|
||||
|
||||
// or
|
||||
http.begin("http://192.168.1.12/test.html");
|
||||
http.setAuthorization("dXNlcjpwYXN3b3Jk");
|
||||
http.begin(client, "http://jigsaw.w3.org/HTTP/Basic/");
|
||||
http.setAuthorization("Z3Vlc3Q6Z3Vlc3Q=");
|
||||
*/
|
||||
|
||||
|
||||
USE_SERIAL.print("[HTTP] GET...\n");
|
||||
Serial.print("[HTTP] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = http.GET();
|
||||
|
||||
// httpCode will be negative on error
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
String payload = http.getString();
|
||||
USE_SERIAL.println(payload);
|
||||
Serial.println(payload);
|
||||
}
|
||||
} else {
|
||||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
@ -82,4 +84,3 @@ void loop() {
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
|
@ -12,22 +12,22 @@
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
#include <WiFiClient.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
void setup() {
|
||||
|
||||
USE_SERIAL.begin(115200);
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@ -40,34 +40,37 @@ void loop() {
|
||||
// wait for WiFi connection
|
||||
if ((WiFiMulti.run() == WL_CONNECTED)) {
|
||||
|
||||
WiFiClient client;
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
USE_SERIAL.print("[HTTP] begin...\n");
|
||||
// configure traged server and url
|
||||
//http.begin("https://192.168.1.12/test.html", "7a 9c f4 db 40 d3 62 5a 6e 21 bc 5c cc 66 c8 3e a1 45 59 38"); //HTTPS
|
||||
http.begin("http://192.168.1.12/test.html"); //HTTP
|
||||
Serial.print("[HTTP] begin...\n");
|
||||
if (http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html")) { // HTTP
|
||||
|
||||
USE_SERIAL.print("[HTTP] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = http.GET();
|
||||
|
||||
// httpCode will be negative on error
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
Serial.print("[HTTP] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = http.GET();
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
String payload = http.getString();
|
||||
USE_SERIAL.println(payload);
|
||||
// httpCode will be negative on error
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||
String payload = http.getString();
|
||||
Serial.println(payload);
|
||||
}
|
||||
} else {
|
||||
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
} else {
|
||||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
http.end();
|
||||
} else {
|
||||
Serial.printf("[HTTP} Unable to connect\n");
|
||||
}
|
||||
}
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,78 @@
|
||||
/**
|
||||
BasicHTTPSClient.ino
|
||||
|
||||
Created on: 20.08.2018
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#include <WiFiClientSecureBearSSL.h>
|
||||
// Fingerprint for demo URL, expires on June 2, 2019, needs to be updated well before this date
|
||||
const uint8_t fingerprint[20] = {0x5A, 0xCF, 0xFE, 0xF0, 0xF1, 0xA6, 0xF4, 0x5F, 0xD2, 0x11, 0x11, 0xC6, 0x1D, 0x2F, 0x0E, 0xBC, 0x39, 0x8D, 0x50, 0xE0};
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFiMulti.addAP("SSID", "PASSWORD");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait for WiFi connection
|
||||
if ((WiFiMulti.run() == WL_CONNECTED)) {
|
||||
|
||||
BearSSL::WiFiClientSecure client;
|
||||
client.setFingerprint(fingerprint);
|
||||
|
||||
HTTPClient https;
|
||||
|
||||
Serial.print("[HTTPS] begin...\n");
|
||||
if (https.begin(client, "https://jigsaw.w3.org/HTTP/connection.html")) { // HTTPS
|
||||
|
||||
|
||||
Serial.print("[HTTPS] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = https.GET();
|
||||
|
||||
// httpCode will be negative on error
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
|
||||
String payload = https.getString();
|
||||
Serial.println(payload);
|
||||
}
|
||||
} else {
|
||||
Serial.printf("[HTTPS] GET... failed, error: %s\n", https.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
https.end();
|
||||
} else {
|
||||
Serial.printf("[HTTPS] Unable to connect\n");
|
||||
}
|
||||
}
|
||||
|
||||
delay(10000);
|
||||
}
|
@ -11,8 +11,8 @@
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
const char* ssid = "........";
|
||||
const char* ssidPassword = "........";
|
||||
const char* ssid = "SSID";
|
||||
const char* ssidPassword = "PASSWORD";
|
||||
|
||||
const char *username = "admin";
|
||||
const char *password = "admin";
|
||||
@ -76,7 +76,7 @@ String getDigestAuth(String& authReq, const String& username, const String& pass
|
||||
}
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
Serial.begin(115200);
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, ssidPassword);
|
||||
@ -95,10 +95,12 @@ void setup() {
|
||||
void loop() {
|
||||
HTTPClient http;
|
||||
|
||||
WiFiClient client;
|
||||
|
||||
Serial.print("[HTTP] begin...\n");
|
||||
|
||||
// configure traged server and url
|
||||
http.begin(String(server) + String(uri));
|
||||
http.begin(client, String(server) + String(uri));
|
||||
|
||||
|
||||
const char *keys[] = {"WWW-Authenticate"};
|
||||
@ -115,7 +117,7 @@ void loop() {
|
||||
String authorization = getDigestAuth(authReq, String(username), String(password), String(uri), 1);
|
||||
|
||||
http.end();
|
||||
http.begin(String(server) + String(uri));
|
||||
http.begin(client, String(server) + String(uri));
|
||||
|
||||
http.addHeader("Authorization", authorization);
|
||||
|
||||
|
@ -13,24 +13,22 @@
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
void setup() {
|
||||
|
||||
USE_SERIAL.begin(115200);
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@ -45,19 +43,21 @@ void loop() {
|
||||
// wait for WiFi connection
|
||||
if ((WiFiMulti.run() == WL_CONNECTED)) {
|
||||
|
||||
http.begin("http://192.168.1.12/test.html");
|
||||
//http.begin("192.168.1.12", 80, "/test.html");
|
||||
WiFiClient client;
|
||||
|
||||
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
|
||||
//http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
|
||||
|
||||
int httpCode = http.GET();
|
||||
if (httpCode > 0) {
|
||||
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
http.writeToStream(&USE_SERIAL);
|
||||
http.writeToStream(&Serial);
|
||||
}
|
||||
} else {
|
||||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
@ -65,6 +65,3 @@ void loop() {
|
||||
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -12,22 +12,20 @@
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
#define USE_SERIAL Serial
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
void setup() {
|
||||
|
||||
USE_SERIAL.begin(115200);
|
||||
// USE_SERIAL.setDebugOutput(true);
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
USE_SERIAL.printf("[SETUP] WAIT %d...\n", t);
|
||||
USE_SERIAL.flush();
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
@ -42,18 +40,20 @@ void loop() {
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
USE_SERIAL.print("[HTTP] begin...\n");
|
||||
WiFiClient client;
|
||||
|
||||
Serial.print("[HTTP] begin...\n");
|
||||
|
||||
// configure server and url
|
||||
http.begin("http://192.168.1.12/test.html");
|
||||
//http.begin("192.168.1.12", 80, "/test.html");
|
||||
http.begin(client, "http://jigsaw.w3.org/HTTP/connection.html");
|
||||
//http.begin(client, "jigsaw.w3.org", 80, "/HTTP/connection.html");
|
||||
|
||||
USE_SERIAL.print("[HTTP] GET...\n");
|
||||
Serial.print("[HTTP] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = http.GET();
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
USE_SERIAL.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
Serial.printf("[HTTP] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
@ -65,7 +65,7 @@ void loop() {
|
||||
uint8_t buff[128] = { 0 };
|
||||
|
||||
// get tcp stream
|
||||
WiFiClient * stream = http.getStreamPtr();
|
||||
WiFiClient * stream = &client;
|
||||
|
||||
// read all data from server
|
||||
while (http.connected() && (len > 0 || len == -1)) {
|
||||
@ -77,7 +77,7 @@ void loop() {
|
||||
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
|
||||
|
||||
// write it to Serial
|
||||
USE_SERIAL.write(buff, c);
|
||||
Serial.write(buff, c);
|
||||
|
||||
if (len > 0) {
|
||||
len -= c;
|
||||
@ -86,12 +86,12 @@ void loop() {
|
||||
delay(1);
|
||||
}
|
||||
|
||||
USE_SERIAL.println();
|
||||
USE_SERIAL.print("[HTTP] connection closed or file end.\n");
|
||||
Serial.println();
|
||||
Serial.print("[HTTP] connection closed or file end.\n");
|
||||
|
||||
}
|
||||
} else {
|
||||
USE_SERIAL.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
@ -99,4 +99,3 @@ void loop() {
|
||||
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,115 @@
|
||||
/**
|
||||
StreamHTTPClient.ino
|
||||
|
||||
Created on: 24.05.2015
|
||||
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266WiFiMulti.h>
|
||||
|
||||
#include <ESP8266HTTPClient.h>
|
||||
|
||||
ESP8266WiFiMulti WiFiMulti;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
// Serial.setDebugOutput(true);
|
||||
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
Serial.println();
|
||||
|
||||
for (uint8_t t = 4; t > 0; t--) {
|
||||
Serial.printf("[SETUP] WAIT %d...\n", t);
|
||||
Serial.flush();
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFiMulti.addAP("SSID", "PASSWORD");
|
||||
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// wait for WiFi connection
|
||||
if ((WiFiMulti.run() == WL_CONNECTED)) {
|
||||
|
||||
HTTPClient http;
|
||||
|
||||
BearSSL::WiFiClientSecure *client = new BearSSL::WiFiClientSecure ;
|
||||
|
||||
bool mfln = client->probeMaxFragmentLength("tls.mbed.org", 443, 1024);
|
||||
Serial.printf("\nConnecting to https://tls.mbed.org\n");
|
||||
Serial.printf("Maximum fragment Length negotiation supported: %s\n", mfln ? "yes" : "no");
|
||||
if (mfln) {
|
||||
client->setBufferSizes(1024, 1024);
|
||||
}
|
||||
|
||||
Serial.print("[HTTPS] begin...\n");
|
||||
|
||||
// configure server and url
|
||||
const uint8_t fingerprint[20] = {0xEB, 0xD9, 0xDF, 0x37, 0xC2, 0xCC, 0x84, 0x89, 0x00, 0xA0, 0x58, 0x52, 0x24, 0x04, 0xE4, 0x37, 0x3E, 0x2B, 0xF1, 0x41};
|
||||
client->setFingerprint(fingerprint);
|
||||
|
||||
if (http.begin(*client, "https://tls.mbed.org/")) {
|
||||
|
||||
Serial.print("[HTTPS] GET...\n");
|
||||
// start connection and send HTTP header
|
||||
int httpCode = http.GET();
|
||||
if (httpCode > 0) {
|
||||
// HTTP header has been send and Server response header has been handled
|
||||
Serial.printf("[HTTPS] GET... code: %d\n", httpCode);
|
||||
|
||||
// file found at server
|
||||
if (httpCode == HTTP_CODE_OK) {
|
||||
|
||||
// get lenght of document (is -1 when Server sends no Content-Length header)
|
||||
int len = http.getSize();
|
||||
|
||||
// create buffer for read
|
||||
static uint8_t buff[128] = { 0 };
|
||||
|
||||
// get tcp stream
|
||||
WiFiClient * stream = client;
|
||||
|
||||
// read all data from server
|
||||
while (http.connected() && (len > 0 || len == -1)) {
|
||||
// get available data size
|
||||
size_t size = stream->available();
|
||||
|
||||
if (size) {
|
||||
// read up to 128 byte
|
||||
int c = stream->readBytes(buff, ((size > sizeof(buff)) ? sizeof(buff) : size));
|
||||
|
||||
// write it to Serial
|
||||
Serial.write(buff, c);
|
||||
|
||||
if (len > 0) {
|
||||
len -= c;
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
}
|
||||
|
||||
Serial.println();
|
||||
Serial.print("[HTTPS] connection closed or file end.\n");
|
||||
|
||||
}
|
||||
} else {
|
||||
Serial.printf("[HTTPS] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
|
||||
}
|
||||
|
||||
http.end();
|
||||
} else {
|
||||
Serial.printf("Unable to connect\n");
|
||||
}
|
||||
|
||||
delete client;
|
||||
}
|
||||
|
||||
delay(10000);
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
name=ESP8266HTTPClient
|
||||
version=1.1
|
||||
version=1.2
|
||||
author=Markus Sattler
|
||||
maintainer=Markus Sattler
|
||||
sentence=http Client for ESP8266
|
||||
|
@ -21,15 +21,19 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#include <StreamString.h>
|
||||
#include <base64.h>
|
||||
|
||||
#include "ESP8266HTTPClient.h"
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <WiFiClientSecure.h>
|
||||
#endif
|
||||
|
||||
#include <StreamString.h>
|
||||
#include <base64.h>
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
class TransportTraits
|
||||
{
|
||||
public:
|
||||
@ -100,12 +104,17 @@ public:
|
||||
protected:
|
||||
uint8_t _fingerprint[20];
|
||||
};
|
||||
#endif // HTTPCLIENT_1_1_COMPATIBLE
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
HTTPClient::HTTPClient()
|
||||
{
|
||||
_client = nullptr;
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
_tcpDeprecated.reset(nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,8 +122,8 @@ HTTPClient::HTTPClient()
|
||||
*/
|
||||
HTTPClient::~HTTPClient()
|
||||
{
|
||||
if(_tcp) {
|
||||
_tcp->stop();
|
||||
if(_client) {
|
||||
_client->stop();
|
||||
}
|
||||
if(_currentHeaders) {
|
||||
delete[] _currentHeaders;
|
||||
@ -130,9 +139,66 @@ void HTTPClient::clear()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* parsing the url for all needed parameters
|
||||
* @param client Client&
|
||||
* @param url String
|
||||
* @param https bool
|
||||
* @return success bool
|
||||
*/
|
||||
bool HTTPClient::begin(WiFiClient &client, String url) {
|
||||
end();
|
||||
|
||||
_client = &client;
|
||||
|
||||
// check for : (http: or https:)
|
||||
int index = url.indexOf(':');
|
||||
if(index < 0) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][begin] failed to parse protocol\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
String protocol = url.substring(0, index);
|
||||
if(protocol != "http" && protocol != "https") {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][begin] unknown protocol '%s'\n", protocol.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
_port = (protocol == "https" ? 443 : 80);
|
||||
return beginInternal(url, protocol.c_str());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* directly supply all needed parameters
|
||||
* @param client Client&
|
||||
* @param host String
|
||||
* @param port uint16_t
|
||||
* @param uri String
|
||||
* @param https bool
|
||||
* @return success bool
|
||||
*/
|
||||
bool HTTPClient::begin(WiFiClient &client, String host, uint16_t port, String uri, bool https)
|
||||
{
|
||||
end();
|
||||
|
||||
_client = &client;
|
||||
|
||||
clear();
|
||||
_host = host;
|
||||
_port = port;
|
||||
_uri = uri;
|
||||
_protocol = (https ? "https" : "http");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
bool HTTPClient::begin(String url, String httpsFingerprint)
|
||||
{
|
||||
_transportTraits.reset(nullptr);
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
_port = 443;
|
||||
if (httpsFingerprint.length() == 0) {
|
||||
return false;
|
||||
@ -148,7 +214,9 @@ bool HTTPClient::begin(String url, String httpsFingerprint)
|
||||
|
||||
bool HTTPClient::begin(String url, const uint8_t httpsFingerprint[20])
|
||||
{
|
||||
_transportTraits.reset(nullptr);
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
_port = 443;
|
||||
if (!beginInternal(url, "https")) {
|
||||
return false;
|
||||
@ -169,7 +237,9 @@ bool HTTPClient::begin(String url, const uint8_t httpsFingerprint[20])
|
||||
*/
|
||||
bool HTTPClient::begin(String url)
|
||||
{
|
||||
_transportTraits.reset(nullptr);
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
_port = 80;
|
||||
if (!beginInternal(url, "http")) {
|
||||
return false;
|
||||
@ -177,6 +247,7 @@ bool HTTPClient::begin(String url)
|
||||
_transportTraits = TransportTraitsPtr(new TransportTraits());
|
||||
return true;
|
||||
}
|
||||
#endif // HTTPCLIENT_1_1_COMPATIBLE
|
||||
|
||||
bool HTTPClient::beginInternal(String url, const char* expectedProtocol)
|
||||
{
|
||||
@ -225,8 +296,12 @@ bool HTTPClient::beginInternal(String url, const char* expectedProtocol)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
bool HTTPClient::begin(String host, uint16_t port, String uri)
|
||||
{
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
clear();
|
||||
_host = host;
|
||||
_port = port;
|
||||
@ -236,6 +311,8 @@ bool HTTPClient::begin(String host, uint16_t port, String uri)
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||
bool HTTPClient::begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint)
|
||||
{
|
||||
if (https) {
|
||||
@ -244,9 +321,13 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, bool https, Strin
|
||||
return begin(host, port, uri);
|
||||
}
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
bool HTTPClient::begin(String host, uint16_t port, String uri, String httpsFingerprint)
|
||||
{
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
clear();
|
||||
_host = host;
|
||||
_port = port;
|
||||
@ -262,6 +343,9 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, String httpsFinge
|
||||
|
||||
bool HTTPClient::begin(String host, uint16_t port, String uri, const uint8_t httpsFingerprint[20])
|
||||
{
|
||||
if(_client) _canReuse = false;
|
||||
end();
|
||||
|
||||
clear();
|
||||
_host = host;
|
||||
_port = port;
|
||||
@ -275,7 +359,7 @@ bool HTTPClient::begin(String host, uint16_t port, String uri, const uint8_t htt
|
||||
DEBUG_HTTPCLIENT("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // HTTPCLIENT_1_1_COMPATIBLE
|
||||
|
||||
/**
|
||||
* end
|
||||
@ -294,17 +378,29 @@ void HTTPClient::end(void)
|
||||
void HTTPClient::disconnect()
|
||||
{
|
||||
if(connected()) {
|
||||
if(_tcp->available() > 0) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][end] still data in buffer (%d), clean up.\n", _tcp->available());
|
||||
while(_tcp->available() > 0) {
|
||||
_tcp->read();
|
||||
if(_client) {
|
||||
if(_client->available() > 0) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][end] still data in buffer (%d), clean up.\n", _client->available());
|
||||
while(_client->available() > 0) {
|
||||
_client->read();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(_reuse && _canReuse) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp keep open for reuse\n");
|
||||
} else {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp stop\n");
|
||||
_tcp->stop();
|
||||
if(_client) {
|
||||
_client->stop();
|
||||
_client = nullptr;
|
||||
}
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
if(_tcpDeprecated) {
|
||||
_transportTraits.reset(nullptr);
|
||||
_tcpDeprecated.reset(nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][end] tcp is closed\n");
|
||||
@ -317,8 +413,8 @@ void HTTPClient::disconnect()
|
||||
*/
|
||||
bool HTTPClient::connected()
|
||||
{
|
||||
if(_tcp) {
|
||||
return (_tcp->connected() || (_tcp->available() > 0));
|
||||
if(_client) {
|
||||
return (_client->connected() || (_client->available() > 0));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -376,7 +472,7 @@ void HTTPClient::setTimeout(uint16_t timeout)
|
||||
{
|
||||
_tcpTimeout = timeout;
|
||||
if(connected()) {
|
||||
_tcp->setTimeout(timeout);
|
||||
_client->setTimeout(timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@ -478,7 +574,7 @@ int HTTPClient::sendRequest(const char * type, uint8_t * payload, size_t size)
|
||||
|
||||
// send Payload if needed
|
||||
if(payload && size > 0) {
|
||||
if(_tcp->write(&payload[0], size) != size) {
|
||||
if(_client->write(&payload[0], size) != size) {
|
||||
return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED);
|
||||
}
|
||||
}
|
||||
@ -557,7 +653,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
|
||||
int bytesRead = stream->readBytes(buff, readBytes);
|
||||
|
||||
// write it to Stream
|
||||
int bytesWrite = _tcp->write((const uint8_t *) buff, bytesRead);
|
||||
int bytesWrite = _client->write((const uint8_t *) buff, bytesRead);
|
||||
bytesWritten += bytesWrite;
|
||||
|
||||
// are all Bytes a writen to stream ?
|
||||
@ -565,11 +661,11 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] short write, asked for %d but got %d retry...\n", bytesRead, bytesWrite);
|
||||
|
||||
// check for write error
|
||||
if(_tcp->getWriteError()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _tcp->getWriteError());
|
||||
if(_client->getWriteError()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _client->getWriteError());
|
||||
|
||||
//reset write error for retry
|
||||
_tcp->clearWriteError();
|
||||
_client->clearWriteError();
|
||||
}
|
||||
|
||||
// some time for the stream
|
||||
@ -578,7 +674,7 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
|
||||
int leftBytes = (readBytes - bytesWrite);
|
||||
|
||||
// retry to send the missed bytes
|
||||
bytesWrite = _tcp->write((const uint8_t *) (buff + bytesWrite), leftBytes);
|
||||
bytesWrite = _client->write((const uint8_t *) (buff + bytesWrite), leftBytes);
|
||||
bytesWritten += bytesWrite;
|
||||
|
||||
if(bytesWrite != leftBytes) {
|
||||
@ -590,8 +686,8 @@ int HTTPClient::sendRequest(const char * type, Stream * stream, size_t size)
|
||||
}
|
||||
|
||||
// check for write error
|
||||
if(_tcp->getWriteError()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _tcp->getWriteError());
|
||||
if(_client->getWriteError()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][sendRequest] stream write error %d\n", _client->getWriteError());
|
||||
free(buff);
|
||||
return returnError(HTTPC_ERROR_SEND_PAYLOAD_FAILED);
|
||||
}
|
||||
@ -642,7 +738,7 @@ int HTTPClient::getSize(void)
|
||||
WiFiClient& HTTPClient::getStream(void)
|
||||
{
|
||||
if(connected()) {
|
||||
return *_tcp;
|
||||
return *_client;
|
||||
}
|
||||
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] getStream: not connected\n");
|
||||
@ -657,7 +753,7 @@ WiFiClient& HTTPClient::getStream(void)
|
||||
WiFiClient* HTTPClient::getStreamPtr(void)
|
||||
{
|
||||
if(connected()) {
|
||||
return _tcp.get();
|
||||
return _client;
|
||||
}
|
||||
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] getStreamPtr: not connected\n");
|
||||
@ -697,7 +793,7 @@ int HTTPClient::writeToStream(Stream * stream)
|
||||
if(!connected()) {
|
||||
return returnError(HTTPC_ERROR_CONNECTION_LOST);
|
||||
}
|
||||
String chunkHeader = _tcp->readStringUntil('\n');
|
||||
String chunkHeader = _client->readStringUntil('\n');
|
||||
|
||||
if(chunkHeader.length() <= 0) {
|
||||
return returnError(HTTPC_ERROR_READ_TIMEOUT);
|
||||
@ -734,7 +830,7 @@ int HTTPClient::writeToStream(Stream * stream)
|
||||
|
||||
// read trailing \r\n at the end of the chunk
|
||||
char buf[2];
|
||||
auto trailing_seq_len = _tcp->readBytes((uint8_t*)buf, 2);
|
||||
auto trailing_seq_len = _client->readBytes((uint8_t*)buf, 2);
|
||||
if (trailing_seq_len != 2 || buf[0] != '\r' || buf[1] != '\n') {
|
||||
return returnError(HTTPC_ERROR_READ_TIMEOUT);
|
||||
}
|
||||
@ -903,39 +999,46 @@ bool HTTPClient::hasHeader(const char* name)
|
||||
*/
|
||||
bool HTTPClient::connect(void)
|
||||
{
|
||||
|
||||
if(connected()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] connect. already connected, try reuse!\n");
|
||||
while(_tcp->available() > 0) {
|
||||
_tcp->read();
|
||||
while(_client->available() > 0) {
|
||||
_client->read();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_transportTraits) {
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
if(!_client) {
|
||||
_tcpDeprecated = _transportTraits->create();
|
||||
_client = _tcpDeprecated.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!_client) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] connect: HTTPClient::begin was not called or returned error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
_tcp = _transportTraits->create();
|
||||
_tcp->setTimeout(_tcpTimeout);
|
||||
_client->setTimeout(_tcpTimeout);
|
||||
|
||||
if(!_tcp->connect(_host.c_str(), _port)) {
|
||||
if(!_client->connect(_host.c_str(), _port)) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] failed connect to %s:%u\n", _host.c_str(), _port);
|
||||
return false;
|
||||
}
|
||||
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] connected to %s:%u\n", _host.c_str(), _port);
|
||||
|
||||
if (!_transportTraits->verify(*_tcp, _host.c_str())) {
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
if (_tcpDeprecated && !_transportTraits->verify(*_tcpDeprecated, _host.c_str())) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] transport level verify failed\n");
|
||||
_tcp->stop();
|
||||
_client->stop();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ESP8266
|
||||
_tcp->setNoDelay(true);
|
||||
_client->setNoDelay(true);
|
||||
#endif
|
||||
return connected();
|
||||
}
|
||||
@ -990,7 +1093,7 @@ bool HTTPClient::sendHeader(const char * type)
|
||||
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client] sending request header\n-----\n%s-----\n", header.c_str());
|
||||
|
||||
return (_tcp->write((const uint8_t *) header.c_str(), header.length()) == header.length());
|
||||
return (_client->write((const uint8_t *) header.c_str(), header.length()) == header.length());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1011,9 +1114,9 @@ int HTTPClient::handleHeaderResponse()
|
||||
unsigned long lastDataTime = millis();
|
||||
|
||||
while(connected()) {
|
||||
size_t len = _tcp->available();
|
||||
size_t len = _client->available();
|
||||
if(len > 0) {
|
||||
String headerLine = _tcp->readStringUntil('\n');
|
||||
String headerLine = _client->readStringUntil('\n');
|
||||
headerLine.trim(); // remove \r
|
||||
|
||||
lastDataTime = millis();
|
||||
@ -1114,7 +1217,7 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
|
||||
while(connected() && (len > 0 || len == -1)) {
|
||||
|
||||
// get available data size
|
||||
size_t sizeAvailable = _tcp->available();
|
||||
size_t sizeAvailable = _client->available();
|
||||
|
||||
if(sizeAvailable) {
|
||||
|
||||
@ -1131,7 +1234,7 @@ int HTTPClient::writeToStreamDataBlock(Stream * stream, int size)
|
||||
}
|
||||
|
||||
// read data
|
||||
int bytesRead = _tcp->readBytes(buff, readBytes);
|
||||
int bytesRead = _client->readBytes(buff, readBytes);
|
||||
|
||||
// write it to Stream
|
||||
int bytesWrite = stream->write(buff, bytesRead);
|
||||
@ -1212,7 +1315,7 @@ int HTTPClient::returnError(int error)
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][returnError] error(%d): %s\n", error, errorToString(error).c_str());
|
||||
if(connected()) {
|
||||
DEBUG_HTTPCLIENT("[HTTP-Client][returnError] tcp stop\n");
|
||||
_tcp->stop();
|
||||
_client->stop();
|
||||
}
|
||||
}
|
||||
return error;
|
||||
|
@ -20,13 +20,17 @@
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Modified by Jeroen Döll, June 2018
|
||||
*/
|
||||
|
||||
#ifndef ESP8266HTTPClient_H_
|
||||
#define ESP8266HTTPClient_H_
|
||||
|
||||
#define HTTPCLIENT_1_1_COMPATIBLE
|
||||
|
||||
#include <memory>
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <WiFiClient.h>
|
||||
|
||||
#ifdef DEBUG_ESP_HTTP_CLIENT
|
||||
@ -124,8 +128,10 @@ typedef enum {
|
||||
HTTPC_TE_CHUNKED
|
||||
} transferEncoding_t;
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
class TransportTraits;
|
||||
typedef std::unique_ptr<TransportTraits> TransportTraitsPtr;
|
||||
#endif
|
||||
|
||||
class StreamString;
|
||||
|
||||
@ -135,17 +141,26 @@ public:
|
||||
HTTPClient();
|
||||
~HTTPClient();
|
||||
|
||||
/*
|
||||
* Since both begin() functions take a reference to client as a parameter, you need to
|
||||
* ensure the client object lives the entire time of the HTTPClient
|
||||
*/
|
||||
bool begin(WiFiClient &client, String url);
|
||||
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false);
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
// Plain HTTP connection, unencrypted
|
||||
bool begin(String url);
|
||||
bool begin(String host, uint16_t port, String uri = "/");
|
||||
bool begin(String url) __attribute__ ((deprecated));
|
||||
bool begin(String host, uint16_t port, String uri = "/") __attribute__ ((deprecated));
|
||||
// Use axTLS for secure HTTPS connection
|
||||
bool begin(String url, String httpsFingerprint);
|
||||
bool begin(String host, uint16_t port, String uri, String httpsFingerprint);
|
||||
bool begin(String url, String httpsFingerprint) __attribute__ ((deprecated));
|
||||
bool begin(String host, uint16_t port, String uri, String httpsFingerprint) __attribute__ ((deprecated));
|
||||
// Use BearSSL for secure HTTPS connection
|
||||
bool begin(String url, const uint8_t httpsFingerprint[20]);
|
||||
bool begin(String host, uint16_t port, String uri, const uint8_t httpsFingerprint[20]);
|
||||
bool begin(String url, const uint8_t httpsFingerprint[20]) __attribute__ ((deprecated));
|
||||
bool begin(String host, uint16_t port, String uri, const uint8_t httpsFingerprint[20]) __attribute__ ((deprecated));
|
||||
// deprecated, use the overload above instead
|
||||
bool begin(String host, uint16_t port, String uri, bool https, String httpsFingerprint) __attribute__ ((deprecated));
|
||||
#endif
|
||||
|
||||
void end(void);
|
||||
|
||||
@ -207,8 +222,11 @@ protected:
|
||||
int writeToStreamDataBlock(Stream * stream, int len);
|
||||
|
||||
|
||||
#ifdef HTTPCLIENT_1_1_COMPATIBLE
|
||||
TransportTraitsPtr _transportTraits;
|
||||
std::unique_ptr<WiFiClient> _tcp;
|
||||
std::unique_ptr<WiFiClient> _tcpDeprecated;
|
||||
#endif
|
||||
WiFiClient* _client;
|
||||
|
||||
/// request handling
|
||||
String _host;
|
||||
|
Reference in New Issue
Block a user