[Solved] HTTPS GET funktioniert nicht über WIFI

Hi,

ich stehe erneut vor einem recht bizarren Problem. Ich benutze das WiFi-Modul eines MKR1000 zum Zugriff auf das Internet. Firmware ist aktuell, IDE ist die Beta 1.9.0.

Ich habe zwei unterschiedliche Internetabfragen im Sketch:

  • HTTP an google.com, Port 80
  • HTTPS an einen anderen Server, Port 443

Beim ersten Abruf interessiert mich hauptsächlich der HTTP-Header, der zweite bringt eine JSON-Struktur zurück. Normalerweise...

Wenn ich das über einen "normalen" Router (Fritzbox etc.) mache, klappt beides. Wenn ich aber über einen Tethering-HotSpot auf einem Mobiltelefon (T-mobile) gehe, funktioniert nur der erste (HTTP-)Request, der zweite kommt zwar korrekt beim Server an, die Antwort des Servers landet aber nicht im Sketch. Da kommt kein einziges Zeichen an, nichtmal der HTTP-Header. Der Server sendet nachweislich einen Header mit "200 OK" und seine Daten.

WTF? :o

[Update]
Inzwischen konnte ich wieder mit normalem WLAN testen - geht auch nicht mehr. Es muss also wohl doch mit meinem Code, der WIFI-Firmware oder der Wifi101-Library zusammenhängen.

[Lösung]
Banaler Grund, massive Wirkung: die "Host: "-Zeile im Request war mit "\n\r" statt "\r\n" abgeschlossen.

Und was genau ist deine Frage? WTF?
Du solltest schon deinen Code in Code Tags hier reinstellen, ansonsten kann man dich sonst nur bemitleiden. Oder wie soll man dir helfen?

Kann der MKR1000 https?

Edit: Kann offensichtlich Add SSL Certificates To MKR1000 - Hackster.io

themanfrommoon:
Und was genau ist deine Frage? WTF?
Du solltest schon deinen Code in Code Tags hier reinstellen, ansonsten kann man dich sonst nur bemitleiden. Oder wie soll man dir helfen?

Ich glaube nicht, dass mein Code da aufschlussreich ist, denn das Problem spielt sich ja wohl außerhalb ab. Ich müsste dazu auch den Sketch von momentan etwa 1800 Zeilen so verkürzen, dass nur die HTTP(S)-Logik übrig bleibt.

Ich habe keine Idee mehr, wo ich noch suchen könnte, deswegen mein etwas hilfloser Post. Ich hatte die Hoffnung, dass schon einmal jemand anders hier auf diesen Effekt gestoßen ist und weiß, woran es lag.

Da die zurückgesendeten Daten nur aus den zwei Zeichen "[]" bestehen, ist mein aktueller Verdacht, dass irgendwer in der Übertragungskette die "wegoptimiert".

Ohne Code wird wir wohl niemand helfen können.

So, habe mal den Wifi-Code in einen separaten Sketch gepackt, der sich genauso verhält. Den HTTPS-Server musste ich XXX-en.

Bitteschön:

#include <mini-printf.h>
#include <WiFi101.h>

// Initialize the Wifi client library
WiFiClient client;

