[Résolu] code HTML non interprété par le navigateur client

Bonjour,

Je suis sous windows 10 avec Yun, port série : COM7

http://oct1.oct2.oct3.oct4/arduino/digital/.../…:5555

J’envoie (pas représenté dans ce code minimaliste) sans problème des infos
depuis un navigateur distant vers mon petit serveur se trouvant
dans le YUN.
Le serveur renvoie sans problème des infos vers
le navigateur (ici on se contente de renvoyer

TOTO

) mais…
le code HTML n’est jamais interprété par le navigateur !!

Je tiens à dire que j’ai fait pas mal de recherches à ce sujet avant de poster
mais je suis très très débutant et ça limite mes possibilités…

Je vous transmets donc ce code très SIMPLE qui ne traite que de la
partie du travail qui ne fonctionne pas :

#include <Bridge.h>

#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;       // le webserver écoute le port 5555 (par défaut)

void setup() 
{

    Serial.begin(9600);

    while(!Serial)
    { }   
    

    Bridge.begin();          
   


    server.noListenOnLocalhost();

    server.begin();

    
      
    Serial.println("Prêt !!");    

}

void loop() 
{

       BridgeClient client = server.accept();

    
       if ( client ) 
       {

                Serial.println("new client");

                String command = client.readStringUntil('/');
                Serial.println(command);
                                  
                client.println("HTTP/1.1 200 OK");
                client.println("Transfer-Encoding: chunked");              
                client.println("Content-Type: text/html; charset=UTF-8");
                client.println("Connection: close");  
                client.println();
                client.println("<!DOCTYPE html>");
                client.println("<html>");                
                client.println("<head><title>Arduino YUN</title></head>");
                client.println("<body><h1>TOTO</h1></body></html>");                   

       }

       // give the web browser time to receive the data
       delay(1);
       // close the connection:
       client.stop();

 
}

J’imagine que c’est une question de cours mais je ne trouve pas…

Merci à tous

Pierregrenoble

Bonjour,

Dans l'entête de votre réponse, dans la ligne :

client.println("Transfer-Encoding: chunked");

vous indiquez au navigateur que vous allez lui envoyer la page en mode : "chunked", c-à-d par morceaux.

Or, dans l'envoi de cette page, vous ne respectez pas la syntaxe du mode "chunked", voir ici
rfc2616#section-3.6.1.

Le plus simple est de renoncer au mode chunked en supprimant la ligne ci dessus et tout devrait rentrer dans l'ordre. La fermeture de la connexion signalera au navigateur que tout a été reçu et qu'il peut interpréter et afficher la page.

Bonne bidouille

MicroQuettas

Bonjour,

Merci pour l'info, mais j'ai l'impression d'avoir tout essayé en matière d'en-tête… et je pense faire une erreur fondamentale ailleurs, mais où ??

Demain matin j'essaie vos suggestions et je vous dirai, mais je désespère un peu de ma capacité à trouver la solution…

Merci :slight_smile:

Pierre Grenoble

virez juste le client.println("Transfer-Encoding: chunked"); et regardez ce que ça dit

Bonjour à tous,

J’ai donc supprimé la ligne…

client.println("Transfer-Encoding: chunked");

sans plus de résultat.

requête : http://ad1.ad2.ad3.ad4/arduino/bonjour/monsieur:5555

Voilà ce qu’affiche un navigateur :

HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Connection: close

Arduino YUN

TOTO

Le CODE SOURCE de la page est exactement ce qui est affiché sans
aucune autre balise supplémentaire.

Retour du Moniteur série :

Prêt !!
new client
bonjour:5555

Rappel du code :

#include <Bridge.h>

#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;       // le webserver écoute le port 5555 (par défaut)

void setup() 
{

    Serial.begin(9600);

    while(!Serial)
    { }   
    

    Bridge.begin();          
   


    server.noListenOnLocalhost();

    server.begin();

    
      
    Serial.println("Prêt !!");    

}

void loop() 
{

       BridgeClient client = server.accept();

    
       if ( client ) 
       {

                Serial.println("new client");

                String command = client.readStringUntil('/');
                Serial.println(command);
                                  
                client.println("HTTP/1.1 200 OK");
                client.println("Content-Type: text/html; charset=UTF-8");
                client.println("Connection: close");  
                client.println();
                client.println("<!DOCTYPE html>");
                client.println("<html>");                
                client.println("<head><title>Arduino YUN</title></head>");
                client.println("<body><h1>TOTO</h1></body></html>");                   

       }

       // give the web browser time to receive the data
       delay(1);
       // close the connection:
       client.stop();

 
}

Merci

Pierre Grenoble

Bonjour,

Il y a autre chose, après :

String command = client.readStringUntil('/');
Serial.println(command);

vous répondez au navigateur avant qu'il n'ait fini d'envoyer sa requête (il y a beaucoup de choses après l'URL dans une requête...).
Une requête se termine par une ligne vide, c'est cela qu'il faut détecter avant de répondre.

Essayez de remplacer les lignes ci-dessus par (sans garantie car je ne connais pas le Yun) :

client.findUntil("\r\n\r\n");
//Serial.println(command);  /* Ne sert plus à rien */

Mieux, inspirez vous du tuto de J-M-L ici : tuto J-M-L en particulier du code de void testRequeteWeb() en début du post #2. Il détecte proprement la fin de la requête.

Bonne bidouille

MicroQuettas

Bonjour,

Merci à MicroQuettas
et à J-M-L pour le tuto, la boucle est bien expliquée.

Toujours sur Arduino Y U N…

J’applique donc ce code qui m’a convaincu.
Pour l’instant , je n’envoie JAMAIS l’entête et la page web
car à la fin du fonctionnement (voir dernières lignes du moniteur série)
la boucle se termine AVANT de lire la séquence \r\n\r\n

