Go Down

Topic: [EtherCard] Envoyer une requete POST (Read 7846 times) previous topic - next topic

timiti29

Bonjour, J'ai fait quelques tests, les voici :

Fenêtre Follow TCP Stream avec une utilisation POST de l'arduino :
Code: [Select]
POST /test/index2.php HTTP/1.0
Host: 192.168.100.22


Accept: */*
Content-Length: 1
Content-Type: application/x-www-form-urlencoded

%HTTP/1.1 200 OK
Date: Tue, 22 Oct 2013 15:30:45 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2.3
Vary: Accept-Encoding
Content-Length: 15
Connection: close
Content-Type: text/html

nothing to show


Puis le contenue de la même fenêtre toujour en POST mais avec un formulaire html sur le PC.
(j'ai bien le résultat attendue sur le navigateur)
Code: [Select]
POST /test/index2.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost/test/index.php
Cookie: __atuvc=2%7C32; fda0c6158220e9c88fb60796995d97d0=nc6un7948pth64r8k3u0m3kq63
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 6

id=422HTTP/1.1 200 OK
Date: Tue, 22 Oct 2013 15:39:23 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2.3
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 27
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

...........LQ.212..x..H....


et avec l'arduino en methode GET :
Code: [Select]
GET /test/index2.php?id=422 HTTP/1.0
Host: 192.168.100.22
Accept: text/html

HTTP/1.1 200 OK
Date: Tue, 22 Oct 2013 15:41:33 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2.3
Vary: Accept-Encoding
Content-Length: 7
Connection: close
Content-Type: text/html

id :422


Le problème doit venir de la librairie non ?

Voici la fonction qui semble géré les requêtes HTTP : (dans le fichier tcpip.cpp)
Code: [Select]
static word www_client_internal_datafill_cb(byte fd) {
  BufferFiller bfill = EtherCard::tcpOffset();
  if (fd==www_fd) {
    if (client_postval == 0) {
      bfill.emit_p(PSTR("GET $F$S HTTP/1.0\r\n"
                        "Host: $F\r\n"
                        "$F\r\n"
                        "\r\n"), client_urlbuf,
                                 client_urlbuf_var,
                                 client_hoststr, client_additionalheaderline);
    } else {
      prog_char* ahl = client_additionalheaderline;
      bfill.emit_p(PSTR("POST $F HTTP/1.0\r\n"
                        "Host: $F\r\n"
                        "$F$S\r\n"
                        "Accept: */*\r\n"
                        "Content-Length: $D\r\n"
                        "Content-Type: application/x-www-form-urlencoded\r\n"
                        "\r\n"
                        "$S"), client_urlbuf,
                                 client_hoststr,
                                 ahl != 0 ? ahl : PSTR(""),
                                 ahl != 0 ? "\r\n" : "",
                                 strlen(client_postval),
                                 client_postval);
    }
  }
  return bfill.position();
}


Merci.
Timiti29

infobarquee

essaye de changer tous les
Quote
HTTP/1.0\r\n"

par
Quote
HTTP/1.1\r\n"


et vire les cookies qui doivent aussi poser soucis
AUCUNE AIDE PAR MP

barbudor

De toute évidence il y a une ligne vide en trop dans le cas de la commande POST qui fait que le serveur interprète cela comme la fin de l'entête et le "Accept" est alors vu comme des data.

Dans le code de la lib, pour le cas du POST, je vois :

Quote

prog_char* ahl = client_additionalheaderline;
bfill.emit_p(PSTR("POST $F HTTP/1.0\r\n"
                       "Host: $F\r\n"
                       "$F$S\r\n"
                       "Accept: */*\r\n"
                       "Content-Length: $D\r\n"
                       "Content-Type: application/x-www-form-urlencoded\r\n"
                       "\r\n"
                       "$S"), client_urlbuf,
                                client_hoststr,
                                ahl != 0 ? ahl : PSTR(""),
                                ahl != 0 ? "\r\n" : "",

                                strlen(client_postval),
                                client_postval);


Donc si client_additionalheaderline est une variable NULL alors la lib insère une ligne vide à cet endroit.

