-1

I have been learning lower level data reading on internet communication As a part of bigger project I am testing web interface.
So far I could get main website displayed and by seeing the web-address read the data from GET request.
As I intend to send codes I wish to use POST method.
I am Trying to make this as standalone class for mine future projects, so I am only sending the class method itself. (Latter it would take websites content as a string, but for now input variables are yet to be implemented)
I am using esp8266, but would prefer to avoid esp8266 specific libraries as I wish it to eventually run on its realtek equivalent.
The code:

uint8_t Stranky::Stav(String obsahStranky, uint8_t obnovovat){
    WiFiClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    char vstupRiadok[150]={'\0'};
    uint8_t i=0;
    bool currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        vstupRiadok[i]=c;
        if(c=='\n' || i>=149) {
            Serial.println(vstupRiadok);
            //------------Extract variables here--------
            for(uint8_t j=0; j<149; j++) {
                //Serial.print(vstupRiadok[j]);
                vstupRiadok[j]='\0';
            }
            i=0;
        } else i++;
        if (c == '\n' && currentLineIsBlank) {
            Serial.println("Sending page");
            client.println(ohlasSa(1,1));
            client.println("<!DOCTYPE HTML>");
          // send a standard http response header
            client.println("<html><head> <meta charset=\"utf-8\"></head><body>");
            client.println("<h1> Nic nove</h1>");
            client.println("<form method='POST'>");
            client.println("Name:<input type=\"text\" id=\"Name\" name=\"Name\"/><br>\nSurname:<input type=\"text\" id=\"Surname\" name=\"Surname\"><br>\n<input type=\"submit\" value=\"Submit\"/><input   type='reset'/>  </form> </body>");
            client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
    Serial.println("Prehliadač dpojený");
  }
}

This results in Browser code:

<!DOCTYPE HTML>
<html><head> <meta charset="utf-8"></head><body>
<h1> Nic nove</h1>
<form method='POST'>
   Name:<input type="text" id="Name" name="Name"/><br>
   Surname<input type="text" id="Surname" name="Surname"><br>
<input type="submit" value="Submit"/><input type='reset'/>  </form> </body>
</html>

When I send any data over the form it does not get received and only receive these:

WS:ac
:ref 1
WS:av
:ref 2
:ur 2
:rn 469
POST / HTTP/1.1

Host: 192.168.43.209

User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:63.0) Gecko/20100101 Firefox/63.0

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: sk,cs;q=0.8,ru;q=0.6,en;q=0.4,en-US;q=0.2

Accept-Encoding: gzip, deflate

Referer: http://192.168.43.209/

Content-Type: application/x-www-form-urlencoded

Content-Length: 25

Connection: keep-alive

Upgrade-Insecure-Requests: 1



Sending page

  No post, or Cookie variables that I could extract

I am far from home and too short of data to be installing more software like wire-shark over phones network sharing

  • I found that I have to decode a json object, but how do I get it from received data? – Tomas Apr 13 '20 at 3:26
0

Check your definition of

String vstupRiadok

it should not be

String vstupRiadok="                                      "; //80 blanks

I would replace it with a decent sized fixed char anyway

char vstupRiadok[81] = {'\0'};

if you create an empty line or other text do not forget to write the end terminator '\0' and make sure the char array is +1 the size for the longest string totake

As String class is a problem on its own as an Arduino class.
The HTML code generated has a missing

<head> <meta charset    ="utf-8"></head>

error in the dev-tools. Aside from that whats the server code running on the Arduino,its not given. The class creates a html page, but at least in FF75 it tries to call server.ip\odpoved - so there has to be some js or Arduino code to decode this route there are no params attached from the form.

EDITAn extraction routine would look like:

bool currentLineIsBlank = true;
bool currentLineIsGet = true;
uint8_t tCount = 0;
char tBuf[64];
uint8_t n=0;
uint8_t s=0;
char *pch;

