22

I am trying to post information to an API on a web project that I have created and hosted. I am not sure what the exact format is for the HTTP POST request. Every time I try I get HTTP 400 errors with the message that there is "an invalid verb".

Sample Code:

byte server[] = {"our IP"}
..
..

client(server, 80)
..
..
client.println("POST /Api/AddParking/3");

It connects to the IP address supplied without any problems, but all I get back in the above mentioned HTTP error code 400. I am not sure if I was supposed to include a HTTP version after my POST or and Content-Length or any other information.

Davy de Vries
  • 4,578
  • 2
  • 14
  • 29
Austen Bryan
  • 229
  • 1
  • 2
  • 3

4 Answers4

32

The original question is already answered, but just for reference for people passing by via Google; here is a more complete example how to post data to a web server with an Arduino:

IPAddress server(10,0,0,138);
String PostData = "someDataToPost";

if (client.connect(server, 80)) {
  client.println("POST /Api/AddParking/3 HTTP/1.1");
  client.println("Host: 10.0.0.138");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.print("Content-Length: ");
  client.println(PostData.length());
  client.println();
  client.println(PostData);
}
Davy de Vries
  • 4,578
  • 2
  • 14
  • 29
stif
  • 429
  • 4
  • 7
  • 2
    client.println(PostData.length()); *missing 't'* – F481 May 23 '13 at 08:06
  • Hi, it seems to me like it does not matter which host you type in the "Host: 10.0.0.138" parameter. As long as the server is correct in the client.connect(server, port) line. Is this expected that the "Host: " parameter does not matter? – teeeeee Feb 21 '23 at 15:59
  • That Content-Length header was the key to getting it to work for me on Heroku – SRR Jun 02 '23 at 03:44
6

Another option is using the HTTPClient.h (for the arduino IDE on adafruit's ESP32 feather), which handles https with no effort it seems. I'm including JSON payload also and can successfully send an IFTTT webhook.

  HTTPClient http;
  String url="https://<IPaddress>/testurl";
  String jsondata=(<properly escaped json data here>);

  http.begin(url); 
  http.addHeader("Content-Type", "Content-Type: application/json"); 

  int httpResponseCode = http.POST(jsondata); //Send the actual POST request

  if(httpResponseCode>0){
    String response = http.getString();  //Get the response to the request
    Serial.println(httpResponseCode);   //Print return code
    Serial.println(response);           //Print request answer
  } else {
    Serial.print("Error on sending POST: ");
    Serial.println(httpResponseCode);

    http.end();

 }
jshep321
  • 553
  • 5
  • 8
2

Sending hand-crafted HTTP packets can be a bit tricky because they are extremely picky about the format used. I highly recommend reading through the HTTP protocol if you have the time because it explains the syntax and fields required. In particular you should look at section 5 "Request".

With regards to your code, you do need to specify the HTTP version after the POST URI and I believe you also need to specify the "Host" header. On top of that you need to be sure to have a carriage-return line-feed (CRLF) at the end of each line. So, your packet should look something like:

POST /Api/AddParking/3 HTTP/1.1
Host: www.yourhost.com
Dean Pucsek
  • 257
  • 2
  • 7
0

Requests can be sent like that too

 // Check if we are Connected.
 if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status
    HTTPClient http;    //Declare object of class HTTPClient

    http.begin("http://useotools.com/");      //Specify request destination
    http.addHeader("Content-Type", "application/x-www-form-urlencoded", false, true);
    int httpCode = http.POST("type=get_desire_data&"); //Send the request

    Serial.println(httpCode);   //Print HTTP return code
    http.writeToStream(&Serial);  // Print the response body

}
user889030
  • 4,353
  • 3
  • 48
  • 51