void setup() {
  long timer = millis() + 30000;
  int status = 0;
  Serial.begin(9600);
  Serial.println("");
  delay(2000);
  
  while (timer>millis())
  {
    status = WiFi.begin("XXXX", "XXXX");
    if(status == WL_CONNECTED) break;
      // wait 5 more seconds for connection:
      delay(5000);
  }
  if(status!=WL_CONNECTED) 
  { 
    Serial.println("No WLAN connection after 30 seconds.");
  }
  else
  {
    IPAddress ip = WiFi.localIP();
    mini_uprintf(Serial, "Connected. IP: %d.%d.%d.%d\n", ip[0], ip[1], ip[2], ip[3]);

// HTTP-Request
    timer = millis()+20000;
    client.connect("google.com", 80);
    while(millis()<timer && !client.connected());
    if(client.connected())
    {
      mini_uprintf(Serial, "Connected to google.com\n");
      mini_uprintf(client, "GET / HTTP/1.1\r\n\r\n");
      //wait for the answer from GET command. Wait for 8 seconds or until a char from client is available. 
      //After every char, wait 250ms or until  a new char arrives
      timer = millis()+8000;
      bool comms_ok = false;
      while(millis()<timer)
      {
        if(client.available()) 
        {
          comms_ok = true;
          break;
        }
      }
      if(comms_ok)
      {
        Serial.print("Response: ");
        int cnt = 0;
        while(client.available())
        {
          char c = client.read();
          if(cnt<500)
          {
            Serial.print(c);
            cnt++;
          }
        }
        Serial.println("");
      }
      else
      {
        Serial.println("Failed.");
      }
      client.stop();
    }

// HTTPS-Request
    timer = millis()+20000;
    client.connectSSL("XXXX", 443);
    while(millis()<timer && !client.connected());
    if(client.connected())
    {
      mini_uprintf(Serial, "Connected to XXXX\n");
      mini_uprintf(client, "GET XXXX/?FMT=JSON&GUID=E2003412-012E-4FD0-A005-89A8E2454254 HTTP/1.1\r\n");
      //wait for the answer from GET command. Wait for 8 seconds or until a char from client is available. 
      //After every char, wait 250ms or until  a new char arrives
      timer = millis()+8000;
      bool comms_ok = false;
      while(millis()<timer)
      {
        if(client.available()) 
        {
          comms_ok = true;
          break;
        }
      }
      if(comms_ok)
      {
        Serial.print("Response: ");
        int cnt = 0;
        while(client.available())
        {
          char c = client.read();
          if(cnt<500)
          {
            Serial.print(c);
            cnt++;
          }
        }
        Serial.println("");
      }
      else
      {
        Serial.println("Failed.");
      }
      client.stop();
    }
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

Hier der Output beim Tethering:

Connected. IP: 192.168.43.101
Connected to google.com
Response: HTTP/1.1 200 OK
Date: Thu, 23 Aug 2018 08:03:29 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: 1P_JAR=2018-08-23-08; expires=Sat, 22-Sep-2018 08:03:29 GMT; path=/; domain=.google.com
Set-Cookie: NID=137=XBhXqhYnnbdfRrbALALKe_LPukfiUuFkzJC9fDnufFTRSUmuLj5c5zDxHhrwt3V0SJJcNqUMGY9gemA2gcDn6Drg
Connected to XXXX
Failed.

Ich kann den Sketch mangels WLAN momentan nicht ohne Tethering laufen lassen, unsterstelle aber mal, dass er sich identisch zum "großen" Sketch verhält.

Hmm, weshalb das gerade beim Tethering auftaucht ist komisch.

Hatte Probleme bei meinem NodeMCU ESP8266. Dort habe ich dann einen Bug auf GitHub ausfindig gemacht, der bei einer bestimmten TLS-Version Probleme bereitet hat.
Da dieser aber noch nicht freigegeben war, musste ich den Fix selber vornehmen und in der NodeMCU Hardware Library manuell ändern.
Hat sogar auf Anhieb funktioniert!

Vielleicht ist sowas in der Art auch Dein Problem? Der Unterschied beim Tethering ist ja eigentlich nur, dass Deine Anfrage getunnelt wird.

Der Tethering-Effekt tritt sowohl bei einem iPhone als auch auf einem Android 8-Gerät auf, weswegen ich den Provider T-mobile im Verdacht habe - der ist nämlich in beiden Fällen die einzige Gemeinsamkeit. Da ich nichtmal einen Header zurückbekomme: wie kann ich die TLS-Variante herausfinden?

Der NodeMCU / ESP8266 gibt einem das im Serial Monitor aus, wenn man ihn in den Debug-Modus stellt.
Dadurch bin ich auch erst auf das Problem aufmerksam geworden.
Wie das beim MKR1000 ist kann ich Dir leider nicht sagen.

Seltsam ist, dass nur der Weg zurück nicht klappt. Hätte erwartet dass es geht oder nicht. Aber nix dazwischen :o

Ich sag' ja: "bizarr"... :o

Aber danke für Deine Hilfe.

Wie im ersten Post geschrieben, funktioniert WLAN ohne Tethering auch nicht mehr. Der Connect über SSL ist erfolgreich (connected() liefert true), aber der GET-Request verpufft.

Lösung: ich hatte versehentlich die "Host: "-Zeile im GET-Request mit LFCR statt CRLF ("\n\r" statt "\r\n") abgeschlossen. Dadurch wurde der Request irgendwo mit "400 BAD REQUEST" abgelehnt, die Response kam aber nicht zu mir durch.

Hi

Netter Fehler!
Noch netter, daß Du uns Diesen zeigst!

MfG