Or tu n'as pas la dernière version car ceci a été corrigé dans le code sous GitHub :
Quote
prog_char* ahl = client_additionalheaderline;
     bfill.emit_p(PSTR("POST $F HTTP/1.0\r\n"
                       "Host: $F\r\n"
                       "$F$S"
                       "Accept: */*\r\n"
                       "Content-Length: $D\r\n"
                       "Content-Type: application/x-www-form-urlencoded\r\n"
                       "\r\n"
                       "$S"), client_urlbuf,
                                client_hoststr,
                                ahl != 0 ? ahl : PSTR(""),
                                ahl != 0 ? "\r\n" : "",
                                strlen(client_postval),
                                client_postval);


Allez, zou. Va faire une tour sur GitHub : https://github.com/jcw/ethercard



timiti29

Je vais essayer, quel cookies ? y'a pas de cookies sur un arduino (je vois pas ou il pourrais les stocker)
J'ai essayer avec HTTP/1.1\r\n" mais sa na fait aucun changement.

Sinon j'ai retélécharger la librairie, je ne voit pas de changement, j'ai donc remodifier manuellement afin d'enlever le \r\n.
J'ai à présent un nothing to show.

Voila le résultat dans Wireshark :

Code: [Select]
POST /test/index2.php HTTP/1.0
Host: 192.168.100.22