Serial.print("Client request: ");

 while (client.connected()) {
  while (client.available()) {
    char c = client.read();

    if (currentLineIsGet && tCount < 63) {
      tBuf[tCount] = c;
      tCount++;
      tBuf[tCount] = 0;
    }

    if (c == '\n' && currentLineIsBlank) {
      Serial.println(tBuf);
      // retrieve the POST data
      Serial.print("POST data: ");
      while (client.available()) Serial.write(client.read());
      Serial.println();

      pch = strtok(tBuf, "?");

      while (pch != NULL) {
        if (strncmp(pch, "Name=", 5) == 0) {
          pch = pch+6;
          char Name [24] = {'\0'};
          while(pch != '&'){
             char Name [n] = pch;
             n++;
           }
          char Name [n+1] = {'\0'};
          Serial.print("Name="); Serial.println(Name);
        }

        if (strncmp(pch, "Surname=", 8) == 0) {
          pch=pch+9;
          char Surname[24] = {'\0'};
          while(pch != '\r') {   // check if your response has that after the content or if its '\0'
             char Surname [s] = pch;
             s++;
           }
          char Surname [s+1] = {'\0'};
          Serial.print("Surname="); Serial.println(Surname);
        }
        pch = strtok(NULL, "& ");
      }
  // here the Sending response part starts

You do not need a JSON parser for this just get the post request

  • Comments are not for extended discussion; this conversation has been moved to chat. – VE7JRO Apr 12 '20 at 22:26
0

Based on codebreakers code I have been able to combine it into working one
The problem was on a fact that communication starts with header variables, then empty line, then body containing the variables
First get the connection: and create base variables

uint8_t Stranky::Stav(){
    WiFiClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    bool currentLineIsBlank = 0;
    bool body=0;             // Helps seeing if this is still header
    bool finished=0;         // To know if to terminate connection
    uint8_t i = 0;           // To prevent iterator from resetting to 0
    char fullLine[81]={'\0'};  // buffer for input character to line
    // char *pch;

    Serial.print("User connected\n");
    while (client.connected()) {
        while (client.available()) {
            bool linEnd=0;          // When to deal with line (print it)

Get one incoming character:

            char c = client.read();

Now deal with new line character first
If the last line was empty That would mean: Header is finished and moving to the body of the incoming data
If not change currentLineIsBlank (until new line gets its first character)

            if(c=='\n') {
                if(currentLineIsBlank) {
                    if(!body) body=1;
                    currentLineIsBlank=0;
                } else {
                    Serial. print("/");
                    currentLineIsBlank=1;
                    linEnd=1;
                }

Now lets deal with any other character then new line:

            } else {
                currentLineIsBlank=0;   //If it has a character then its not empty
                fullLine[i]=c;
                i++;                //Move to the next letter
            }

Make sure that our array doesn't overflow

            if(i>=81) linEnd=1;

Now we know what is happening we can take some action after the buffer line is finished

if we are at the body stage, but we havent "finised" sending code

            if(linEnd){ 
                if(body && !finished) {
                    finished=1;          // Finishing sending page
                    Serial.printf(F("Variables:\n\t"));

Start extracting characters from body of the incoming data.
In a simple form like ours POST variables are on a last line, so we will just keep rewriting the line

                    uint8_t k=0;
                    while (client.available()) {
                        fullLine[k]=client.read();
                        Serial.printf(F("%c"),fullLine[k]);
                        if(k<80) k++;
                        if(fullLine[k]=='\n') {        
                            k=0;
                            Serial.println();
                        }
                    }
                    // Here you can extract variables as shown in codebreakers' answer

Finaly send then websites html code:

                    Serial.print("Sending page\n");
                    client.println(heatheRoutine()); //I have extra routine to inject heather so I do not have to write it every time I write a page
                    client.println("<!DOCTYPE HTML>");
                    // send a standard http response header
                    client.println("<html><head> <meta charset=\"utf-8\"></head><body>");
                    client.println("<h1>Fill the form now !!!</h1>");
                    client.println("<form method='POST'>");
                    client.println("Meno:<input type=\"text\" id=\"Name\" name=\"Name\"/><br>\nPriezvisko:<input type=\"text\" id=\"Surname\" name=\"Surname\"><br>\n<input type=\"submit\" value=\"Submit\"/><input    type='reset'/>  </form> </body>");
                    /*Serial.printf(F("Page source send\n"));*/
                    client.println("</html>\n");
                    break;
                }

If we are not dealing with the body yet:

                currentLineIsBlank=1;
                for(uint8_t j=0; j<i; j++) { //Print the last line
                    Serial.print(fullLine[j]);
                    fullLine[j]='/0';     //restore default values To prevent characters leaking into next line
                }
                Serial.println();
                i=0;    //Since we are on an end of a line we are starting from first position in a buffer
            }
        }

If we have finished what we have wanted we need to get out of communication loop

        if(finished) {
            Serial.printf(F("Ending\n"));
            break;
        }
    }

And close the connection:

    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
    Serial.println("browser disconnected");
  }
}

Complete code:

uint8_t Stranky::Stav(){
    WiFiClient client = server.available();
  if (client) {
    // an http request ends with a blank line
    bool currentLineIsBlank = 0;
    bool body=0;             // Helps seeing if this is still header
    bool finished=0;         // To know if to terminate connection
    uint8_t i = 0;           // To prevent iterator from resetting to 0
    char fullLine[81]={'\0'};  // buffer for input character to line
    // char *pch;

    Serial.print("User connected\n");
    while (client.connected()) {
        while (client.available()) {
            bool linEnd=0;          // When to deal with line (print it)
            char c = client.read();
            if(c=='\n') {
                if(currentLineIsBlank) {
                    if(!body) body=1;
                    currentLineIsBlank=0;
                } else {
                    Serial. print("/");
                    currentLineIsBlank=1;
                    linEnd=1;
                }
            } else {
                currentLineIsBlank=0;   //If it has a character then its not empty
                fullLine[i]=c;
                i++;                //Move to the next letter
            }
            if(i>=81) linEnd=1;
            if(linEnd){ 
                if(body && !finished) {
                    finished=1;          // Finishing sending page
                    Serial.printf(F("Variables:\n\t"));
                    uint8_t k=0;
                    while (client.available()) {
                        riadok[k]=client.read();
                        Serial.printf(F("%c"),riadok[k]);
                        if(k<80) k++;
                        if(riadok[k]=='\n') {
                            k=0;
                            Serial.println();
                        }
                    }
                    // Here you can extract variables as shown in codebreakers' answer


                    Serial.print("Sending page\n");
                    client.println("HTTP/1.1 200 OK\r\n");
                    client.println("Content-Type: text/html\r\n");
                    client.println("Connection: close\r\n");
                    client.println();
                    client.println("<!DOCTYPE HTML>");
                    client.println("<html><head> <meta charset=\"utf-8\"></head><body>");
                    client.println("<h1>Fill the form now !!!</h1>");
                    client.println("<form method='POST'>");
                    client.println("Meno:<input type=\"text\" id=\"Name\" name=\"Name\"/><br>\nPriezvisko:<input type=\"text\" id=\"Surname\" name=\"Surname\"><br>\n<input type=\"submit\" value=\"Submit\"/><input    type='reset'/>  </form> </body>");
                    /*Serial.printf(F("Page source send\n"));*/
                    client.println("</html>\n");
                    break;
                }
                currentLineIsBlank=1;
                for(uint8_t j=0; j<i; j++) { //Print the last line
                    Serial.print(fullLine[j]);
                    fullLine[j]='/0';     //restore default values To prevent characters leaking into next line
                }
                Serial.println();
                i=0;    //Since we are on an end of a line we are starting from first position in a buffer
            }
        }
        if(finished) {
            Serial.printf(F("Ending\n"));
            break;
        }
    }
    // give the web browser time to receive the data
    delay(1);

    // close the connection:
    client.stop();
    Serial.println("browser disconnected");
  }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.