C’est à se demander si cette séquence a jamais été envoyée !

Il y a bcp de Serial.println() dans mon code c’est pas indispensable pour vous
ça l’est pour moi:

CODE ARDUINO YUN
--------------------------------------------------------------------------------



#include <Bridge.h>

#include <BridgeServer.h>
#include <BridgeClient.h>

BridgeServer server;  // le webserver écoute le port 5555 (par défaut)




void setup() 
{

       pinMode(11, OUTPUT);
       pinMode(10, OUTPUT);

       Bridge.begin();     
   
       Serial.begin(9600);
  
       while(!Serial)
       { }
  
       server.noListenOnLocalhost();

       server.begin();

       Serial.println("Prêt !!");    

}



void loop() 
{
       testRequeteWeb();
}





void testRequeteWeb()
{

       boolean currentLineIsBlank = true;
       Serial.println("valeur initiale  : currentLineIsBlank == true");   


       BridgeClient client = server.accept();

       if (!client) return; // pas de client connecté

       while (client.connected()) 
       {
               Serial.println("client.connected()");
        
              if (client.available()) 
              {
                     Serial.println("client.available()");
                     // on lit toute la trame HTPP, ici sans se soucier de la requête
                     char c     = client.read();
                     int  ascii = (int)c;

                     Serial.print( "CAR : " );
                     Serial.print( c );
                     Serial.print( "  code ASCII : " );
                     Serial.println( ascii );
                     

                     if (c == '\n' && currentLineIsBlank) 
                     {      // une requête HTTP se termine par une ligne vide
                            // ON GENERE LA PAGE WEB
                            // On envoie un en tête de réponse HTTP standard
                            Serial.println("ENVOI EN-TETE HTTP");
                            
                            client.println( "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" );
                            client.println();                             
                            client.println( "<!DOCTYPE html><html><head></head><body><h1>TOTO</h1></body></html>" );
 
                            // on sort du while et termine la requête
                            break;
                     }                     


                     if ( c == '\n' )
                     {
                            Serial.println("fin de boucle \\n : currentLineIsBlank == true");  
                            currentLineIsBlank = true;
                     }
                     else 
                     {

                            if ( c != '\r' )
                            {                      
                                   Serial.println("fin de boucle    : Ni  \\n  ni  \\r  : currentLineIsBlank == false");                                    
                                   currentLineIsBlank = false;  //on lit un caractère
                            }
                            else
                            {
                                   Serial.println("fin de boucle \\r");                  
  
                            }                            
                     }                     


              } // end if available


       } // end while

       delay(1);
       client.stop(); // termine la connexion

}

REQUETE TAPEE

http://oct1.oct2.oct3.oct4/arduino/bonjour6:5555

VOICI LA SORTIE MONITEUR SERIE CORRESPONDANTE

Prêt !!
valeur initiale  : currentLineIsBlank == true
valeur initiale  : currentLineIsBlank == true
valeur initiale  : currentLineIsBlank == true
 
   etc...
 
valeur initiale  : currentLineIsBlank == true
valeur initiale  : currentLineIsBlank == true
client.connected()
client.available()
CAR : b  code ASCII : 98
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : o  code ASCII : 111
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : n  code ASCII : 110
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : j  code ASCII : 106
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : o  code ASCII : 111
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : u  code ASCII : 117
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : r  code ASCII : 114
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 6  code ASCII : 54
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : :  code ASCII : 58
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 5  code ASCII : 53
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 5  code ASCII : 53
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 5  code ASCII : 53
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 5  code ASCII : 53
fin de boucle    : Ni  \n  ni  \r  : currentLineIsBlank == false
client.connected()
client.available()
CAR : 
  code ASCII : 13
fin de boucle \r
client.connected()
client.available()
CAR : 
  code ASCII : 10
fin de boucle \n : currentLineIsBlank == true
client.connected()
client.connected()
client.connected()
client.connected()
client.connected()
client.connected()
client.connected()
client.connected()

Merci

pierre Grenoble

Bonsoir,

On avance, votre navigateur n'envoie pas de requête HTTP !
Pourquoi ?
Probablement parce que vous n'avez pas bien placé le numéro de port.
Je ne suis pas habitué à utiliser des ports autres que le standard pour le HTTP (80), mais j'ai eu un doute sur votre syntaxe.
D'après la doc que j'ai trouvée (URL sur Wiki), il faut envoyer :

http://oct1.oct2.oct3.oct4:5555/arduino/bonjour6

Bonne bidouille,

MicroQuettas

Bonjour,

Merci MicroQuettas,

Plusieurs jours à m####ouiller là-dessus... heureusement que je fais ça
pour mes loisirs sinon je gagnerais pas mon beurre !

Lamentable ! :frowning:

Une dernière question… comme dirait Columbo… je comprends bien l'instruction client.available()
mais j'ai du mal à piger la différence entre

if (client)
{}

et

while (client.connected())
{}

j'ai pas trouvé des explications précises sur internet...

Merci

Pierre Grenoble

client est « vrai » si un client est prêt (attention ça ne teste pas le pointeur sur votre classe, mais c'est implémenté par surcharge de l'operator bool()

Un client est considéré connecté même si la connexion est close tant qu’il y a des données non lue dans le buffer associé (donc que available() retourne pas 0)

Bonjour,

je ne trouve pas le bouton RESOLU mais c'est résolu et bien résolu

Merci

Pierre

Il n'y a pas de bouton résolu.
Si tu veux marquer ton sujet comme résolu tu ėdites ton premier message et tu modifies le titre en prėfixant par [Résolu ]