PUT request using ArduinoHttpClient

Hello,

I am trying to replicate the functionality of the following curl command (which I have confirmed working with non-dummy values):

curl --digest -u admin:1234 -X PUT -H "X-CSRF: x" --data "value=true" "http://192.168.0.100/restapi/relay/outlets/2/state/"
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoHttpClient.h>
#include <ArduinoJson.h>

// Ethernet settings
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 
IPAddress arduinoIP(192, 168, 0, 101); 
IPAddress serverIP(192, 168, 0, 100); 
int serverPort = 80; 

EthernetClient ethclient;
HttpClient client = HttpClient(ethclient, serverIP, serverPort);

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

  // Initialize Ethernet with a fixed IP address
  Ethernet.begin(mac, arduinoIP);

  // Wait for Ethernet to initialize
  delay(1000);

  Serial.println("Arduino is connected to the Ethernet network");
  Serial.print("Arduino IP address: ");
  Serial.println(Ethernet.localIP());
}

void loop() {

  if (client.connect(serverIP, serverPort)) {
  
// Perform the PUT request
    client.beginRequest();
    client.put("/restapi/relay/outlets/2/state/", "application/x-www-form-urlencoded", "value=true");
    client.sendBasicAuth("admin", "1234");
    client.sendHeader("X-Requested-With", "X-CSRF: x");  
    client.endRequest();

    // Read the response
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.print(c);
      }
    }

    Serial.println();
    Serial.println("Request complete");
    Serial.println(client.responseStatusCode());
    Serial.println(client.responseBody());

    // Wait five seconds before making the next request
    delay(5000);
  } else {
    Serial.println("Failed to connect for GET request");
    delay(5000);
  }
}

I receive the following output:

HTTP/1.1 403 Forbidden
Transfer-Encoding: chunked
Content-Type: text/plain
Cache-Control: max-age=0, private, must-revalidate

7B
Request forgery attempt detected, please supply X-Requested-With: XMLHttpRequest or X-CSRF: (any value) with your requests.
0


Request complete

Am I sending the X-Requested-With header incorrectly? Am I missing anything else to properly replicate the curl command?

Thank you in advance.

For posterity, the correct answer seems to be:

#include <Ethernet.h>
#include <ArduinoHttpClient.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // This can be any unique MAC address
IPAddress ip(192, 168, 0, 101); // Static IP address
IPAddress server(192, 168, 0, 100);

EthernetClient ethernetClient;
HttpClient client = HttpClient(ethernetClient, server, 80);

void setup() {
  Ethernet.begin(mac, ip);
  Serial.begin(9600);

  while (!Serial) {
    ; // wait for serial port to connect
  }

  // Ensure Ethernet is properly initialized
  delay(1000);

  putRequest();
}

void putRequest() {
  client.beginRequest();
  client.put("/restapi/relay/outlets/7/state/");
  
  // Basic authentication (username:password base64 encoded) 
  client.sendBasicAuth("admin", "1234");
  
  client.sendHeader("X-CSRF", "x");
  client.sendHeader("Content-Type", "application/x-www-form-urlencoded");
  client.sendHeader("Content-Length", 10); // length of "value=true"
  
  client.beginBody();
  client.print("value=true");
  client.endRequest();

  // Read the response
  int statusCode = client.responseStatusCode();
  String response = client.responseBody();
  
  Serial.print("Status code: ");
  Serial.println(statusCode);
  Serial.print("Response: ");
  Serial.println(response);
}

void loop() {
  // This example runs the PUT request only once in setup()
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.