Hallo zusammen,
ich habe ein schwer nachvollziehbares Verhalten beim WiFiClientSecure
.
Und zwar nutze ich einen ESP32 an einem eInk-Display.
Dieser verbindet sich mit dem WLan und bezieht einen einfachen Text von einem Projekt auf https://script.google.com
Die Herausforderung hier ist, dass die erste Anfrage auf einen 302 "Moved Temporarily" stößt.
Im Header steht dann
Location: https://script.googleusercontent.com/macros/echo?user_content_key=SeCrEtUnIqUeKeY
welches dann der Pfad für die Redirection ist.
Folge ich diesem Link, so erhalte ich sauber meinen Rückgabetext vom Script. Zumindest in einem WLAN.
Im anderen WLAN ist es eine Chance von ~1/20 dass der zweite Response irgendetwas enthält. Weder Header, noch Body. Lediglich ein paar Zeilenumbrüche.
Jetzt würde man meinen, es liegt am Router?! Leider beides die identischen Standardgeräte vom pinken T. Es gibt keinen Eintrag in dessen Firewall o.ä.
Nutze ich den Postman am Laptop zum Ausführen des Get´s, so erhalte ich immer den korrekten Response.
Im Script selbst kann ich die eingehende Anfrage ebenfalls erkennen.
Was kann das also sein? Läuft der WiFiClient über? Timeout, wegen einer langsameren (oder gar zu schnellen) Verbindung?
Der Code ist wahrlich kein Meisterwerk..
String GetGoogleScriptResult() {
WiFiClientSecure client;
String movedURL;
String line;
if (!client.connect(HOST, HTTPS_PORT))
return "";
SendGet(client, "https://" + String(HOST) + "/macros/s/" + ScriptId + "/exec" + SecretParam);
ReadHeader(client, movedURL);
movedURL.trim();
if (movedURL.length() > 10) {
Serial.println("Forewarding URL: \"" + movedURL + "\"");
client.stop();
// https:// = 8 chars
String newHost = movedURL.substring(8);
newHost.remove(newHost.indexOf('/'));
char newHostChars[newHost.length() + 1];
newHost.toCharArray(newHostChars, sizeof(newHostChars));
if (client.connect(newHostChars, HTTPS_PORT))
SendGet(client, movedURL);
else
Serial.println("Redirect failed!");
//Read Header again:
ReadHeader(client, movedURL);
}
while (client.connected()) {
if (client.available()) {
line += client.readStringUntil('\r');
}
}
client.stop();
return line;
}
void SendGet(WiFiClientSecure &client, String adress) {
client.println("GET " + adress);
client.println("Host: " + String(HOST));
//client.println("Connection: close");
client.println("Connection: keep-alive");
client.println("Content-Type: text/plain");
client.println("Pragma: no-cache");
client.println("Cache-Control: no-cache");
client.println("User-Agent: ESP32");
client.println("Accept: application/json");
client.println();
}
void ReadHeader(WiFiClientSecure &client, String &movedURL) {
String line;
Serial.println("Header:");
while (client.connected()) {
line = client.readStringUntil('\n');
Serial.println(line);
if (line == "\r")
break;
if (line.indexOf("Location") >= 0) { // Rerouting
movedURL = line.substring(line.indexOf(":") + 2 ) ;
}
}
}
Denke, trotz des "historisch gewachsenem" Code, kann man die Idee erkennen.
Es wird immer der Header ausgelesen, bis ein einzelner Zeilenumbruch erscheint (welcher Header von Body trennt).
Ist ein "Location" enthalten, wird die Anfrage nochmal an diese Adresse gesendet und wieder bis zum Body ausgelesen.
Irgendwelche Ideen, wie ich dem Ganzen weiter auf den Grund gehen könnte?