mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ESP8226 mit Bad Request


Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich hoffe Ihr hattet oder habt ein schönen Weihnachtsfest.

Ich beschäftige mich zur Zeit mit den WLAN-Modul ESP8266, welche mir 
eine PHP auf meinen Server mit Übergabewerten aufruft und diese PHP dann 
in eine XML schreibt. Der Code der PHP funktioniert tadellos. Die 
gesendeten Werte des ESP8266 wurden wochenlang sauber in die XML 
geschrieben. Nur seit ein paar Tagen, sendet mir der Server "Bad 
Request" zurück (siehe Bild), obwohl der Code der selbe ist.

Die GET-Anfrage sieht ungefähr so aus:
putString("GET /esp8266/haawrite.php?b0=0&b0=1&b0=2&b0=3&b4=4&b5=5&b6=6&b7=7 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n");

Ich bin mir ziemlich sicher, dass das nicht an meiner Anfrage liegt, 
weil sie ja schliesslich immer so funktioniert hat. Ich gehe eher davon 
aus, dass in der Zeit neue Update des Servers daran schuld sind. Was die 
Sache noch verwirrender macht ist, dass wenn ich manchmal die komplette 
Schaltung neu starte, ein einziger Request erfolgreich gesendet wird, 
dannach kommt wieder nur noch der Bad Request. Leider konnte kann ich 
das nicht reproduzieren, mal geht es mit dem Neustart, mal nicht.

Infos zum Server:
Synology DS 413j
PHP 5.6 läuft
PHP 7.0 läuft
WebStation läuft
Apache HTTP Server 2.2 läuft
Apache HTTP Server 2.4 läuft

Hat jemand eine Idee woran das liegen kann ?

Gruss
Peter

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Untersuche den Netzwerk-Verkehr mit Wireshark, insbesondere den HTTP 
Request.

Autor: Jim Meba (turboj)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Das ist ein HTTP/1.0 Request. Für HTTP 1.1 muss da IMO noch ein 
"Connection: close" Header mit rein, siehe Kapitel 6.1 in RFC 7230.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
> b0=0&b0=1&b0=2&b0=3&b4=4

Kommt mir irgendwie komisch vor. viermal wird b0 ein unterschiedlicher 
Wert zugewiesen. Soll das so sein?

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> b0=0&b0=1&b0=2&b0=3&b4=4
>Kommt mir irgendwie komisch vor.

Das man komisch sein, ist aber sicher nicht die Problemursache. Es ist 
sogar offiziell erlaubt, einen Parameter mehrmals zu wiederholen. Ich 
würde es allerdings nicht tun.

Autor: Jürgen K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
> Die GET-Anfrage sieht ungefähr so aus:
> ...

Und wie sieht sie wirklich aus?

Lass dir die URL doch mal ausgeben oder schau in den Logfiles vom 
Server, vermutlich wird die einfach nur falsch zusammengebaut weil eine 
der Variablen aus denen sie wohl besteht leer ist (irgend ein sensor 
ausgestiegen?).

In etwa so:
> b0=&b0=1&b0=2&b0=3&b4=4

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde auch ganz stark auf einen kaputten GET-Request tippen. Der 
Server wird sicherlich ausgereifter sein, als dein Code, und mit 
Sicherheit würde ein Server nicht über ein Update kaputt gepatcht. Lass 
dir den vom ESP zusammengebauten GET-Request über's Terminal ausgeben 
oder sieh dir die Kommunikation in Wireshark an, da wirst du sicher 
schnell fündig.

Gruß

Autor: Jan L. (ranzcopter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was sagt denn das nginx error Log? Wenn es nichts sagt, dann aktiviere 
es, am besten mit Loglevel ‚debug‘ (falls möglich), oder zumindest 
‚info‘.

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jim M. schrieb:
> Das ist ein HTTP/1.0 Request.

Wo siehst du das? Er schickt doch klar HTTP/1.1 im Request mit.

Jim M. schrieb:
> Für HTTP 1.1 muss da IMO noch ein "Connection: close" Header mit rein,
> siehe Kapitel 6.1 in RFC 7230

Nein, braucht es nicht. HTTP/1.1 geht grundsätzlich von persistenten 
Verbindungen aus, siehe Kapitel 6.3 im RFC 7230.

Abgesehen davon wäre das überhaupt unlogisch, da es ja wochenlang 
funktioniert hat. Wieso sollte sich daher der Server jetzt plötzlich an 
einem fehlenden Header-Feld stören, welches vorher auch schon gefehlt 
hat?

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> HTTP/1.1 geht grundsätzlich von persistenten Verbindungen aus

Eben das könnte der Haken sein. Wenn jetzt weder der Server noch der 
Client die Verbindung nach der Response schließt, dann wird der zweite 
Request nicht richtig erkannt, denn es gibt auch keinen Content-Length 
Header und keinen Chunked-Mode.

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
P. F. schrieb:
> Die GET-Anfrage sieht ungefähr so aus:

Zeig uns doch einfach den Teil Code, der deine Anfrage konkret 
zusammenbaut.

P. F. schrieb:
> Ich bin mir ziemlich sicher, dass das nicht an meiner Anfrage liegt,
> weil sie ja schliesslich immer so funktioniert hat.

Häufig ist es dann aber so, dass es ziemlich sicher am eigenen Code 
liegt :)

P. F. schrieb:
> Was die Sache noch verwirrender macht ist, dass wenn ich manchmal die
> komplette Schaltung neu starte, ein einziger Request erfolgreich
> gesendet wird, dannach kommt wieder nur noch der Bad Request.

Das untermauert meine Aussage noch.

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
>> HTTP/1.1 geht grundsätzlich von persistenten Verbindungen aus
>
> Eben das könnte der Haken sein. Wenn jetzt weder der Server noch der
> Client die Verbindung nach der Response schließt, dann wird der zweite
> Request nicht richtig erkannt, denn es gibt auch keinen Content-Length
> Header und keinen Chunked-Mode.

Das könnte es natürlich sein und war auch eine meiner Ideen. Ich würde 
immer einen sauberen Request mit zumindest einem Content-Length- und 
einem Connection-Header mitsenden.

Aber die Ideen hier widersprechen der Aussage des TO, wonach es ja 
anfänglich problemlos funktioniert hat. Entweder stimmt es, was wir 
vermuten, dann dürfte es aber noch nie sauber funktioniert haben. Oder 
der TO hat uns nicht alles erzählt und es hat sich zwischendurch noch 
etwas mehr getan.

Es wäre daher gut, wenn der TO sich wieder einklinken würde und neuen 
Input lieferte, was denn in der Zwischenzeit geschehen ist.

: Bearbeitet durch User
Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Untersuche den Netzwerk-Verkehr mit Wireshark, insbesondere den HTTP
> Request.

Danke, teste ich mal aus.

Jim M. schrieb:
> Das ist ein HTTP/1.0 Request. Für HTTP 1.1 muss da IMO noch ein
> "Connection: close" Header mit rein, siehe Kapitel 6.1 in RFC 7230.

