Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Add support for sending PUT, PATCH, DELETE request #5

Closed
@gleniat

Description

@gleniat

Hello,

thanks for a nice library, good work.

I would be nice to add a support for sending remaining HTTP methods, too.
The requests PUT, PATCH, DELETE are technically the same as POST, they just have a different name.


Arduino IDE version: 1.8.13
ESP32 Core Version 1.0.4
OS: macOS Catalina v10.15.5

Context:

I have tried to send PUT, PATCH and DELETE and it always end up in an endless loop (Guru Meditation Error).

How to reproduce:

  1. load examples/AsyncHTTPRequest_ESP/AsyncHTTPRequest_ESP.ino demo sketch
  2. change GET request (line 108) to POST
    request.open("POST", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
  3. compile and run on esp32 ... code is still working fine
  4. now change it to PUT and compile
    request.open("PUT", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
  5. now it is constantly restarting
    Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.

Full sketch:

This is a full code for testing PUT, PATCH and DELETE methods. Uncommend one line in the end of setup() function

/****************************************************************************************************************************
  AsyncHTTPRequest_ESP.ino - Dead simple AsyncHTTPRequest for ESP8266, ESP32 and currently STM32 with built-in LAN8742A Ethernet
  
  For ESP8266, ESP32 and STM32 with built-in LAN8742A Ethernet (Nucleo-144, DISCOVERY, etc)
  
  AsyncHTTPRequest_Generic is a library for the ESP8266, ESP32 and currently STM32 run built-in Ethernet WebServer
  
  Based on and modified from asyncHTTPrequest Library (https://github.com/boblemaire/asyncHTTPrequest)
  
  Built by Khoi Hoang https://github.com/khoih-prog/AsyncHTTPRequest_Generic
  Licensed under MIT license
  
  Copyright (C) <2018>  <Bob Lemaire, IoTaWatt, Inc.>
  This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License 
  as published bythe Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
  You should have received a copy of the GNU General Public License along with this program.  If not, see <https://www.gnu.org/licenses/>.  
 
  Version: 1.0.2
  
  Version Modified By   Date      Comments
  ------- -----------  ---------- -----------
  1.0.0    K Hoang     14/09/2020 Initial coding to add support to STM32 using built-in Ethernet (Nucleo-144, DISCOVERY, etc).
  1.0.1    K Hoang     09/10/2020 Restore cpp code besides Impl.h code.
  1.0.2    K Hoang     09/11/2020 Make Mutex Lock and delete more reliable and error-proof
 *****************************************************************************************************************************/
//************************************************************************************************************
//
// There are scores of ways to use AsyncHTTPRequest.  The important thing to keep in mind is that
// it is asynchronous and just like in JavaScript, everything is event driven.  You will have some
// reason to initiate an asynchronous HTTP request in your program, but then sending the request
// headers and payload, gathering the response headers and any payload, and processing
// of that response, can (and probably should) all be done asynchronously.
//
// In this example, a Ticker function is setup to fire every 300 seconds to initiate a request.
// Everything is handled in AsyncHTTPRequest without blocking.
// The callback onReadyStateChange is made progressively and like most JS scripts, we look for
// readyState == 4 (complete) here.  At that time the response is retrieved and printed.
//
// Note that there is no code in loop().  A code entered into loop would run oblivious to
// the ongoing HTTP requests.  The Ticker could be removed and periodic calls to sendRequest()
// could be made in loop(), resulting in the same asynchronous handling.
//
// For demo purposes, debug is turned on for handling of the first request.  These are the
// events that are being handled in AsyncHTTPRequest.  They all begin with Debug(nnn) where
// nnn is the elapsed time in milliseconds since the transaction was started.
//
//*************************************************************************************************************

#if !( defined(ESP8266) ||  defined(ESP32) )
  #error This code is intended to run on the ESP8266 or ESP32 platform! Please check your Tools->Board setting.
#endif

// Level from 0-4
#define ASYNC_HTTP_DEBUG_PORT     Serial
#define _ASYNC_HTTP_LOGLEVEL_     4    

// 300s = 5 minutes to not flooding
#define HTTP_REQUEST_INTERVAL     30  //300

int status;     // the Wifi radio's status

const char* ssid        = "77002";
const char* password    = "nob48.jute.netstone";

#if (ESP8266)
  #include <ESP8266WiFi.h>
#elif (ESP32)
  #include <WiFi.h>
#endif

#include <AsyncHTTPRequest_Generic.h>           // https://github.com/khoih-prog/AsyncHTTPRequest_Generic
#include <Ticker.h>

AsyncHTTPRequest request;
Ticker ticker;

// GET REQUEST ARE WORKING FINE
void sendGetRequest() 
{
  Serial.println("Sending GET request...");
  
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    // GET IS WORKING CORRECLY
    request.open("GET", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send();
  }
  else
  {
    Serial.println("Can't send request");
  }
}

// POST REQUESTS ARE WORKING FINE
void sendPostRequest() 
{
  Serial.println("Sending POST request...");
  
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    request.open("POST", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send("dummy request body");
  }
  else
  {
    Serial.println("Can't send request");
  }
}

// PUT REQUESTS END UP IN Guru Meditation Error
void sendPutRequest() 
{
  Serial.println("Sending PUT request...");
  
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    request.open("PUT", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send("dummy request body");
  }
  else
  {
    Serial.println("Can't send request");
  }
}

// PATCH REQUESTS END UP IN Guru Meditation Error
void sendPatchRequest() 
{
  Serial.println("Sending PATCH request...");
  
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    request.open("PATCH", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send("dummy request body");
  }
  else
  {
    Serial.println("Can't send request");
  }
}

// DELETE REQUESTS END UP IN Guru Meditation Error
void sendDeleteRequest() 
{
  Serial.println("Sending DELETE request...");
  
  if (request.readyState() == readyStateUnsent || request.readyState() == readyStateDone)
  {
    request.open("DELETE", "http://worldtimeapi.org/api/timezone/America/Toronto.txt");
    request.send("dummy request body");
  }
  else
  {
    Serial.println("Can't send request");
  }
}

void requestCB(void* optParm, AsyncHTTPRequest* request, int readyState) 
{
  if (readyState == readyStateDone) 
  {
    Serial.println("\n**************************************");
    Serial.println(request->responseText());
    Serial.println("**************************************");
    
    //request->setDebug(false);
  }
}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  while (!Serial);
  
  Serial.println("\nStarting AsyncHTTPRequest_ESP using " + String(ARDUINO_BOARD));

  WiFi.mode(WIFI_STA);

  WiFi.begin(ssid, password);
  
  Serial.println("Connecting to WiFi SSID: " + String(ssid));

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.print(F("\nHTTP WebServer is @ IP : "));
  Serial.println(WiFi.localIP());
 
  request.setDebug(true);
  
  request.onReadyStateChange(requestCB);
  //ticker.attach(HTTP_REQUEST_INTERVAL, sendGetRequest);
  
  // Uncomment one
  //sendGetRequest(); // works correctly
  //sendPostRequest(); // works correctly
  //sendPutRequest(); // Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
  sendPatchRequest(); // Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
  //sendDeleteRequest(); // Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
}

void loop()
{ 
}

Thank you

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions