Authentification web et GET

Bonjour à tous?

Je rencontre un problème de traitement de ma commande GET, celle-ci est bien lu mais n'est pas traité, auriez vous une idée ?

Elle est bien reçu mais n'est pas traité ! (moniteur série ce dessous)

en vous remerciant par avance pour vos contribution.

#include <SPI.h>
#include <Ethernet.h>

// Entrez une adresse MAC et une adresse IP pour votre contrôleur ci-dessous.
// L'adresse IP est :
byte mac[] = { 
  0xDE, 0xAD, 0xAF, 0xBA, 0xEE, 0xDF };
IPAddress ip(192,168,0,200);
String readString;

// Initialiser la bibliothèque du serveur Ethernet
// avec l'adresse IP et le port que vous souhaitez utiliser
EthernetServer server(2856);

void setup() {
  Serial.begin(9600);

  // démarrez la connexion Ethernet et le serveur :
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  pinMode(7, OUTPUT); digitalWrite(7, HIGH);

}
 

char linebuf[100];
int charcount=0;
boolean authentificated=false;

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Nouvelle connexion client");
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;
    authentificated=false;   // authentifié = faux
    // une requête http se termine par une ligne vide
    boolean currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
    while (client.connected()) {   // boucle infini -> tant que le client et connecté
      if (client.available()) {    // et queleclient est disponible
        char c = client.read();   
        linebuf[charcount]=c;

        
        if (charcount<sizeof(linebuf)) charcount++;
        Serial.write(c);
        
        // si vous êtes arrivé à la fin de la ligne (reçu un saut de ligne
        // caractère) et la ligne est vide, la requête http est terminée,
        // vous pouvez donc envoyer une réponse
        if (c == '\n' && currentLineIsBlank) {
          if (authentificated)
            SendOKpage(client);
          else
            SendAuthentificationpage(client);  
          break;
        }
        
        if (c == '\n') {
          // tu commences une nouvelle ligne
          currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
          if (strstr(linebuf,"Authorization: Basic")>0 && strstr(linebuf,"dGVzdDpUZXN0")>0) // Encryptage "ident:pass" via https://www.base64encode.org/  {forme ident:pas}
            authentificated=true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;
          
         if (strstr(linebuf,"/?lumon") >0){
          memset(linebuf,0,sizeof(linebuf));
          digitalWrite(7, LOW);
             }

         if (strstr(linebuf,"/?lumoff") >0){
          memset(linebuf,0,sizeof(linebuf));
          digitalWrite(7, HIGH);
             }

        } 
        else if (c != '\r') {
          // vous avez un caractère sur la ligne actuelle
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
   
    Serial.println("client disonnected");
    Serial.println(F(""));

  }
}

void SendOKpage(EthernetClient &client)
{
          // envoyer un en-tête de réponse http standard
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println(F("<style> #Bouton_1{background-color:red; width:150px; height:100px;} #Bouton_2{width:150px; height:100px; font size:9; } #Bouton_3{background-color:#ED2FD7;}</style>"));
          
          client.println(F("<br />"));
          client.println(F("<a href=\"/?lumon\"\"><input type=button value=ON id='Bouton_2' ></a>"));
          client.println(F("<a href=\"/?lumoff\"\"><input type=button value=OFF id='Bouton_2' ></a>"));
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.print(F("Etat de l'Eclairage : "));
          if(digitalRead(7) == HIGH){
            client.println(F("<font color=#9E9F6C>"));
            client.print(F(" ETEINT"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          if(digitalRead(7) == LOW){
            client.println(F("<font color=#F6FA04>"));
            client.print(F(" ALLUME"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          client.println(F("<br />"));

          client.println("</html>");
}

void SendAuthentificationpage(EthernetClient &client)
{
          client.println("HTTP/1.1 401 Authorization Required");
         
          client.println("WWW-Authenticate: Basic realm=\"Secure Area\"");
           
          client.println("Content-Type: text/html");
          
          client.println("Connnection: close");
          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println();
          client.println("<!DOCTYPE HTML>");
          
          client.println("<HTML>  <HEAD>   <TITLE>Error</TITLE>");
          client.println(" </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>");
}

voici les retour du moniteur serie :

09:40:20.400 -> Nouvelle connexion client
09:40:20.434 -> GET /?lumon HTTP/1.1
09:40:20.468 -> Host: 192.168.0.200:2856
09:40:20.501 -> Connection: keep-alive
09:40:20.501 -> Authorization: Basic dGVzdDpUZXN0
09:40:20.569 -> Upgrade-Insecure-Requests: 1
09:40:20.569 -> User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
09:40:20.705 -> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
09:40:20.875 -> Referer: http://192.168.0.200:2856/?lumoff
09:40:20.910 -> Accept-Encoding: gzip, deflate
09:40:20.945 -> Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
09:40:20.979 ->
09:40:21.050 -> client disonnected
09:40:21.084 ->
09:40:21.422 -> Nouvelle connexion client
09:40:21.456 -> GET /favicon.ico HTTP/1.1
09:40:21.456 -> Host: 192.168.0.200:2856
09:40:21.489 -> Connection: keep-alive
09:40:21.523 -> Authorization: Basic dGVzdDpUZXN0
09:40:21.557 -> User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
09:40:21.692 -> Accept: image/avif,image/webp,image/apng,image/svg+xml,image/,/*;q=0.8
09:40:21.761 -> Referer: http://192.168.0.200:2856/?lumon
09:40:21.796 -> Accept-Encoding: gzip, deflate
09:40:21.830 -> Accept-Language: fr-FR,fr;q=0.9,en-US;q=0.8,en;q=0.7
09:40:21.899 ->
09:40:21.967 -> client disonnected
09:40:21.967 ->

A mon avis, tous les traitements devraient être réalisés sous cette ligne.
On peut en particulier afficher la requête reçue, ce qui aiderait certainement.

Pas très classique comme URL. Tel que c'est écrit la requête est : /, et les paramètres lumon et lumoff. Or une URL devrait être écrite sous la forme suivante :
/?param1=valeur&param2=valeur
Donc :

/?lum=ON
/?lum=OFF

Serait plus normal.

Bonjour hbachetti,

Je vais tester ça ce soir et te fait un retour.

Encore merci.

J'ai donc remis les lignes au niveau de l'état identifié

le problème reste le même pas de traitement de la commande GET.

Voila comment je l'ai écrit :

if (c == '\n' && currentLineIsBlank) {
          if (authentificated){
            SendOKpage(client);
              Serial.println(F("bien identifie"));
            if (strstr(linebuf,"/?lum=on") >0){
              Serial.println(F("On allume la led"));
                   digitalWrite(7, LOW);
                    }

             if (strstr(linebuf,"/?lum=off") >0){
              Serial.println(F("On eteint la led"));
                  digitalWrite(7, HIGH);
                    }
          }
          else
            SendAuthentificationpage(client);  
          break;
        }

j'en ai profité pour corriger mes URL de maniére à être plus propre.

Sans description de ce qui se passe réellement, que dire ?
Que dit la sortie du moniteur série ?

je remet le code au complet ainsi que le retour sur le moniteur série:

#include <SPI.h>
#include <Ethernet.h>

// Entrez une adresse MAC et une adresse IP pour votre contrôleur ci-dessous.
// L'adresse IP est :
byte mac[] = { 
  0xDE, 0xAD, 0xAF, 0xBA, 0xEE, 0xDF };
IPAddress ip(192,168,0,200);
String readString;

// Initialiser la bibliothèque du serveur Ethernet
// avec l'adresse IP et le port que vous souhaitez utiliser
EthernetServer server(2856);

void setup() {
  Serial.begin(9600);

  // démarrez la connexion Ethernet et le serveur :
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  pinMode(7, OUTPUT); digitalWrite(7, HIGH);

}
 

char linebuf[100];
int charcount=0;
boolean authentificated=false;

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Nouvelle connexion client");
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;

    authentificated=false;   // authentifié = faux
    // une requête http se termine par une ligne vide
    boolean currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
    while (client.connected()) {    // boucle infini -> tant que le client et connecté
        if (client.available()) {    // et queleclient est disponible
        char c = client.read();
           linebuf[charcount]=c;
        if (charcount<sizeof(linebuf)) charcount++;
        
        Serial.write(c);
              
        // si vous êtes arrivé à la fin de la ligne (reçu un saut de ligne
        // caractère) et la ligne est vide, la requête http est terminée,
        // vous pouvez donc envoyer une réponse
        if (c == '\n' && currentLineIsBlank) {
          if (authentificated){
            SendOKpage(client);
              Serial.println(F("bien identifié"));
            if (strstr(linebuf,"/?lum=on") >0){
              Serial.println(F("On allume la led"));
                   digitalWrite(7, LOW);
                    }

             if (strstr(linebuf,"/?lum=off") >0){
              Serial.println(F("On eteint la led"));
                  digitalWrite(7, HIGH);
                    }
          }
          else
            SendAuthentificationpage(client);
          break;
        }
        
        if (c == '\n') {
          // tu commences une nouvelle ligne
          currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
          if (strstr(linebuf,"Authorization: Basic")>0 && strstr(linebuf,"dGVzdDpUZXN0")>0) // Encryptage "ident:pass" via https://www.base64encode.org/  {forme ident:pas}
            Serial.println(F("On verifie le id et pass"));
            authentificated=true;
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;

        } 
        else if (c != '\r') {
          // vous avez un caractère sur la ligne actuelle
          currentLineIsBlank = false;
        //  Serial.println(F("arrivée de nouvelle donnee"));
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
   
    Serial.println("client disonnected");
    Serial.println(F(""));

  }
}

void SendOKpage(EthernetClient &client)
{
          // envoyer un en-tête de réponse http standard
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println(F("<style> #Bouton_1{background-color:red; width:150px; height:100px;} #Bouton_2{width:150px; height:100px; font size:9; } #Bouton_3{background-color:#ED2FD7;}</style>"));
          
          client.println(F("<br />"));
          client.println(F("<a href=\"/?lum=on\"\"><input type=button value=ON id='Bouton_2' ></a>"));
          client.println(F("<a href=\"/?lum=off\"\"><input type=button value=OFF id='Bouton_2' ></a>"));
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.print(F("Etat de l'Eclairage : "));
          if(digitalRead(7) == HIGH){
            client.println(F("<font color=#9E9F6C>"));
            client.print(F(" ETEINT"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          if(digitalRead(7) == LOW){
            client.println(F("<font color=#F6FA04>"));
            client.print(F(" ALLUME"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          client.println(F("<br />"));

          client.println("</html>");
}

void SendAuthentificationpage(EthernetClient &client)
{
          client.println("HTTP/1.1 401 Authorization Required");
         
          client.println("WWW-Authenticate: Basic realm=\"Secure Area\"");
           
          client.println("Content-Type: text/html");
          
          client.println("Connnection: close");
          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println();
          client.println("<!DOCTYPE HTML>");
          
          client.println("<HTML>  <HEAD>   <TITLE>Error</TITLE>");
          client.println(" </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>");
}

Le moniteur série reçoit bien l'URL mais la commande n'est pas traité, il ne rentre pas dans la boucle IF de l'allumage de la led et de plus la commande GET de ma page web ne vide pas la chaine de caractères en réponse, pour moi l'URL devrais redevenir :
http://192.168.0.200:2856/

or elle reste http://192.168.0.200:2856/?lum=on

moniteur série:

18:09:40.729 -> Nouvelle connexion client
18:09:40.764 -> GET /?lum=on HTTP/1.1
18:09:40.798 -> Host: 192.168.0.200:2856
18:09:40.833 -> Connection: keep-alive
18:09:40.833 -> Authorization: Basic dGVzdDpUZXN0
18:09:40.866 -> On verifie le id et pass
18:09:40.900 -> Upgrade-Insecure-Requests: 1
18:09:40.934 -> User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
18:09:41.071 -> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,/;q=0.8,application/signed-exchange;v=b3;q=0.9
18:09:41.207 -> Referer: http://192.168.0.200:2856/?lum=on
18:09:41.274 -> Accept-Encoding: gzip, deflate
18:09:41.309 -> Accept-Language: fr-FR,fr;q=0.9
18:09:41.309 ->
18:09:41.378 -> bien identifié
18:09:41.411 -> client disonnected
18:09:41.411 ->
18:09:41.411 -> Nouvelle connexion client
18:09:41.446 -> GET /favicon.ico HTTP/1.1
18:09:41.480 -> Host: 192.168.0.200:2856
18:09:41.514 -> Connection: keep-alive
18:09:41.549 -> Authorization: Basic dGVzdDpUZXN0
18:09:41.582 -> On verifie le id et pass
18:09:41.582 -> User-Agent: Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
18:09:41.720 -> Accept: image/avif,image/webp,image/apng,image/svg+xml,image/,/*;q=0.8
18:09:41.786 -> Referer: http://192.168.0.200:2856/?lum=on
18:09:41.855 -> Accept-Encoding: gzip, deflate
18:09:41.888 -> Accept-Language: fr-FR,fr;q=0.9
18:09:41.922 ->
18:09:41.958 -> bien identifié
18:09:41.991 -> client disonnected
18:09:42.025 ->

Pourquoi mettre les données reçues à blanc à la réception de '\n' ? ? ?

Cela devrait être fait à un seul endroit :

Et tous les traitements, y compris autorisation, devraient être faits après cette ligne :

        if (c == '\n' && currentLineIsBlank) {

Et on renvoie la page HTML en réponse à partir du moment où la requête a été exécutée, et pas le contraire.
Chacun fait comme il veut, mais ce n'est qu'une question de convention.

Bonjour hbachetti,

Je fini par me mélanger et je n'y vois plus clair !!

Aurais tu la bienveillance de me produire un exemple de cette séquence car je n'arrive plus à revoir cette logique à force de reprendre.

Le problème c'est que quand j'affiche le chaîne elle est pourtant complète a l'envers de ce que tu me propose :upside_down_face::upside_down_face::upside_down_face:.

Si tu l'affiches juste avant cette ligne :

if (strstr(linebuf,"/?lum=on") >0){

Cela m'étonnerait qu'elle ne soit pas vide, étant donné qu'elle est remise à zéro à la réception du premier '\n'.

        if (c == '\n' && currentLineIsBlank) {
          // vérifier autorisation 
          // si autorisation OK
            // exécuter la commande : LEDs
            // renvoyer la page HTML
          // si autorisation NON OK
            // renvoyer la page HTML Authorization Required
        }
        if (c == '\n') {
          // ici on ne fait rien
          currentLineIsBlank = true;
        } else if (c != '\r') {
          currentLineIsBlank = false;
        }

Alors j'ai donc modifier le code et repris la séquence et j'ai des résultat positif mais je rencontre encore des difficultés:

le GET ON est bien exécuté la LEDs s'allume et le statut est pris en compte, par contre j'ai toujours mon URL qui garde le commande GET : http://192.168.0.200:9623/?lum=on.

Or elle devrais se remettre : http://192.168.0.200:9623

Ensuite quand j'appui sur OFF le commande GET est exécuté la LED s'éteint mais le statut d'affichage n'est pas actualisé et j'ai toujours http://192.168.0.200:9623/?lum=off.

comment creer un timout sur la durée de validité de l'identification car je ne retrouve plus ma demande d'identification
et au final l'identification ne fonctionne plus elle est valide en permanence !!

voici le code

#include <SPI.h>
#include <Ethernet.h>

// Entrez une adresse MAC et une adresse IP pour votre contrôleur ci-dessous.
// L'adresse IP est :
byte mac[] = { 
  0xDE, 0xAD, 0xAF, 0xBA, 0xEE, 0xDF };
IPAddress ip(192,168,0,200);
String readString;

// Initialiser la bibliothèque du serveur Ethernet
// avec l'adresse IP et le port que vous souhaitez utiliser
EthernetServer server(9623);

void setup() {
  Serial.begin(115200);

  // démarrez la connexion Ethernet et le serveur :
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());

  pinMode(7, OUTPUT); digitalWrite(7, HIGH);

}
 

char linebuf[100];
int charcount=0;
boolean authentificated=false;

void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Nouvelle connexion client");
    memset(linebuf,0,sizeof(linebuf));
    charcount=0;

    authentificated=false;   // authentifié = faux
    // une requête http se termine par une ligne vide
    boolean currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
    while (client.connected()) {    // boucle infini -> tant que le client et connecté
        if (client.available()) {    // et queleclient est disponible
        char c = client.read();
  
           linebuf[charcount]=c;
       
        if (charcount<sizeof(linebuf)) charcount++;
        Serial.write(c);
            
        // si vous êtes arrivé à la fin de la ligne (reçu un saut de ligne
        // caractère) et la ligne est vide, la requête http est terminée,
        // vous pouvez donc envoyer une réponse
        if (c == '\n' && currentLineIsBlank) {
          
          if (authentificated){
           
            SendOKpage(client);

          }
          else
            SendAuthentificationpage(client);
          break;
        }
        
        if (c == '\n') {
          // tu commences une nouvelle ligne
          currentLineIsBlank = true;    //la ligne actuelle est vide = vrai
          
          if (strstr(linebuf,"Authorization: Basic")>0 && strstr(linebuf,"dGVzdDpUZXN0")>0) // Encryptage "ident:pass" via https://www.base64encode.org/  {forme ident:pas}
            Serial.println(F("On verifie le id et pass"));
            authentificated=true;

         if (strstr(linebuf,"/?lum=on") >0){
              Serial.println(F("On allume la led"));
                   digitalWrite(7, LOW);
                  
                    }

             if (strstr(linebuf,"/?lum=off") >0){
              Serial.println(F("On eteint la led"));
                  digitalWrite(7, HIGH);
                  
                    }
          memset(linebuf,0,sizeof(linebuf));
          charcount=0;

        } 
        else if (c != '\r') {
          // vous avez un caractère sur la ligne actuelle
          currentLineIsBlank = false;
        //  Serial.println(F("arrivée de nouvelle donnee"));
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
   
    Serial.println("client disonnected");
    Serial.println(F(""));

  }
}

void SendOKpage(EthernetClient &client)
{
          // envoyer un en-tête de réponse http standard
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");

          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println(F("<style> #Bouton_1{background-color:red; width:150px; height:100px;} #Bouton_2{width:150px; height:100px; font size:9; } #Bouton_3{background-color:#ED2FD7;}</style>"));
          
          client.println(F("<br />"));
          client.println(F("<a href=\"/?lum=on\"\"><input type=button value=ON id='Bouton_2' ></a>"));
          client.println(F("<a href=\"/?lum=off\"\"><input type=button value=OFF id='Bouton_2' ></a>"));
          client.println(F("<br />"));
          client.println(F("<br />"));
          client.print(F("Etat de l'Eclairage : "));
          if(digitalRead(7) == HIGH){
            client.println(F("<font color=#9E9F6C>"));
            client.print(F(" ETEINT"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          if(digitalRead(7) == LOW){
            client.println(F("<font color=#F6FA04>"));
            client.print(F(" ALLUME"));
            client.println(F("</font>"));
            client.println(F("<br />"));
          }
          client.println(F("<br />"));

          client.println("</html>");
}

void SendAuthentificationpage(EthernetClient &client)
{
          client.println("HTTP/1.1 401 Authorization Required");
         
          client.println("WWW-Authenticate: Basic realm=\"Secure Area\"");
           
          client.println("Content-Type: text/html");
          
          client.println("Connnection: close");
          client.println(F("<body style=\"color: #ffffff; background-color: #0c273d;\">"));
          client.println();
          client.println("<!DOCTYPE HTML>");
          
          client.println("<HTML>  <HEAD>   <TITLE>Error</TITLE>");
          client.println(" </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>");

Je ne comprends pas ce que tu veux-tu dire.

Si tu indentais ton code (CTRL-T) tu verrais un problème d'accolades.

Lorsque que j'appuie sur mon bouton, L'URL transmise est http://192.168.0.200:9623/?lum=on

Mais ce que je ne comprends pas c'est le réponse devrait me retourner L'URL http://192.168.0.200:9623

Or mon URL reste http://192.168.0.200:9623/?lum=on, je n'arrive pas à retourner une URL sans ma commande GET /?lum=on.

Sur une requête http://192.168.0.200:9623/?lum=on le serveur renvoie une réponse, en l'occurrence une page WEB.
Un serveur ne retourne pas une URL comme réponse.

Dans ton code il y a divers problèmes :

char linebuf[100];
Si tu espères recevoir une requête dans 100 caractères, c'est perdu d'avance.
Teste ceci pour t'en convaincre :

        if (charcount < sizeof(linebuf) - 2) {   // moins 2 sinon le '\0' disparaît
          charcount++;
        }
        else {
          Serial.println(F("BUFFER OVERFLOW !!!"));
        }

Si tu fais des traitements ici ils seront répétés pour chaque '\n' rencontré dans la requête. Et il n'y en a pas qu'un ! ! !

strstr() est la manière du pauvre de tester si une URL matche.
Or, dans le header il y a en particulier Referer, qui contient l'URL d'où tu viens.
GET /?lum=on HTTP/1.1
...
Referer: http://192.168.1.210:9623/?lum=on
ou
Referer: http://192.168.1.210:9623/?lum=off
Donc si tu cherches une occurrence de /?lum=on ou /?lum=off à chaque fois que tu rencontres '\n', tu trouves plusieurs occurrences.

Pour analyser correctement une requête tu dois la parser, récupérer l'URL, les arguments, leur valeur. Cela ne se fait pas simplement à l'aide d'une recherche avec strstr().