Page 1 of 1

Problems with ESP32 Web Server handling POST requests

Posted: Tue Jul 09, 2024 1:38 pm
by BivvyCoder
I'm developing a very basic web server as part of an IoT project on an ESP32-S3.
I have a web page with an input box and up / down buttons. My aim is to get the value in the input box to change each time the button is pressed and then POST the new value to the web server for processing.
The web page appears to work OK, but there are two problems.
  • When I parse the message content there are some extra characters that were not sent by the web page
  • If I press the button more than 5 or 6 times the server stops handling the POST messages until the page is refreshed manually

Code: Select all

// WiFi web pages
#include "handler.h"
//#include "timer.h"
#include "helper.h"
#include "esp_wifi.h"

#include <sys/param.h>

#include "nvs.h"
#include "globals.h"
#include "functions.h"

static const char *TAG = "Control Handler";

esp_err_t control_handler(httpd_req_t *req)
{
    ESP_LOGI(TAG,"Loading Control Page");
    httpd_req_to_sockfd(req);
    static esp_err_t out;

    if (req->method == HTTP_POST)  //Data has been entered and needs to be handled
    {
        int ret, remaining = req->content_len;
        char buf[req->content_len];

        while (remaining > 0)
        {
            /* Read the data for the request */
            if ((ret = httpd_req_recv(req, buf, MIN(remaining, sizeof(buf)))) <= 0)
            {
                if (ret == HTTPD_SOCK_ERR_TIMEOUT)
                {
                    continue;
                }
                ESP_LOGE(TAG, "Timeout occured");
                return ESP_FAIL;
            }

            remaining -= ret;
        }

        //Now extract the parameters from the buffer
        size_t contentLength = 64;
        char PAN_Angle[contentLength], TILT_Angle[contentLength], Control_Mode[contentLength];
        ESP_LOGE(TAG,"Buffer: %s",buf);

        readUrlParameterIntoBuffer(buf, "pan", PAN_Angle, contentLength);
        readUrlParameterIntoBuffer(buf, "tilt", TILT_Angle, contentLength);
        readUrlParameterIntoBuffer(buf, "mode", Control_Mode, contentLength);
        
        ESP_LOGI(TAG, "Processed form %s/%s/%s",  Control_Mode, PAN_Angle, TILT_Angle);
       
        // Send an HTTP response
         httpd_resp_set_status(req, "200 OK");
     
          
        
        out = ESP_OK;
        return out;
    }
  }
Here is an example of the console output in the ESP32 IDE (with two extra characters "h☺" on the end of the buffer)

Code: Select all

E (1744596) Control Handler: Buffer: pan=0&tilt=22&mode=Automatich☺
I (1744596) urihelper: Found 'pan' parameter => 0
I (1744596) urihelper: Found 'tilt' parameter => 22
I (1744606) urihelper: Found 'mode' parameter => Automatich☺
I (1790846) Control Handler: Processed form Automatich☺/0/24
And after the button is pressed several times

Code: Select all

E (1794996) httpd: httpd_accept_conn: error in accept (23)
W (1794996) httpd: httpd_server: error accepting new connection
So it looks like I'm trying to open a new connection each time the message is posted - so I'm guessing I need to find a way to keep the connection open while the web page is open.

In case it's relevant, here's the javascript I use to post the messages to the ESP32 server

Code: Select all

// Function to post value to the server
    function postValueToServer(value) {
	
		const message = 'pan='+ panInput.value + '&tilt=' + tiltInput.value + '&mode=' + document.querySelector('input[name="mode"]:checked').value;
		console.log(message);
		
        // Implement your server-side logic here
        console.log(`Posting value ${value} to the server...`);
        // You can use AJAX or fetch to send the value to your server endpoint
		const xhr = new XMLHttpRequest();
		xhr.open('POST', '/control', true);
		xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log('Value posted successfully:', message);
        }
    };
    xhr.send(message);
	
    }
   

Thanks for your support

Re: Problems with ESP32 Web Server handling POST requests

Posted: Tue Jul 09, 2024 2:12 pm
by MicroController
Try calling httpd_resp_send(...), possibly with a buf_len of 0, instead of httpd_resp_set_status(...) to actually send a response and mark the request as handled.

httpd_resp_set_status(...) by itself does not send anything back to the client.

Re: Problems with ESP32 Web Server handling POST requests

Posted: Tue Jul 09, 2024 2:14 pm
by boarchuz
And null-terminate buf

Re: Problems with ESP32 Web Server handling POST requests

Posted: Mon Jul 15, 2024 2:38 pm
by BivvyCoder
Thanks - works perfectly now