Accept: */*
Content-Length: 1
Content-Type: application/x-www-form-urlencoded

%HTTP/1.1 200 OK
Date: Tue, 22 Oct 2013 19:45:48 GMT
Server: Apache/2.2.22 (Ubuntu)
X-Powered-By: PHP/5.4.9-4ubuntu2.3
Vary: Accept-Encoding
Content-Length: 15
Connection: close
Content-Type: text/html

nothing to show

Les variables non pas l'aire d'êtres envoyés.
Merci
Timiti29

barbudor

Je persiste, la version qui est sur GitHub n'a pas le "\r\n" après $F$S

En fait je pense qu'en plus y'a une erreur dans ton code (qui provient peut être d'un mauvais exemple)
Mais le 3eme paramètre additionalheaderline devrait être NULL plutot que PSTR("")

PST("") est non null
Donc
Code: [Select]
   "$F$S"
...
  ahl != 0 ? ahl : PSTR(""),
  ahl != 0 ? "\r\n" : "",


$F$S devient additionalheaderline  suivit de "\r\n" c'est à dire "" suivit de "\r\n" donc une ligne vide

Si additionalheaderline  est null on passe dans le 2eme cas du ? et $F$S devient "" suivit de "" soit rien du tout, même pas un retour à la ligne donc on continue ensuite sur "Accept:"

En résumé :
- Il faut la dernière version de la lib qui utilise $F$S au lieu de $F$S\r\n
- il faut que le 3eme paramètre de httpPost() soit NULL au lieu de PSTR("")

infobarquee

moi je vois un cookie qui se met via ton pc
Quote
Referer: http://localhost/test/index.php
Cookie: __atuvc=2%7C32; fda0c6158220e9c88fb60796995d97d0=nc6un7948pth64r8k3u0m3kq63


barbudor a raison
j'ai lu quelque part qu'un gars avait le même soucis et il avait modifié le
\r\n
en
\n
comme dab, je retrouve plus le lien.
AUCUNE AIDE PAR MP

timiti29

J'ai fait les manip' suivante :

- Il faut la dernière version de la lib qui utilise $F$S au lieu de $F$S\r\n
- il faut que le 3eme paramètre de httpPost() soit NULL au lieu de PSTR("")

mais aucuns changements, toujours le nothing to show

Merci.
Timiti29

barbudor

Bon, ben encore 2 semaines et demi avant que je reçoive mon module  ENC28J60 en provenance de Honk-Kong.

Sinon tu essayes la méthode violente : tu vire la ligne $F$S ainsi que les 2 lignes avec "ahf != 0" comme ca on est sur que ca ne génère plus cette foutu ligne vide.

Et vérifie quand même que tu n'as pas une autre version de la lib EtherCard quelque part dans un autre répertoire
Les répertoires valides sont les répertoires "libraries" situés dans le répertoire principal Arduino ainsi que dans le répertoire personnel Arduino, celui qui est indiqué dans la boite de configuration "PAramètres" de l'IDE.

timiti29

J'ai déjà tout supprimer et re-télécharger Arduino et la librairie EtherCard.

Ensuite, dans la requete envoyer, il y a bien Accept ..... le content-lenght (qui vaut toujours 1)
et il n'y a pas de paramètres.

Il devrais y avoir mes variables tout à la fin mais elles n'y sont pas.

Merci
Timiti29

infobarquee

ca me tracasse cette histoire, je viens de regarder sur github des exemples et je vois une différence, peut être une explication.
pas trop le temps de vérifier si ca fait la même chose, mais ca mérite de reprendre l'exemple comme il est écrit.
comme ca à la louche, je vois 3 solutions :
timeout, mais peu probable
buffer qui ne prend pas les variables du POST
lib qui bug

https://github.com/jcw/ethercard/blob/master/examples/webClient/webClient.ino

Quote
// called when the client request is complete
static void my_callback (byte status, word off, word len) {
  Serial.println(">>>");
  Ethernet::buffer[off+300] = 0;
  Serial.print((const char*) Ethernet::buffer + off);
  Serial.println("...");
}


ton code est comme ceci
Quote
static void response_callback (byte status, word off, word len) {
 
  Serial.print((const char*) Ethernet::buffer + off + 207);
}
AUCUNE AIDE PAR MP

timiti29

le code que tu me demande de modifier, concerne le buffer d'affichage, celui la marche (d'après moi) bien.

après analyse des données http (avec wireshark, fenetre follow TCP stream), les variables non pas l'aire d'être émise.

Je pense donc, que le problème vient de la librairie ou de l'appel de la fonction httpPost (dans mon code)

actuellement j'ai le code suivant :
Code: [Select]
#include <EtherCard.h>

static byte mymac[] = {0xDD,0xDD,0xDD,0x00,0x00,0x01};
char website[] PROGMEM = "192.168.100.22";

boolean x = true;

byte Ethernet::buffer[700];
static uint32_t timer;

static void response_callback (byte status, word off, word len) {
 
  Serial.print((const char*) Ethernet::buffer + off + 207);
}

void setup () {

  Serial.begin(57600);
  Serial.println("Client Demo");
  Serial.println();

  if (!ether.begin(sizeof Ethernet::buffer, mymac, 10))
    Serial.println( "Failed to access Ethernet controller");
else
   Serial.println("Ethernet controller initialized");
Serial.println();

  if (!ether.dhcpSetup())
    Serial.println("Failed to get configuration from DHCP");
  else
    Serial.println("DHCP configuration done");

  ether.printIp("IP Address:\t", ether.myip);
  ether.printIp("Netmask:\t", ether.mymask);
  ether.printIp("Gateway:\t", ether.gwip);
  Serial.println();
 
  ether.hisip[0] = 192;
  ether.hisip[1] = 168;
  ether.hisip[2] = 100;
  ether.hisip[3] = 22;
  ether.printIp("SRV IP:\t", ether.hisip);
  Serial.println("Loop :");
  delay(1000);
}

void loop() {

  ether.packetLoop(ether.packetReceive());
 
  if ((millis() > timer) && x == true) {
    timer = millis() + 5000;
    const char postval[] = "id=422";
    //ether.browseUrl(PSTR("/test/index2.php"), "?id=422", website, response_callback);
    ether.httpPost(PSTR("/test/index2.php"), website, NULL, postval, response_callback);
    x = false;
  }
}


Merci à vous.
Timiti29

barbudor

J'ai pas la carte EtherCard donc je ne peut pas faire tourner ton code telquel.
mais j'ai extrait des bout de la lib et j'ai essayé de simuler, et tout va bien, les headers sont ok et les données de POST sont là.
Donc là je n'ai plus d'idée et je ne voit pas ce que je pourrait faire de plus tant que je n'aurais pas reçu l'EtherCard commandée dimanche.

infobarquee

essaye le code du lien dessous et dis si ca fonctionne, en modifiant pour toi
le PATH
le VARIABLE
le website
http://stackoverflow.com/questions/17791876/sending-post-data-with-arduino-and-enc28j60-ethernet-lan-network-module
si ca fonctionne, je pense savoir pourquoi.
si ca fonctionne pas, je sèche aussi
AUCUNE AIDE PAR MP

timiti29

Je vais essayer sa plus tard, car la je ne suis pas chez moi je reviendrais d'ici lundi

Je vous tient au courant.

Timiti29

timiti29

Bonjour, je viens de rentrée chez moi et je me suis dépêché de tester sa,

J'ai donc tester le code du lien que tu ma donnée, et j'ai dut faire plusieurs modification.
déjà au niveau des define,
ensuite le nom de la variable à modifier, j'ai ajouter le type de contenue à la requête    car sa ne marchait pas
(vous pouvez en déduire que sa marche ... mdr)
j'ai enlever le .csv qui me donnais une belle erreur 404

Donc j'ai le code suivant :
Code: [Select]
#include <EtherCard.h>

// your variable

#define PATH    "test/index2.php"
#define VARIABLE    "456768"

// ethernet interface mac address, must be unique on the LAN
byte mymac[] = { 0xDD,0xDD,0xDD,0x00,0x00,0x01 };

char website[] PROGMEM = "192.168.100.22";

byte Ethernet::buffer[700];
uint32_t timer;
Stash stash;

void setup () {
  Serial.begin(57600);
  Serial.println("\n[webClient]");

  if (ether.begin(sizeof Ethernet::buffer, mymac, 10) == 0)
    Serial.println( "Failed to access Ethernet controller");
  if (!ether.dhcpSetup())
    Serial.println("DHCP failed");

  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip); 
  ether.printIp("DNS: ", ether.dnsip); 

  //if (!ether.dnsLookup(website))
  //  Serial.println("DNS failed");
ether.hisip[0] = 192;
ether.hisip[1] = 168;
ether.hisip[2] = 100;
ether.hisip[3] = 22;
  ether.printIp("SRV: ", ether.hisip);
}

void loop () {
  ether.packetLoop(ether.packetReceive());

  if (millis() > timer) {
    timer = millis() + 10000;

    byte sd = stash.create();
    stash.print("id=");
    stash.print(VARIABLE);
    stash.save();

    // generate the header with payload - note that the stash size is used,
    // and that a "stash descriptor" is passed in as argument using "$H"
    Stash::prepare(PSTR("POST http://$F/$F HTTP/1.0" "\r\n"
                        "Host: $F" "\r\n"
                        "Content-type: application/x-www-form-urlencoded" "\r\n"
                        "Content-Length: $D" "\r\n"
                        "\r\n"
                        "$H"),
            website, PSTR(PATH), website, stash.size(), sd);

    // send the packet - this also releases all stash buffers once done
    ether.tcpSend();
  }
}


j'ai le résultat suivant avec le port série :
Code: [Select]
[webClient]
IP:  192.168.100.100
GW:  192.168.100.22
DNS: 192.168.100.22
SRV: 192.168.100.22


et le résultat avec wireshark :
Code: [Select]
POST http://192.168.100.22/test/index2.php HTTP/1.0
Host: 192.168.100.22
Content-type: application/x-www-form-urlencoded
Content-Length: 9

id=456768[538328668 bytes missing in capture file]HTTP/1.1 200 OK
Date: Mon, 28 Oct 2013 18:01:40 GMT
Server: Apache/2.4.6 (Ubuntu)
X-Powered-By: PHP/5.5.3-1ubuntu2
Content-Length: 10
Connection: close
Content-Type: text/html

id :456768


Déjà on remarque que le code ne permet pas l'affichage du buffer.
Je constate donc d'après l'analyse de wireshark, que le serveur HTTP renvoie bien id=45678

Le problème doit donc ce situé dans la requête de la librairie ?

Merci.
Timiti29

Go Up