Sobald ich ein "OK" empfange, schliesse ich auc die Verbindung, siehe 
Bild.

Rufus Τ. F. schrieb:
> P. F. schrieb:
>> b0=0&b0=1&b0=2&b0=3&b4=4
>
> Kommt mir irgendwie komisch vor. viermal wird b0 ein unterschiedlicher
> Wert zugewiesen. Soll das so sein?

Kopierfehler. Soll b0, b1, b2, usw heissen.

Jürgen K. schrieb:
> P. F. schrieb:
>> Die GET-Anfrage sieht ungefähr so aus:
>> ...
>
> Und wie sieht sie wirklich aus?
>
> Lass dir die URL doch mal ausgeben oder schau in den Logfiles vom
> Server, vermutlich wird die einfach nur falsch zusammengebaut weil eine
> der Variablen aus denen sie wohl besteht leer ist (irgend ein sensor
> ausgestiegen?).

Hmm, ich hab auch testeweise die URL nicht zusammen gesetzt sondern 
direkt in die "putString" geschrieben. Da hab ich das selbe Problem.

Jan L. schrieb:
> Was sagt denn das nginx error Log? Wenn es nichts sagt, dann aktiviere
> es, am besten mit Loglevel ‚debug‘ (falls möglich), oder zumindest
> ‚info‘.

Uii....wie kann ich die denn auslesen ?

A.. P. schrieb:
> P. F. schrieb:
>> Die GET-Anfrage sieht ungefähr so aus:
>
> Zeig uns doch einfach den Teil Code, der deine Anfrage konkret
> zusammenbaut.

