Closed
Description
Platform
- Hardware: [ESP-12]
- Core Version: [8ae0746]
- Development Env: [Arduino IDE]
- Operating System: [MacOS]
Settings in IDE
- Module: [Generic ESP8266 Module]
- Flash Mode: [qio]
- Flash Size: [4MB/1MB]
- lwip Variant: [v2 Lower Memory]
- Reset Method: [nodemcu]
- Flash Frequency: [40Mhz]
- CPU Frequency: [160MHz]
- Upload Using: [SERIAL]
- Upload Speed: [115200]
Problem Description
No Timeout implemented using client.readStringUntil()
Tested with WiFiClient, WiFiClientSecure, BearSSL::WiFiClientSecure
MCVE Sketch
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <WiFiClient.h>
WiFiClient client;
const int API_TIMEOUT = 1500;
struct Result {
int code;
String content;
};
Result res;
struct Timings {
int count;
int conn;
int req;
int head;
int body;
int stop;
int htout;
int btout;
};
Timings t;
String line;
int myWdt;
const char* host = "el-sag.com";
const char* url = "/wm/tout.cgi";
const int httpsPort = 80;
long init_ms;
String data = "{}";
bool TOUT;
int c_len;
char c_buf[512];
int bytes;
void setup() {
init_ms = millis();
Serial.begin(74880);
Serial.print("Connecting to Wifi");
WiFi.begin();
while (WiFi.status() != WL_CONNECTED) { Serial.print("."); delay(200); }
Serial.println();
logger("Free HEAP: " + String(ESP.getFreeHeap()));
}
void loop() {
t.count++;
myWdt = millis();
client.setTimeout(API_TIMEOUT);
logger("Client Secure started " + String(millis() - myWdt) + " ms");
logger("Free HEAP: " + String(ESP.getFreeHeap()));
logger("connecting to " + String(host));
t.conn += millis() - myWdt;
myWdt = millis();
if (!client.connect(host, httpsPort)) {
logger("Connection failed " + String(millis() - myWdt) + " ms");
res.code = 0; res.content = F("connection failed");
return; // 1 = connection failed
}
logger("Free HEAP: " + String(ESP.getFreeHeap()));
t.conn += millis() - myWdt;
logger("Connected " + String(millis() - myWdt) + " ms");
myWdt = millis();
logger("Free HEAP: " + String(ESP.getFreeHeap()));
logger("requesting URL: " + String(url) + " with data: " + String(data));
myWdt = millis();
client.print(String("POST ") + url + " HTTP/1.0\r\n" +
"Host: " + host + "\r\n"
+ "Content-Type: application/json\r\n"
+ "Content-Length: " + data.length() + "\r\n\r\n"
+ data);
t.req += millis() - myWdt;
logger("Request sent " + String(millis() - myWdt) + " ms");
logger("Free HEAP: " + String(ESP.getFreeHeap()));
client.setTimeout(API_TIMEOUT);
myWdt = millis();
TOUT=1;
while (client.connected()) {
line = client.readStringUntil('\n');
if (line.startsWith("HTTP/1.")) {
res.code = line.substring(9, 12).toInt();
logger("Got HTTP code " + String(res.code));
}
if (line.startsWith("Content-Length: ")) {
c_len = line.substring(15).toInt();
logger("Got Content-length: " + String(c_len));
}
if (line == "\r") {
t.head += millis() - myWdt;
logger("Headers received " + String(millis() - myWdt) + " ms");
logger("Free HEAP: " + String(ESP.getFreeHeap()));
TOUT=0;
break;
}
}
if(TOUT) {
t.htout++;
logger("\n*** Timeout receiving headers. Connected: " + String(client.connected()));
return;
}
myWdt = millis();
if (client.available()) {
TOUT=1;
//res.content += String(client.read());
bytes = client.readBytes(c_buf, c_len);
c_buf[c_len] = '\0';
TOUT=0;
}
if(TOUT) {
t.btout++;
logger("\n*** Timeout receiving body. Connected: " + String(client.connected()));
return;
}
res.content = String(c_buf);
logger("Result length: " + String(res.content.length()) + " | " + String(bytes));
t.body += millis() - myWdt;
logger("Content received " + String(millis() - myWdt) + " ms");
logger("Free HEAP: " + String(ESP.getFreeHeap()));
myWdt = millis();
client.stop();
t.stop += millis() - myWdt;
logger("Client stop " + String(millis() - myWdt) + " ms");
logger("Free HEAP: " + String(ESP.getFreeHeap()));
logger("\n*** Result: " + res.content);
logger(String("Cycles: ") + t.count + " Head TOUTs: " + t.htout + " Body TOUTs: " + t.btout + "\nConn ave: " + t.conn/t.count
+ "\nReq ave: " + t.req/t.count + "\nHead ave: " + t.head/t.count
+ "\nBody ave: " + t.body/t.count + "\nStop ave: " + t.stop/t.count + "\nOverall ave: " + (t.conn+t.req+t.head+t.body+t.stop)/t.count);
// logger("Session size: " + String(sizeof(session)));
}
void printTS() {
long ts = millis() - init_ms;
int m = ts / 60000;
int s = (ts) / 1000 - m * 60;
int ms = ts - m * 60000 - s * 1000;
Serial.printf("%02d:%02d:%03d ", m, s, ms);
}
void logger(String str) {
printTS();
Serial.println(str);
}
Debug Messages
SDK:3.0.0-dev(c0f7b44)/Core:2.4.2-96-g8ae0746e/lwIP:2.1.0(STABLE-2_1_0_RELEASE/glue:arduino-2.4.2-13-g80224f0)/BearSSL:f55a6ad
Connecting to Wifiscandone
.scandone
state: 0 -> 2 (b0)
state: 2 -> 3 (0)
state: 3 -> 5 (10)
add 0
aid 4
cnt
connected with Welcome, channel 11
dhcp client start...
.ip:192.168.3.128,mask:255.255.255.0,gw:192.168.3.200
00:00:408 Free HEAP: 49352
00:00:408 Client Secure started 0 ms
00:00:408 Free HEAP: 49352
00:00:409 connecting to el-sag.com
00:00:594 Free HEAP: 48928
00:00:595 Connected 185 ms
00:00:595 Free HEAP: 48928
00:00:595 requesting URL: /wm/tout.cgi with data: {}
00:00:597 Request sent 1 ms
00:00:600 Free HEAP: 48232
pm open,type:2 0
00:12:362 Got HTTP code 200
00:12:368 Headers received 11765 ms
00:12:368 Free HEAP: 47984
00:12:369 Result length: 0 | 0
00:12:369 Content received 0 ms
00:12:370 Free HEAP: 47984
00:12:374 Client stop 1 ms
00:12:376 Free HEAP: 48056
00:12:380
*** Result:
00:12:384 Cycles: 1 Head TOUTs: 0 Body TOUTs: 0
Conn ave: 186
Req ave: 1
Head ave: 11765
Body ave: 0
Stop ave: 1
Overall ave: 11953