Esp32 server - client: i think i must be missing something

hi all

recently i have been putting together an esp32 serve / client project using examples from RNT

to POST data from a client to a server

the two relevant functions are:

for the server:

void loop(){
  WiFiClient client = server.available();   // Listen for incoming clients
  if (client)                    // If a new client connects,
  {
        Serial << "incoming data: ";
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected())
    {
      if (client.available())              // if the client has data
      {
        char c = client.read();             // read a byte, then
        header += c;
        Serial << c;
        if (c == '\n') {      // if the byte is a newline character
          // 2 blank lines means end of the request
          if (currentLine.length() == 0) {

          } else // if you got a newline, then clear currentLine
          { 
            Serial << endl << endl;
            // close the connection
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            //---------------------------------------
            // so here we can look for "/xxxx" in currentline and reply
        
            Serial << "loop received currentLine: " << currentLine <<
            "  header: " << header << endl;

            if(currentLine.indexOf("/nodeDetails") != -1)  // looking for hello
            {    // reply to the client
              client.println("node1 replying");
              Serial << "main loop replied: node1 replying" << endl << endl;
            }
            else  // looking for hello2
            {
              if(currentLine.indexOf("/hello2") != -1)
              {
                client.println("xxxx hello client2 xxxx");
              }
              else  // currentLine not got a reply
              {
              }
            }
            client.println();    // The HTTP response ends with another blank line
            currentLine = "";
            break;      // Break out of the while loop
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    header = "";      // clear header
    client.stop();    // Close the connection
  }
}

and for the post request:

void httpPostRequest(const char* serverName, const char* dataToSend)
{
  if(WiFi.status()== WL_CONNECTED){
    WiFiClient client;
    HTTPClient http;
    // Your Domain name with URL path or IP address with path
    http.begin(client, serverName);
      // for sendingtext
      http.addHeader("Content-Type", "text/plain");     // content type
      
      String httpRequestData = dataToSend;      // Data to send with HTTP POST
      // Send HTTP POST request
      //int httpResponseCode = http.POST(httpRequestData);
      int httpResponseCode = http.POST("**********");
      Serial << "httpPostRequest: " << endl <<
      "dataToSend: " << dataToSend << endl <<
      "serverName: " << serverName << endl <<
      "responsecode: " << httpResponseCode << endl << endl;
      
    http.end();   // free up resources
  }
}

my problem is:

in the server, the path, “serverName” i can see arrive

but sending the data: int httpResponseCode = http.POST("**********");

i never see the data arrive at the server

i think this must be due to me not understanding something,

can someone explain to me please where my problem is

thanks in advance

Dave

What's relevant is the complete code. Please post it.

I found the problem but since that part is not posted look around line

ok, thank you for coming back so quickly the whole code is several pages long but here’s the server sketch



/*********
  Rui Santos
  Complete project details at:
  https://randomnerdtutorials.com/esp32-web-server-arduino-ide/
*********/

// Load librarys
//#include <esp_wifi.h>
#include <WiFi.h>
#include <esp_wifi.h>
#include <ESPAsyncWebServer.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <TaskScheduler.h>
#include <Streaming.h>
#include <Preferences.h>


Preferences nvr;
//===============================================
// prototypes
void every1Sec();
void httpPostRequest(const char* serverName, const char* dataToSend);
//-------------------------------------
// included files
#include "nodeDetails.h"
#include "variables.h"
#include "utilities.h"
//-------------------------------------
// tasks
Task task1Sec   (1000,  TASK_FOREVER, &every1Sec);      // timing
Scheduler scheduler;
//-------------------------------------

WiFiServer server(node1Port);          // Set web server port
String header;                  // to save the HTTP request
//-------------------------------------
void every10Secs()
{

}
//-------------------------------------

void every1Sec() 
{
  timeSecs ++;
  if((timeSecs % 10) == 0)    // every 10 secs
  {
    every10Secs();
  }
  //---------------------------------
  if((timeSecs % 5) == 0)    // every 5 secs
  {
    if(sendGet) httpPostRequest("http://192.168.0.211:8080/nodeData", "hello from node1");
  }
  //---------------------------------
  if(timeSecs == 60)        // every minute
  {
    timeSecs = 0;
    myTime ++;
    if(myTime == 86400) myTime = 0; // 12 midnight
  }
}

//unsigned long currentTime = millis();   // Current time
//unsigned long previousTime = 0;         // Previous time
const long timeoutTime = 2000;          // set timeout to 2S
//---------------------------------
void connectWifi() {    // 192, 168, 0, 210
  //getChannel();
  uint8_t trys = 50;
  WiFi.mode(WIFI_AP_STA);  // Set device as a Wi-Fi Station
  if(!WiFi.config(node1Ip, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("Failed to configure Static IP");
  }
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
    trys --;
    if(trys == 0) {
      Serial << "trys = 0 restarting" << endl << endl;
      ESP.restart();
    }
  }
  Serial.print("Station IP Address: ");
  Serial.println(WiFi.localIP());
}

//---------------------------------
void setup() {
  Serial.begin(115200);
  delay(100);
  //---------------------------------
  // init tasks...... TaskScheduler
    scheduler.init();
    scheduler.addTask(task1Sec);
  //---------------------------
  newSettings = true;   // load new settings for node
  setMyDetails();       // set node details either nvr or new settings
  //---------------------------
  connectWifi();        // Connect to network
  //---------------------------------
  server.begin();
  task1Sec.enable();
}

void loop(){
  scheduler.execute();
  
  WiFiClient client = server.available();   // Listen for incoming clients
  if (client)                    // If a new client connects,
  {
        Serial << "incoming data: ";
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected())
    {
      if (client.available())              // if the client has data
      {
        char c = client.read();             // read a byte, then
        header += c;
        Serial << c;
        if (c == '\n') {      // if the byte is a newline character
          // 2 blank lines means end of the client HTTP request, 
          if (currentLine.length() == 0) {

          } else // if you got a newline, then clear currentLine
          { 
            Serial << endl << endl;
            // close the connection
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            //---------------------------------------
            // so here we can look for "/xxxx" in currentline and reply
        
            Serial << "loop received currentLine: " << currentLine <<
            "  header: " << header << endl;

            if(currentLine.indexOf("/nodeDetails") != -1)  // looking for hello
            {    // reply to the client
              client.println("node1 replying");
              Serial << "main loop replied: node1 replying" << endl << endl;
            }
            else  // looking for hello2
            {
              if(currentLine.indexOf("/hello2") != -1)
              {
                client.println("xxxx hello client2 xxxx");
              }
              else  // currentLine not got a reply
              {
              }
            }
            client.println();    // The HTTP response ends with another blank line
            currentLine = "";
            break;      // Break out of the while loop
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    header = "";      // clear header
    client.stop();    // Close the connection
  }
}
//---------------------------------
void httpPostRequest(const char* serverName, const char* dataToSend)
{
  if(WiFi.status()== WL_CONNECTED){
    WiFiClient client;
    HTTPClient http;
    // Your Domain name with URL path or IP address with path
    http.begin(client, serverName);
      // Specify content-type header
      // for sending Json in Json format
        //http.addHeader("Content-Type", "application/json");
        // Data to send with HTTP POST
        //int httpResponseCode = http.POST("{\"api_key\":\"tPmAT5Ab3j7F9\",\"sensor\":\"BME280\",\"value1\":\"24.25\",\"value2\":\"49.54\",\"value3\":\"1005.14\"}");

      // for sending text
      http.addHeader("Content-Type", "text/plain");     // content type
      //String httpRequestData = "hello from node1";    // Data to send with HTTP POST
      String httpRequestData = dataToSend;              // Data to send with HTTP POST

      // Send HTTP POST request
      int httpResponseCode = http.POST(httpRequestData);

      Serial << "httpPostRequest: " << endl <<
      "dataToSend: " << dataToSend << endl <<
      "serverName: " << serverName << endl <<
      "  responsecode: " << httpResponseCode << endl;
    
    http.end();   // free up resources
  }
}




and heres the client sketch

/*********
  Rui Santos
  Complete project details at:
  https://randomnerdtutorials.com/esp32-web-server-arduino-ide/
*********/

// Load librarys
#include <WiFi.h>
#include <esp_wifi.h>
#include <ESPAsyncWebServer.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <TaskScheduler.h>
#include <Streaming.h>
#include <Preferences.h>


Preferences nvr;
//---------------------------
/*  Using Dallas DS18B20 sensor
#include <OneWire.h>
#include <DallasTemperature.h>
OneWire oneWire(4); //DallasTempPin is 4;
DallasTemperature sensors(&oneWire);
// use sensors.begin(); in setup
*/
//===============================================
// prototypes
void every1Sec();
void httpPostRequest(const char* serverName, const char* dataToSend);
//-------------------------------------
// included files
#include "nodeDetails.h"
#include "variables.h"
#include "utilities.h"
//-------------------------------------
// tasks
Task task1Sec   (1000,  TASK_FOREVER, &every1Sec);      // timing
Scheduler scheduler;
//-------------------------------------

WiFiServer server(node2Port);          // Set web server port
String header;                          // to save the HTTP request
//-------------------------------------
void every10Secs()
{

}
//-------------------------------------

void every1Sec() 
{
  timeSecs ++;
  if((timeSecs % 10) == 0)    // every 10 secs
  {
    every10Secs();
  }
  //---------------------------------
  if((timeSecs % 7) == 0)    // every 5 secs
  {
    //if(sendGet) httpGETRequest("http://192.168.0.210:80/hellofromNode2");
    if(sendGet) httpPostRequest("http://192.168.0.210:80/nodeDetails", "hello from node2");

  }
  //---------------------------------
  if(timeSecs == 60)        // every minute
  {
    timeSecs = 0;
    myTime ++;
    if(myTime == 86400) myTime = 0; // 12 midnight
  }
}


const long timeoutTime = 2000;          // set timeout to 2S
//---------------------------
void connectWifi() {    // 192, 168, 0, 210
  //getChannel();
  uint8_t trys = 50;
  WiFi.mode(WIFI_AP_STA);  // Set device as a Wi-Fi Station
  if(!WiFi.config(node2Ip, gateway, subnet, primaryDNS, secondaryDNS)) {
    Serial.println("Failed to configure Static IP");
  }
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print(".");
    trys --;
    if(trys == 0) {
      Serial << "trys = 0 restarting" << endl << endl;
      ESP.restart();
    }
  }
  Serial.print("Station IP Address: ");
  Serial.println(WiFi.localIP());
}

//---------------------------------
void setup() {
  Serial.begin(115200);
  delay(100);
  
  //---------------------------------
  // init tasks...... TaskScheduler
    scheduler.init();
    scheduler.addTask(task1Sec);
  //---------------------------
  newSettings = true;  // load new settings for node
  setMyDetails();  // set node details either fro, nvr or new settings
  //---------------------------------

  connectWifi();            // Connect to network
  //---------------------------------
  server.begin();
  task1Sec.enable();
}

void loop(){
  scheduler.execute();
  
  WiFiClient client = server.available();   // Listen for incoming clients
  if (client) {                             // If a new client connects,

    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected())
    {
      if (client.available())              // if there's bytes to read from the client,
      {
        char c = client.read();             // read a byte, then
        header += c;
        if (c == '\n') {      // if the byte is a newline character
          // 2 blank lines means end of the client HTTP request, 
          if (currentLine.length() == 0) {

          } 
          else // if you got a newline, then clear currentLine
          { 
            Serial << "main loop received: " << currentLine << endl;
            // close the connection
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println("Connection: close");
            client.println();
            Serial << "loop received currentLine: " << currentLine <<
            "  header: " << header << endl;

        
            if(currentLine.indexOf("/nodeData") != -1)  // looking for hello
            {    // reply to the client
              client.println("node1 replying");
              Serial << "main loop replied: node2 replying" << endl << endl;
            }
            else  // looking for hello2
            {
              if(currentLine.indexOf("/hello2") != -1)
              {
                client.println("xxxx hello client2 xxxx");
              }
              else
              {
              }
            }
           
        
            client.println();    // The HTTP response ends with another blank line
            currentLine = "";
            break;      // Break out of the while loop
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }
      }
    }
    header = "";    // clear header
    client.stop();    // Close the connection
  }
  //-------------------------------
}

//---------------------------------

void httpPostRequest(const char* serverName, const char* dataToSend)
{
  if(WiFi.status()== WL_CONNECTED){
    WiFiClient client;
    HTTPClient http;
    // Your Domain name with URL path or IP address with path
    http.begin(client, serverName);

      //http.addHeader("Content-Type", "text/plain");     // content type
      http.addHeader("Content-Type", "application/x-www-form-urlencoded");
      
      String httpRequestData = dataToSend;      // Data to send with HTTP POST
      // Send HTTP POST request
      //int httpResponseCode = http.POST(httpRequestData);
      int httpResponseCode = http.POST("**********");


      Serial << "httpPostRequest: " << endl <<
      "dataToSend: " << dataToSend << endl <<
      "serverName: " << serverName << endl <<
      "responsecode: " << httpResponseCode << endl << endl;
      
    http.end();   // free up resources
  }
}


thanks for showing interest

Dave

Your server loop is written to behave like a simple HTTP GET request parser.
It stops reading at the blank line that terminates the header:

if (c == '\n') {
    if (currentLine.length() == 0) {
        // end of request
    } else {
        ...
        break;
    }
}

This is the key:
HTTP POST requests contain a body after the blank line, but your code stops reading at the blank line and immediately replies, without reading the POST body.

Therefore:

  • The URL/path shows up correctly (because it's in the request line: POST /yourPath HTTP/1.1)
    The POST data never shows up because you never read past the headers
    The HTTPClient does send the body correctly, but your server ends reading too early

man thats great, thank you, as i think said in my first post not understanding fully,

you have expanded my knowledge thank you

Dave