Hier baue ich den Request zusammen, zähle ich Zeichenlänge und sende 
dann:
Unter "TCP_senden" gibt es noch die auskommentierte Zeile die ioch 
testweise sende und damit das zusammenbauen umgehe. Geht aber auch 
nicht.
void TCP_Laenge(uint8_t var0, uint8_t var1, uint8_t var2, uint8_t var3, uint8_t var4, uint8_t var5, uint8_t var6, uint8_t var7)    //Zeichenzählen für Anfrage ermitteln
{
   char wert_chr[3];          //Variable zum wandeln

  /*Komplette GET-Anfrage, Beispiel: 
  GET /esp8266/haawrite.php?b0=333 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n
  */
  
  //Array zusammensetzten
  char get[GET_GROESSE] = "GET ";      //Array beginnen
  strcat(get, PHP_ZIEL);          //an Array anhängen  
  
//   strcat(get, "?b0=");          //an Array anhängen  
//  itoa(byte, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
//   strcat(get, wert_chr);          //an Array anhängen    
//   strcat(get, "=");            //an Array anhängen  
  
  strcat(get, "?b0=");          //an Array anhängen    
  itoa(var0, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt  
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");

  strcat(get, "b1=");            //an Array anhängen      
  itoa(var1, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");
  
  strcat(get, "b2=");            //an Array anhängen  
  itoa(var2, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");

  strcat(get, "b3=");            //an Array anhängen    
  itoa(var3, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");

  strcat(get, "b4=");            //an Array anhängen    
  itoa(var4, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");
  
  strcat(get, "b5=");            //an Array anhängen    
  itoa(var5, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");
  
  strcat(get, "b6=");            //an Array anhängen    
  itoa(var6, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
  strcat(get, "&");
  
  strcat(get, "b7=");            //an Array anhängen    
  itoa(var7, wert_chr, 10);        //Variable wandeln sonst wird die Länge der Zeichen falsch gezählt
  strcat(get, wert_chr);          //an Array anhängen
                
  strcat(get, " HTTP/1.1\r\nHost: ");    //an Array anhängen
  strcat(get, SERVER_IP);          //an Array anhängen
  strcat(get, "\r\n\r\n");        //an Array anhängen
  
  memcpy(_get, get, strlen(get));      //Zusammengesetzten Befehl zum senden global speichern

  size_t i = strlen(get);        //Stringlänge von Array ermitteln
  itoa(i, wert_chr, 10);        //Variable wandeln

  //Array zusammensetzten
  char cipsend[] = "AT+CIPSEND=";  //Array beginnen
  strcat(cipsend, wert_chr);    //an Array anhängen
  strcat(cipsend, "\r\n");    //an Array anhängen
  
  //zusammengesetztes CIPSEND senden
  putString(cipsend);
  //putString("AT+CIPSEND=96\r\n");  //Array beginnen
}
void TCP_Senden()      //
{
//  putString("GET /esp8266/haawrite.php?b0=0&b1=1&b2=2&b3=3&b4=4&b5=5&b6=6&b7=7 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n");
  putString(_get);    //globales, kopiertes Array senden
}

Das eigentlich Senden des Protokolls sieht so aus:
void Protokoll_senden()    //Ausgabe des Protokolls
{    
  static int anfrage_i = 0;    //Laufvariable welche Anfrage gesendet wurde
      
  if (_t_Status_s >= T_STATUS_S)    //Ausgabe erst nach angegebener Zeit
  {
    
    if(!_ESP_Busy)  //ESP steht zur Verfügung und kann angefragt werden
    {      
        //Welches Protkoll soll gesendet werden
        switch(anfrage_i)
        {
          //Anfragen senden
          case 0:
            ESP_Query(TCP_START, "OK");  //mit Empfänger verbinden
          break;

          case 1:
            TCP_Laenge(BAS, SIR, REE, AKL, AKN, SWP, SWB, SWS);    //Zeichenlänge ermitteln
            _ESP_Timeout_s = 0;    //Timeout-Zeit zurücksetzten
            _ESP_Busy = true;    //Flag ESP ist beschäftigt
          break;

          case 2:
            TCP_Senden();      //Eigentliche Daten senden
            _ESP_Timeout_s = 0;    //Timeout-Zeit zurücksetzten
            _ESP_Busy = true;    //Flag ESP ist beschäftigt            
          break;

          case 3:
            ESP_Query(TCP_DISCONNECT, "OK");  //Verbindung schliessen
          break;        
        
          //alle Anfragen wurden gesendet
          default:
            _t_Status_s = 0;    //Timer zurücksetzten, damit in angegebener Zeit wieder gesenet wird
            anfrage_i = 0;      //Laufvariable zurücksetzten, damit die Funktion nochmal aufgerufen werden kann
          break;        
        }      
     }
     
    else
    {
       //prüfen ob erwartete Antwort vorhanden ist
       if(ESP_Response())
       {
         anfrage_i++;      //variable für nächste Anfrage
       }  
    }
  }
}
void ESP_Query (char *anfrage, char *antwort)
{
  strcpy(_gesuchte_antw, antwort);  //erwartete Antwort abspeichern
  putString(anfrage);          //Anfrage senden
  _ESP_Timeout_s = 0;          //Timeout-Zeit zurücksetzten
  _ESP_Busy = true;          //Flag ESP ist beschäftigt
}
bool ESP_Response()
{
  bool rueckgabe = false;

  //Abfrage ob Antwort vorhanden ist
  if(_uart_str_complete)
  {
    //prüfen ob die gesuchte Antwort vorhanden ist
    if(strstr(_uart_string, _gesuchte_antw))  //nach einzelnen Wörtern suchen (ohne Leerzeichen)
    {
      _ESP_Busy = false;    //ESP wieder freigeben        
      rueckgabe = true;    //Rückgabewert positiv
    }
        
    //Unabhängig der Antwort, alles zurücksetzten
    memset(_uart_string, '\0', sizeof(_uart_string));  //Inhalte vom Array löschen
    _uart_str_complete = false;              //String komplett zurücksetzten    
  }

  return rueckgabe;
}

Das ist die esp8266.h:
#ifndef _ESP_8266_H_
#define _ESP_8266_H_
//-----------------------Konstanten / Variablen-------------------------
//WLAN-Daten
#define SSID      "Fxxxx-WLAN"      //WLAN Netzwerk
#define WLAN_PASS    "Mxxxxxxxxxxxxxxxxx."  //WLAN Passwort
#define SERVER_IP    "192.168.1.100"      //IP-Adresse des Servers
#define SERVER_PORT    "80"          //Port des Servers
#define PHP_ZIEL    "/esp8266/haawrite.php"  //Ziel PHP die die gesendeten Daten in XML schreibt

//AT-Befehle
#define WORKS      ("AT\r\n")                      //Esp arbeitet
#define RESET      ("AT+RST\r\n")                    //ESP Software-Reset  
#define WIFI_AUTO_DIS  ("AT+CWAUTOCONN=0\r\n")                //Automatisches WiFi-Connect ausschalten
#define WIFI_AUTO_CON  ("AT+CWAUTOCONN=1\r\n")                //Automatisches WiFi-Connect einschalten
#define WIFI_LISTING  ("AT+CWLAP\r\n")                  //Verfügbare SSID's
#define WIFI_STA    ("AT+CWMODE=1\r\n")                  //WiFi-Verbindungsmodus Stand alone  
#define WIFI_JOIN    ("AT+CWJAP=\"" SSID "\",\"" WLAN_PASS "\"\r\n")    //Mit Router verbinden TODO "Fail" auswerten
#define TCP_SINGLE_CON  ("AT+CIPMUX=0\r\n")                  //TCP/UDP Connetion Single
#define TCP_START    ("AT+CIPSTART=\"TCP\",\"" SERVER_IP "\"," SERVER_PORT "\r\n")    //Mit Empfänger verbinden TODO "ERROR" auswerten
#define TCP_DISCONNECT  ("AT+CIPCLOSE\r\n")                  //TCP-Verbindung schliessen

#define GET_GROESSE    120  //Größe der Zeichen im get-Befehl definieren (max. Zeichen bei Wert 7x 255)
char _get [GET_GROESSE];  //globales Array für den GET-Befehl
char _gesuchte_antw[10];      //Stringbuffer für für die ESP-Antwort
//----------------------------------------------------------------------

//------------------------------Prototypen------------------------------                
void TCP_Laenge(uint8_t var0, uint8_t var1, uint8_t var2, uint8_t var3, uint8_t var4, uint8_t var5, uint8_t var6, uint8_t var7);
void TCP_Senden();
//----------------------------------------------------------------------

#endif

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> char wert_chr[3];          //Variable zum wandeln

Das ist ein Byte zu wenig. Du brauchst 4 Bytes wegen dem abschließenden 
Null-Byte das den String terminiert.

Autor: Jan L. (ranzcopter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
>> Was sagt denn das nginx error Log? Wenn es nichts sagt, dann aktiviere
>> es, am besten mit Loglevel ‚debug‘ (falls möglich), oder zumindest
>> ‚info‘.
>
> Uii....wie kann ich die denn auslesen ?

?? du hast irgendwo ("Server"?) einen nginx laufen. Dieser liefert Error 
400. Recherchiert man da mal ein paar Sekunden im Netz erfährt man, dass 
nginx üblicherweise bei einem Error 400 die (vielfältigen) Ursachen 
dafür in sein Error-Log schreibt. Das Error-Log muss man *evtl.* 
aktivieren - dafür gibt es auf dem "Server" die Datei nginx.conf - oder 
vermutlich eher sowas wie /etc/nginx/conf.d/meinserver.conf o.ä.

Da sollte sowas wie hier stehen:
http {
    server {
        error_log /path/to/log debug;

"debug" wird nicht überall vorgesehen sein, dann einfach "info" nehmen. 
Die Fehlermeldungen stehen dann in "/path/to/log"...

Google Treffer 1:
When nginx returns 400 (Bad Request) it will log the reason into error log, at "info" level. Hence an obvious way to find out what's going on is to configure error_log to log messages at "info" level and take a look into error log when testing.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Das ist ein Byte zu wenig. Du brauchst 4 Bytes wegen dem abschließenden
> Null-Byte das den String terminiert.

Ok, danke. Habs angepasst.

Jan L. schrieb:
> ?? du hast irgendwo ("Server"?) einen nginx laufen. Dieser liefert Error
> 400. Recherchiert man da mal ein paar Sekunden im Netz erfährt man, dass
> nginx üblicherweise bei einem Error 400 die (vielfältigen) Ursachen
> dafür in sein Error-Log schreibt. Das Error-Log muss man *evtl.*
> aktivieren - dafür gibt es auf dem "Server" die Datei nginx.conf - oder
> vermutlich eher sowas wie /etc/nginx/conf.d/meinserver.conf o.ä.
>
> Da sollte sowas wie hier stehen:http {
>     server {
>         error_log /path/to/log debug;
>
> "debug" wird nicht überall vorgesehen sein, dann einfach "info" nehmen.
> Die Fehlermeldungen stehen dann in "/path/to/log"...

Oh man, das scheint kompliziert zu sein. Ich kenne mich damit nicht aus.
Also, ich hab unter /etc/nginx eine "nginx.conf" gefunden. Ist das die 
richtige ?
admin@DiskStation:/etc/nginx$ dir
total 60
drwxr-xr-x  2 root root 4096 Dec 27 07:04 .
drwxr-xr-x 47 root root 4096 Dec 27 13:38 ..
lrwxrwxrwx  1 root root   20 Nov  8 07:03 app.d -> /var/tmp/nginx/app.d
lrwxrwxrwx  1 root root   27 Nov  8 07:03 conf.d -> /usr/local/etc/nginx/conf.d
-rw-r--r--  1 root root 1077 Nov  2 23:13 fastcgi.conf
-rw-r--r--  1 root root 1007 Nov  2 23:13 fastcgi_params
-rw-r--r--  1 root root 2837 Nov  2 23:13 koi-utf
-rw-r--r--  1 root root 2223 Nov  2 23:13 koi-win
-rw-r--r--  1 root root 3957 Nov  2 23:13 mime.types
-rw-r--r--  1 root root 9149 Dec 27 07:04 nginx.conf
-rw-r--r--  1 root root 3491 Nov  2 23:07 nginx.conf.default
-rw-r--r--  1 root root  277 Nov  2 23:07 proxy.conf
-rw-r--r--  1 root root 1204 Nov  2 23:13 scgi_params
lrwxrwxrwx  1 root root   34 Nov  8 07:03 sites-enabled -> /usr/local/etc/nginx/sites-enabled
-rw-r--r--  1 root root  664 Nov  2 23:13 uwsgi_params
-rw-r--r--  1 root root 3610 Nov  2 23:13 win-utf

Im Inhalt steht aber nichts über "error_log":
 server {
        listen 80 default_server;
        listen [::]:80 default_server;

        gzip on;

        server_name _;

        location ~ ^/volume(?:X|USB|SATA|Gluster)?\d+/ {
            internal;

            root /;

            include app.d/x-accel.*.conf;
            include conf.d/x-accel.*.conf;
        }

        include app.d/www.*.conf;
        include app.d/alias.*.conf;
        include /usr/syno/share/nginx/conf.d/www.*.conf;
        include conf.d/www.*.conf;

        location = /webdefault/images/logo.jpg {
            alias /usr/syno/share/nginx/logo.jpg;
        }

        error_page 403 404 500 502 503 504 @error_page;

        location @error_page {
            root /usr/syno/share/nginx;
            rewrite (.*) /error.html break;
        }

        location ^~ /.well-known/acme-challenge {
            root /var/lib/letsencrypt;
            default_type text/plain;
        }

        include app.d/.location.webstation.conf*;

        location / {
            rewrite ^ / redirect;
        }

        location ~ ^/$ {
            rewrite / http://$host:5000/ redirect;
        }
    }


An welcher Stelle muss das denn reingeschrieben werden ?

Einen Pfad "/path...." gibt es beimir nicht:
admin@DiskStation:/$ dir
total 76
drwxr-xr-x  24 root root 4096 Dec 27 07:01 .
drwxr-xr-x  24 root root 4096 Dec 27 07:01 ..
lrwxrwxrwx   1 root root    7 Nov  8 07:01 bin -> usr/bin
drwxr-xr-x   4 root root    0 Dec 27 07:02 config
drwxr-xr-x  11 root root 3800 Dec 27 07:03 dev
drwxr-xr-x  47 root root 4096 Dec 27 13:38 etc
drwxr-xr-x  39 root root 4096 Dec 22 00:03 etc.defaults
drwxr-xr-x   2 root root 4096 Nov  2 23:19 initrd
lrwxrwxrwx   1 root root    7 Nov  8 07:01 lib -> usr/lib
drwx------   2 root root 4096 Nov  2 23:19 lost+found
drwxr-xr-x   2 root root 4096 Nov  2 23:19 mnt
drwxr-xr-x   3 root root 4096 Nov  8 07:01 .old_patch_info
dr-xr-xr-x 224 root root    0 Jan  1  1970 proc
-rw-------   1 root root 1024 Mar 14  2011 .rnd
drwx------   5 root root 4096 Nov 14 03:00 root
drwxr-xr-x  23 root root 1780 Dec 27 13:38 run
lrwxrwxrwx   1 root root    8 Nov  8 07:01 sbin -> usr/sbin
drwxrwxrwx   4 root root 4096 Dec 22 00:03 .syno
drwxr-xr-x  11 root root    0 Jan  1  1970 sys
drwxr-xr-x   2 root root 4096 Mar 14  2011 .system_info
drwxrwxrwt  15 root root 1500 Dec 27 14:49 tmp
drwxr-xr-x   2 root root 4096 Dec 16 03:03 tmpRoot
drwxr-xr-x   9 root root 4096 Nov  2 22:29 usr
drwxr-xr-x  18 root root 4096 Dec 27 07:01 var
drwxr-xr-x  14 root root 4096 Nov  8 07:02 var.defaults
drwxr-xr-x  21 root root 4096 Dec 27 07:02 volume1
drwxr-xr-x  11 root root 4096 Dec 27 07:02 volume2
drwxr-xr-x  10 root root 4096 Dec 27 07:02 volume4

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
> Einen Pfad "/path...." gibt es beimir nicht:

Natürlich nicht. "/path/to/log" ist ein Platzhalter mit offenkundigem 
Namen.

Autor: Jan L. (ranzcopter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>
> Oh man, das scheint kompliziert zu sein. Ich kenne mich damit nicht aus.
> Also, ich hab unter /etc/nginx eine "nginx.conf" gefunden. Ist das die
> richtige ?

Jein; das ist zwar die "Startconfig", die Config deiner Domain liegt 
aber in einem dieser Verzeichnisse:

        include app.d/www.*.conf;
        include app.d/alias.*.conf;
        include /usr/syno/share/nginx/conf.d/www.*.conf;
        include conf.d/www.*.conf;

Ist aber egal, die nginx.conf tut's hierfür erstmal auch - einfach z.B. 
unter "server_name" noch reinschreiben:
error_log  /var/log/nginx/error.log info;

und nginx neu starten. Danach liegt unter /var/log/nginx ein 
"error.log".

Falls es /var/log/nginx noch nicht geben sollte, und du dich vermutlich 
mit Dateirechten nicht recht auskennst :), kannst du einfach auch 
"/tmp/nginx_error.log" nehmen:
error_log  /tmp/nginx_error.log info;

da "darf" nginx immer reinschreiben.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit Wireshark kommst du vielleicht doch schneller voran. Da klickt man 
sich durch.

Autor: Joachim S. (oyo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A.. P. schrieb:
> Jim M. schrieb:
>> Das ist ein HTTP/1.0 Request.
>
> Wo siehst du das? Er schickt doch klar HTTP/1.1 im Request mit.
>
> Jim M. schrieb:
>> Für HTTP 1.1 muss da IMO noch ein "Connection: close" Header mit rein,
>> siehe Kapitel 6.1 in RFC 7230
>
> Nein, braucht es nicht. HTTP/1.1 geht grundsätzlich von persistenten
> Verbindungen aus, siehe Kapitel 6.3 im RFC 7230.

Letztlich habt ihr doch beide Recht:
Laut 6.3 der besagten Spec ist das "Connection: close" bei HTTP/1.1 
nicht zwingend nötig, der Server geht in diesem Fall dann eben von einer 
persistenten Verbindung aus.
Wenn der Client (wie im vorliegenden Fall) aber eben keine persistenten 
Verbindungen unterstützt, dann MUSS er nach Kapitel 6.1 eben doch einen 
"Connection: close"-Header senden.
So gesehen sind die von Arduino-Code erzeugten HTTP-Requests 
strenggenommen ja tatsächlich nicht HTTP/1.1-konform, und die "Bad 
request"-Fehlermeldung somit im Grunde berechtigt.

@Threadstarter: Ich würde an Deiner Stelle wirklich einfach mal 
ausprobieren, was passiert, wenn Du das wahlweise als HTTP 1.0-Request 
sendest, oder eben zusätzlich einfach noch ein "Connection: 
close"-Header-Feld mit einfügst.
Die von stefanus genannte mögliche Erklärung für das Phänomen, warum es 
direkt nach einem Neustart genau einmal funktioniert, klingt für mich 
ziemlich plausibel.

: Bearbeitet durch User
Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim S. schrieb:
> Letztlich habt ihr doch beide Recht

Nicht ganz. Hätte Jim M. geschrieben es "kann" noch ein Connection: 
close rein, dann hätte ich dem zugestimmt. Aber er meinte es "muss" eins 
rein - und das ist eben falsch ;)

Joachim S. schrieb:
> So gesehen sind die von Arduino-Code erzeugten HTTP-Requests
> strenggenommen ja tatsächlich nicht HTTP/1.1-konform, und die "Bad
> request"-Fehlermeldung somit im Grunde berechtigt.

Strenggenommen ist es eben doch ein konformer Request und die Antwort 
des Servers in so einem Fall (sofern der fehlende Connection-Header eben 
der einzige Grund wäre) nicht berechtigt. In dem Moment, wo der Sender 
kein "Connection: close" mitsendet, nimmt der Server automatisch eine 
dauerhafte Verbindung an. Soweit ist doch alles konform. Sobald nun der 
Request vollständig und korrekt beim Server ankommt und dieser seine 
Antwort verschickt hat, bleibt die Verbindung einfach bestehen. Nun 
schließt der Client irgendwann die TCP-Verbindung und alles ist immer 
noch korrekt.

Ich würde aber an Stelle des TO doch einfach als ersten Ansatz einen 
korrekten Content-Length Header setzen, um ein eventuelles Problem mit 
dem Request-Body - welcher ja leer ist - auszuschließen.

: Bearbeitet durch User
Autor: Joachim S. (oyo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A.. P. schrieb:
> Joachim S. schrieb:
>> Letztlich habt ihr doch beide Recht
>
> Nicht ganz. Hätte Jim M. geschrieben es "kann" noch ein Connection:
> close rein, dann hätte ich dem zugestimmt. Aber er meinte es "muss" eins
> rein - und das ist eben falsch ;)

Och, das kann man so oder so sehen, denn im konkreten Fall "muss" laut 
Kapitel 6.1 der Spec doch tatsächlich ein solcher Header rein:
> A client that does not support persistent connections MUST send the
> "close" connection option in every request message.

;)

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim S. schrieb:
> Och, das kann man so oder so sehen, denn im konkreten Fall "muss" laut
> Kapitel 6.1 der Spec doch tatsächlich ein solcher Header rein:
>> A client that does not support persistent connections MUST send the
>> "close" connection option in every request message.
>
> ;)

Und woher kommt deine Annahme, dass der TO mit seinem Code keine 
persistente Verbindung unterstützt? Die Eigenschaft, eine persistente 
Verbindung zu unterstützen, wird doch nicht durch höhere Gewalt 
bestimmt, sondern einzig vom Entwickler vorgegeben und von der Weise, 
wie er seinen HTTP-Code implemetiert hat. Somit signalisiert der TO 
automatisch mit dem fehlenden Header, dass er eine dauerhafte Verbindung 
möchte. Dass er diese vielleicht 200 ms nachdem er die Antwort des 
Servers erhalten hat wieder schließt, ist kein Indiz dafür, dass er 
keine persistente Verbindungen unterstützt. Eine persistente Verbindung 
ist eben alles, was nach Erhalt der Server-Antwort noch offen gehalten 
wird, unabhängig davon, ob es nur 10 ms sind oder bis morgen Mittag 12 
Uhr.

Im Übrigen ziehe ich meine vorherige Aussage bzgl. Content-Length 
zurück, da dies bei einem GET, wie in diesem Fall, nicht das Problem 
sein kann, da es dazu auch im RFC 7230, Kapitel 3.3.2 heißt:

"A user agent SHOULD NOT send a Content-Length header field when the 
request message does not contain a payload body and the method semantics 
do not anticipate such a body."

Gruß

: Bearbeitet durch User
Autor: Jan L. (ranzcopter)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Joachim S. schrieb:
> Och, das kann man so oder so sehen, denn im konkreten Fall "muss" laut

...im "konkreten Fall" ist das in der Praxis völlig unerheblich, wie 
eigentlich jeder jederzeit höchst simpel mit irgendeinem nginx (oder 
apache etc.) nachprüfen kann: Ein einfacher Telnet auf Port 80 eines 
Webservers liefert einwandfreie Antworten, einziger "mandatory header" 
bei HTTP/1.1 ist der Host:-Header, der allerdings halbwegs stimmen 
sollte:
# telnet www.spiegel.de 80
Trying 128.65.210.182...
Connected to www.spiegel.de (128.65.210.182).
Escape character is '^]'.
HEAD / HTTP/1.1
HOST: www.spiegel.de

HTTP/1.1 200 OK
Date: Wed, 27 Dec 2017 17:10:01 GMT
Cache-Control: max-age=45
Expires: Wed, 27 Dec 2017 17:10:46 GMT
X-SP-TE: 6151
X-Robots-Tag: index, follow, noarchive, noodp
Content-Type: text/html;charset=UTF-8
X-SP-AP: 6128
Vary: Accept-Encoding, isssl
Age: 32
X-SP-PR: 6128
Connection: keep-alive

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
> Und woher kommt deine Annahme, dass der TO mit seinem Code keine
> persistente Verbindung unterstützt?

Weil er weder den Content-Length Header noch den Chunked-Transfer 
verwendet hat. Habe ich doch oben geschrieben. Ohne das kann er keinen 
2. Request senden.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> "A user agent SHOULD NOT send a Content-Length header field when the
> request message does not contain a payload body and the method semantics
> do not anticipate such a body."

Ich vermute, dieser Satz stammt aus HTTP 1.0 Zeiten. Get Requests können 
einen Body enthalten (auch wenn das unüblich ist). Und deswegen darf man 
bei GET nicht von der Länge 0 ausgehen. Macht auch kein Server.

Der nächste Request beginnt, nachdem der vorherige beendet ist. Ein 
Request endet wahlweise
a) nach Erreichen der Content-Length,
b) beim Schließen der Verbindung,
c) bei der Ende-Markierung vom Chunked Transfer (nur HTTP 1.1)

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Unabhängig von diesen ganzen Erörterungen, wie der HTTP-Standard denn 
nun aussieht, denke ich, dass der TO nur weiterkommt, wenn er sich mal 
vor sein System setzt und sich ein paar dieser fehlerhaften Anfragen 
ansieht. Ob das nun seriell über das Terminal, über das nginx-Log oder 
mittels Wireshark erfolgt - irgendwas davon wird ihn sicher weiter 
bringen, als alle Diskussionen über den korrekten Aufbau einer Anfrage 
:)

Ich gehe stark davon aus, dass der Server schon richtig arbeitet und der 
Fehler sicher in dem (m.M.n. etwas ungelenken) Zusammenbau der Anfrage 
steckt. Es wird dem TO sicher selbst schnell auffallen, an welcher 
Stelle sein Code unvollständige Anfragen erzeugt, wenn er sich mal ein 
paar davon ansieht.

Autor: Joachim S. (oyo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was mir übrigens gerade eben noch aufgefallen ist:
//Array zusammensetzten
  char cipsend[] = "AT+CIPSEND=";  //Array beginnen
  strcat(cipsend, wert_chr);    //an Array anhängen
  strcat(cipsend, "\r\n");    //an Array anhängen

Meine C/C++-Kenntnisse sind zugegebenermassen äusserst gering, aber ist 
obiges Code-Fragment wirklich okay so? Ich hätte jetzt instinktiv 
vermutet, dass durch ein
char cipsend[] = "AT+CIPSEND="
nur 12 Bytes reserviert werden (also genau so viele, um den String 
"AT+CIPSEND=" sowie ein abschliessenden 0-Byte zu speichern). Und es 
durch die anschliessenden beiden strcat-Befehle dann zu einer Art 
Pufferüberlauf kommt, bei dem möglicherweise unbeabsichtigt etwas ganz 
anderes überschrieben wird, mit möglicherweise unvorhergesehenen Folgen.

Ist obiges Codefragment wirklich okay so?

: Bearbeitet durch User
Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hast du richtig erkannt, du überfüllst das Array und das kann 
allerlei Fehlfunktionen auslösen.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim S. schrieb:
> Ist obiges Codefragment wirklich okay so?

Nee, das ist definitiv kaputt, das hast Du richtig erkannt.

Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Joachim S. schrieb:
> @Threadstarter: Ich würde an Deiner Stelle wirklich einfach mal
> ausprobieren, was passiert, wenn Du das wahlweise als HTTP 1.0-Request
> sendest

Mit den funktioniert das auch nicht:
  putString("GET /esp8266/haawrite.php?b0=0&b1=1&b2=2&b3=3&b4=4&b5=5&b6=6&b7=7 HTTP/1.0\r\nHost: 

192.168.1.100\r\n\r\n");

Joachim S. schrieb:
> zusätzlich einfach noch ein "Connection:
> close"-Header-Feld mit einfügst.

Ist das nicht hiermit schon geschehen ?
#define TCP_DISCONNECT  ("AT+CIPCLOSE\r\n")                  

//TCP-Verbindung schliessen

A.. P. schrieb:
> Ich würde aber an Stelle des TO doch einfach als ersten Ansatz einen
> korrekten Content-Length Header setzen, um ein eventuelles Problem mit
> dem Request-Body - welcher ja leer ist - auszuschließen.

Das verstehe ich nicht ganz. Wie kann ich das realisieren ?

Stefan U. schrieb:
> Weil er weder den Content-Length Header noch den Chunked-Transfer
> verwendet hat. Habe ich doch oben geschrieben. Ohne das kann er keinen
> 2. Request senden.

Ich verstehe nur Bahnhof :-(

A.. P. schrieb:
> Ob das nun seriell über das Terminal, über das nginx-Log oder
> mittels Wireshark erfolgt - irgendwas davon wird ihn sicher weiter
> bringen, als alle Diskussionen über den korrekten Aufbau einer Anfrage
> :)

Über den Terminal sieht die Zeichenlängeermittlung und die eigentliche 
GET-Anfrage wie auf dem Bild aus.

Das Wireshark hab ich ausprobiert. Wenn ich das richtig verstanden habe, 
brauche ich dafür WLAN am PC,

was ich nicht habe. Bleibt noch der nginx-log übrig. Da bin ich dran und 
werde berichten.

Das ist echt frustierend. Ich kann den Fehler immernoch nicht richtig 
reproduzieren. An einen Abend geht es nicht, am nächsten Tag 
funktioniert die Übermittlung wieder. Aber auch nur bis ich die 
Schaltung wieder aus- und einschalte.

Joachim S. schrieb:
> Meine C/C++-Kenntnisse sind zugegebenermassen äusserst gering, aber ist
> obiges Code-Fragment wirklich okay so? Ich hätte jetzt instinktiv
> vermutet, dass durch einchar cipsend[] = "AT+CIPSEND="nur 12 Bytes
> reserviert werden (also genau so viele, um den String
> "AT+CIPSEND=" sowie ein abschliessenden 0-Byte zu speichern). Und es
> durch die anschliessenden beiden strcat-Befehle dann zu einer Art
> Pufferüberlauf kommt, bei dem möglicherweise unbeabsichtigt etwas ganz
> anderes überschrieben wird, mit möglicherweise unvorhergesehenen Folgen.

Gute Adleraugen. Danke. Hab eine feste Größe zugewiesen:
char cipsend[15] = "AT+CIPSEND=";

Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Jan L. schrieb:
> Falls es /var/log/nginx noch nicht geben sollte, und du dich vermutlich
> mit Dateirechten nicht recht auskennst :), kannst du einfach auch
> "/tmp/nginx_error.log" nehmen:
> error_log  /tmp/nginx_error.log info;

Ich kann die Datei nicht abspeichern. Was mache ich falsch ?

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, ich hab mir Root-Rechte gegeben und konnte die Datei abspeichern. 
Ein Haken hab ich bei der Sache. Ich hab den ganzen Server neu gestartet 
und die Datei wurde dann anscheinend neu geschrieben.
In welcher Datei dann ich das den reinschreiben was auch dann beim 
neustart erhalten bleibt ?

Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Schwere Geburt, ich habs aber hinbekommen eine error_log zu schreiben.
Ich weiß nur nicht genau was Sie zu bedeuten habe. Kann jemand helfen ?

: Bearbeitet durch User
Autor: Jan L. (ranzcopter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...ein GET, HEAD oder PUT fehlt, der Request enthält nur eine URL...

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan L. schrieb:
> ...ein GET, HEAD oder PUT fehlt, der Request enthält nur eine URL...

Na gut da hätte ich auch drauf kommen können. Ich dachte das "GET" wird 
wie die Zeilenumbrüche einfach nur nicht mit angezeigt.

Mittlerweile funktioniert es auch wieder, wenn ich zum einen die 
Funktion "TCP_Laenge" durch einen festen String ersetzte und zum anderen 
die Zählung der Länge anpasse. Mir ist echt schleierhaft, wie es dann 
vorher funktionieren konnte. Vielleicht hab ich etwas rausgelöscht ohne 
es zu merken. Naja aufjedenfall liegt es an der Zusammensetztung inkl. 
Längenermittlung.

In der Funktion zählt er immer 97 Bytes. Ich hab mit den Werten die er 
immer sendet die Zeichen gezählt und bin auf 102 gekommen, siehe unten. 
Selbst wenn ich das fehlende "GET " lösche komme ich nicht auf 97. Dabei 
habe ich immer "\r\n" als 2 Zeichen gezählt. Im kompletten String sind 
das dann 108-6.

So geht's:
putString("AT+CIPSEND=102\r\n");
putString("GET /esp8266/haawrite.php?b0=8&b1=50&b2=0&b3=0&b4=0&b5=17&b6=80&b7=0 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n")

Wenn jemand Lust hat, kann mir nen Tipp geben was an der 
zusammensetztung verkehrt ist.

Gruss und danke Männer.

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
> Joachim S. schrieb:
>> zusätzlich einfach noch ein "Connection:
>> close"-Header-Feld mit einfügst.
>
> Ist das nicht hiermit schon geschehen ?

Nein. Der Befehl AT+CIPCLOSE weist den ESP an die TCP-Verbindung zu 
schließen. Wenn du deiner Anfrage aber noch ein "Connection: close" 
hinzufügst, so teilst du dem Server mit, dass dieser die Verbindung 
schließen soll, wenn die Antwort versendet wurde. Der Header ist dabei 
ein Teil des HTTP-Protokolls, welches über dem TCP-Protokoll liegt.

P. F. schrieb:
> A.. P. schrieb:
>> Ich würde aber an Stelle des TO doch einfach als ersten Ansatz einen
>> korrekten Content-Length Header setzen, um ein eventuelles Problem mit
>> dem Request-Body - welcher ja leer ist - auszuschließen.
>
> Das verstehe ich nicht ganz. Wie kann ich das realisieren ?

Genauso, wie du es doch schon mit dem Host Header gemacht hast. Einfach 
eine zusätzliche Zeile einfügen und die Content-Length angeben.

P. F. schrieb:
> Stefan U. schrieb:
>> Weil er weder den Content-Length Header noch den Chunked-Transfer
>> verwendet hat. Habe ich doch oben geschrieben. Ohne das kann er keinen
>> 2. Request senden.
>
> Ich verstehe nur Bahnhof :-(

Vielleicht solltest du dir nochmal ansehen, wie HTTP grundlegend 
funktioniert bzw. was so die wichtigsten Header sind. Das solltest du 
schon wissen, wenn du versuchst, selbstgestrickte Anfragen an deinen 
Server zu senden.

Gruß

: Bearbeitet durch User
Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
> Gute Adleraugen. Danke. Hab eine feste Größe zugewiesen:char cipsend[15]
> = "AT+CIPSEND=";

Das reicht aber immer noch nicht. Für den String "AT+CIPSEND=" (11 
Zeichen), eine dreistellige Zahl, das abschließende CRLF und das 
Null-Byte brauchst du 17 Zeichen Platz.

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wartest du nach dem "AT+CIPSEND" Befehl eigentlich, bis der ESP die 
Eingabeaufforderung ">" für die Daten zurück gibt?

Wenn nicht ist kein Wunder, daß die Übertragung unvollständig ist.

Offensichtlich wartest du nicht, aber wer weiß wie der aktuelle 
Quelltext inzwischen aussieht.

: Bearbeitet durch User
Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan U. schrieb:
> Wartest du nach dem "AT+CIPSEND" Befehl eigentlich, bis der ESP die
> Eingabeaufforderung ">" für die Daten zurück gibt?

Mir ist auch schon aufgefallen, dass im obigen Code-Auszug das ">" 
nirgends auftaucht.

Stefan U. schrieb:
> Wenn nicht ist kein Wunder, daß die Übertragung unvollständig ist.

Das würde dann aber nicht zum Fehlerbild passen. Ich weiß gerade nicht 
genau, wie sich der ESP verhält, wenn er noch auf fehlende Zeichen 
wartet, aber ich glaube, dass er dann ewig wartet. Und weil er ewig 
wartet, werden die Daten gar nicht erst verschickt und es kommt erst gar 
keine Anfrage an den Server zustande. Und wo keine Anfrage kommt, kann 
ja auch kein Server antworten (die Antwort könnte ja sowieso nicht 
empfangen werden, da der ESP ja noch auf Zeichen wartet ;) )

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An den TO:

Woran lag's denn nun? Hat sich zwischenzeitlich was an deinem Problem 
getan? Wäre super, wenn du mit der Gemeinschaft auch deine Erfahrungen 
und Lösungen teilen würdest, damit auch andere davon profitieren können.

Gruß

Autor: P. F. (pfuhsy)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
A.. P. schrieb:
> "Connection: close"
Sende ich das in der nächsten Schleife, kommt nur "Error" zurück. Das 
ist aber das Error vom ESP8266 und nicht vom Server, Bild 1.
case 2:
//TCP_Senden();      //Eigentliche Daten senden
putString("GET /esp8266/haawrite.php?b0=8&b1=50&b2=0&b3=0&b4=0&b5=17&b6=80&b7=0 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n");
//putString("Connection: close\r\n"); 
_ESP_Timeout_s = 0;    //Timeout-Zeit zurücksetzten
_ESP_Busy = true;    //Flag ESP ist beschäftigt      
break;

case 3:
ESP_Query("Connection: close\r\n", "OK");  //Verbindung schliessen
break;                


Wenn ich den das direkt hinter dem Request sende, kommt ein "busy s..." 
Bild 2, übernimmt aber die Daten:
case 2:
//TCP_Senden();      //Eigentliche Daten senden
putString("GET /esp8266/haawrite.php?b0=8&b1=50&b2=0&b3=0&b4=0&b5=17&b6=80&b7=0 HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n");
putString("Connection: close\r\n"); 
_ESP_Timeout_s = 0;    //Timeout-Zeit zurücksetzten
_ESP_Busy = true;    //Flag ESP ist beschäftigt            
break;

So eine ähliche Anfrage hatte ich in einen Youtube-Video schonmal 
gesehen (Youtube-Video "ESP 8266 Part 2: ESP8266 GET Request using Arduino IDE"), jedoch 
funktioniert das "Connenction: close" bei mir an der selben Stelle nicht 
so richtig.

A.. P. schrieb:
> Vielleicht solltest du dir nochmal ansehen, wie HTTP grundlegend
> funktioniert bzw. was so die wichtigsten Header sind. Das solltest du
> schon wissen, wenn du versuchst, selbstgestrickte Anfragen an deinen
> Server zu senden.

Ja, ich werde mich mal einlesen.

A.. P. schrieb:
> Das reicht aber immer noch nicht. Für den String "AT+CIPSEND=" (11
> Zeichen), eine dreistellige Zahl, das abschließende CRLF und das
> Null-Byte brauchst du 17 Zeichen Platz.

Danke. Geändert.

Stefan U. schrieb:
> Wartest du nach dem "AT+CIPSEND" Befehl eigentlich, bis der ESP die
> Eingabeaufforderung ">" für die Daten zurück gibt?

Ne, ich such nach einem "OK". Danke für den Tip, werde ich mit 
einpflegen.

A.. P. schrieb:
> Woran lag's denn nun? Hat sich zwischenzeitlich was an deinem Problem
> getan? Wäre super, wenn du mit der Gemeinschaft auch deine Erfahrungen
> und Lösungen teilen würdest, damit auch andere davon profitieren können.

Wie schon ober geschrieben, klappt es ja jetzt nachdem ich den 
zusammengesetzten Request durch einen festen String ersetzt habe, weil 
dort anscheinend laut Server das "GET " gefehlt hat. Ich hatte mir den 
zusammengesetzten String ausgeben lassen, doch der war vollstädig. Warum 
die Zusammensetztung nicht geklappt hat und warum die dazu gehörige 
Ausgabe trotzdem richtig aussah, hab ich noch nicht feststellen können, 
dafür brauche ich noch etwas Zeit. Jetzt läuft es erstmal wieder und die 
nächsten Schritte wären, den Code aus Euren Hinweißen zu verbessern und 
die Zusammensetztung der Anfrage nochmal Schritt für Schritt neu 
aufzubauen. Wenn es soweit ist, werde ich natürlich berichten.

Autor: Joachim S. (oyo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
P. F. schrieb:
>
> putString("GET 
> /esp8266/haawrite.php?b0=8&b1=50&b2=0&b3=0&b4=0&b5=17&b6=80&b7=0 
> HTTP/1.1\r\nHost: 192.168.1.100\r\n\r\n");
> putString("Connection: close\r\n");
> 

"Connection: close" gehört in den Header Deines http-Requests und muss 
daher VOR der Zeichenfolge "\r\n\r\n" gesendet werden.
Schon aus diesem Grund würde ich übrigens empfehlen, in Deinen 
putString-Aufrufen nicht gleich den gesamten Request als langen 
mehrzeiligen String zu senden, sondern für jede Zeile einen eigenen 
Aufruf zu machen. z.B. so:
void putLine(char *line) {
  putString(line);
  putString("\r\n");
}

[...]
putLine("GET /esp8266/haawrite.php?b0=8&b1=50&b2=0&b3=0&b4=0&b5=17&b6=80&b7=0 HTTP/1.1");
putLine("Host: 192.168.1.100");
putLine("Connection: close");
putLine("");
[...]
Mittlerweile glaube ich allerdings nicht mehr, dass das Problem 
überhaupt mit dem "Connection: close" zusammenhängt. Ich tippe derzeit 
eher auf irgendwelche versehentlichen Pufferüberläufe - der ganze Code 
erscheint mir ehrlich gesagt ein wenig umständlich und fehleranfällig... 
:(

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joachim S. schrieb:
> void putLine(char *line) {
>   putString(line);
>   putString("\r\n");
> }

Ich hab es ausgetestet. Es macht kein Unterschied zu meinen Request von 
oben: "Wenn ich den das direkt hinter dem Request sende, kommt ein "busy 
s..."
Bild 2, übernimmt aber die Daten:"

Joachim S. schrieb:
> Mittlerweile glaube ich allerdings nicht mehr, dass das Problem
> überhaupt mit dem "Connection: close" zusammenhängt. Ich tippe derzeit
> eher auf irgendwelche versehentlichen Pufferüberläufe - der ganze Code
> erscheint mir ehrlich gesagt ein wenig umständlich und fehleranfällig...
> :(

Recht hast du. Es ist gerade die v1.0 welche stetig verbessert wird. 
Natürlich versuche ich schon da den Code so gut wie möglich zu 
gestalten, jedoch sollen die hauptsächlichen Dinge, wie erfolgreiches 
Senden der Daten, funktionieren. In der Zeit hänge ich die Schaltung an 
meine Alarmanlage während der Code damit getestet und verbessert werden 
soll. Ich bin eigentlich ganz froh, wenn jemand einen Fehler entdeckt 
während ich den Wald vor lauter Bäumen nicht sehe.

Autor: P. F. (pfuhsy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

nach stundenlanger suche bin ich jetzt doch fündig geworden. Ich habe 
ein Array für empfangene UART-Daten "_uart_string[50]". Anscheindend war 
der reserierte Speicherplatz nicht ausreichend und ist beim überlauf auf 
den Speicherbreich der Variable des zusammengesetzten GET-Request 
gefallen. Dabei wurde mal die erste 4 Zeichen "GET " überschrieben und 
mal wieder nicht, was die Fehlersuche deutlich erschwert hat. Ich hatte 
zwar ein Überlaufschutz eingebaut, nur leider war der fehlerhaft:
ISR (USART_RXC_vect)    //Interrupt wird ausgelöst sobald neue Daten im USART-Empfangspuffer liegen
{
  volatile static uint8_t count = 0;    //Char-Zähler
  
  //String ist noch nicht komplett
  if (!_uart_str_complete)
  {
    if(UDR != '\n' && count < 50)    //kein Abschlusszeichen vorhanden oder Arraylänge erreicht TODO Länge selbst ermitteln
    {
      _uart_string[count] = UDR;        //in Array schreiben
      count++;                //Array-Zähler inkrementieren
    }
    else
    {
      _uart_string[count]='\0';        //String abschliessen
      count = 0;                //Zähler zurücksetzten
      _uart_str_complete = true;        //String komplett
    }
  }    
  
}

Jetzt sieht er besser aus und der Fehler ist bis jetzt nicht mehr 
aufgetaucht:
ISR (USART_RXC_vect)    //Interrupt wird ausgelöst sobald neue Daten im USART-Empfangspuffer liegen
{
  volatile static uint8_t count = 0;    //Char-Zähler
  
  //String ist noch nicht komplett
  if (!_uart_str_complete)
  {
    //kein Abschlusszeichen vorhanden
    if(UDR != '\n')    
    {
      _uart_string[count] = UDR;        //in Array schreiben
      count++;                //Array-Zähler inkrementieren
    }
    else
    {
      _uart_string[count]='\0';        //String abschliessen
      count = 0;                //Zähler zurücksetzten
      _uart_str_complete = true;        //String komplett
    }
    
    //Arraylänge erreicht
    if (count >= sizeof(_uart_string) - 1)    
    {
      count = 0;                //Zähler zurücksetzten
    }
  }    
  
}

Autor: Stefanus F. (stefanus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Danke für die Rückmeldung. So können andere noch was daraus lernen.

Autor: A.. Punkt (arnonym)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Und bei diesem Beispiel zeigt sich wieder, dass es nur hilfreich ist, 
den gesamten Code zu posten und nicht nur Teile, von denen man selbst 
"denkt", dass da der Fehler drin steckt. Wie nun deutlich zu erkennen 
war, haben alle Beteiligten die ganze Zeit an der falschen Stelle 
gesucht und die wildesten Annahmen getroffen, ohne zu wissen, dass 
irgendwo in diesem Spaghetti-Code noch die ominöse Variable 
"_uart_string" auf eigenartige Weise zusammengesetzt wird -_-

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.