2

I'm using an ESP8266 version 1 with the WiFiEsp library to connect to WiFi, and that works just fine.

I'm setting up the device using the same code as in the example WebClientRepeating.

I need to send a POST request instead of a GET request, but I can't get it to work as I want. If I create my POST request like this, it works just fine:

if (client.connect(server, 3005)) {
  Serial.println("Connecting...");

  // send the HTTP POST request  
  client.println("POST /open/peripherals HTTP/1.1");
  client.println("Host: 192.168.10.137:3005");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.println();

  // note the time that the connection was made
  lastConnectionTime = millis();
}
else {
  // if you couldn't make a connection
  Serial.println("Connection failed");
}

I get the response like this:

[WiFiEsp] Connecting to 192.168.10.137
Connecting...
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 19
ETag: W/"13-jSAaqMh5E3R94/b2aONzvg"
Date: Sun, 13 Nov 2016 10:20:58 GMT
Connection: close

{"temp":"Testdata"}

However, if I try to send some body data in the request it fails:

if (client.connect(server, 3005)) {
  Serial.println("Connecting...");

  // send the HTTP POST request  
  client.println("POST /open/peripherals HTTP/1.1");
  client.println("Host: 192.168.10.137:3005");
  client.println("User-Agent: Arduino/1.0");
  client.println("Connection: close");
  client.println("Content-Type: application/x-www-form-urlencoded");
  client.println("Content-Length: 16");
  client.println();
  client.println("temperature=22.7");

  // note the time that the connection was made
  lastConnectionTime = millis();
}
else {
  // if you couldn't make a connection
  Serial.println("Connection failed");
}

Then the response from serial output is:

[WiFiEsp] Connecting to 192.168.10.137
Connecting...
[WiFiEsp] >>> TIMEOUT >>>
[WiFiEsp] Data packet send error (1)
[WiFiEsp] Failed to write to socket 0
[WiFiEsp] Disconnecting  0

However, the POST request including the body is received by the Web server just fine, but the response sent to the Arduino I can't read because it shows me an error instead of a proper response. From my webserver the response for the POST call that works and the POST call that fails is the same.

Does anyone knows why this fails when I add Content-Type, Content-Length and some body data?

Thanks in advance!

  • 1
    The first response doesn't correspond to the first code. It is hard to guess where is the problem without the full code. – Chupo_cro Dec 5 '16 at 20:54
  • Your content length is actually 18, considering the CRLF appended by println(). – TisteAndii Feb 13 '17 at 1:55
2

Your problem is the content you are sending. While this format works well e. g. in Python libraries, this library seems to have a problem with it. I solved it this way, when I happened to face this problem:

//all your other code, including the remaining HTTP-Request
String content = "{\"temperature\":\""+String(value)+"\"}";
client.println("Content-Length: 16"); //insert, well, your content length
client.println(content);
0

One major problem seems to exists within the AT firmware of most ESP's. By default, the http headers it sends include "Connection: close". However, the firmware seems to be buggy and unable to cope with the server closing the connection after it sends the response. Thus, in order to be able to get a response back from the target server you need to have "Connection: keep-alive" instead. This means you must explicitly add this to your header since "Connection: close" will be added if nothing else is said. Also to make life easier for the WifiEsp library you could make sure your server returns an already well-known status string for the library like fx "SEND OK"… I'm doing this on a barometer logger that sends data to a MVC Web Api written in C# and it works perfect...

Here's my code:

String PostHeader = "POST http://" + server + ":" + String(port) + "/api/values HTTP/1.1\r\n";
PostHeader += "Connection: keep-alive\r\n";
PostHeader += "Content-Type: application/json; charset=utf-8\r\n";
PostHeader += "Host: " + server + ":" + String(port) + "\r\n";
PostHeader += "Content-Length: " + String(jsonString.length()) + "\r\n\r\n";
PostHeader += jsonString;
Serial.println(PostHeader);
client.connect(server.c_str(), port);
client.println(PostHeader);
client.stop();

And the full log looks like this:

POST http://192.168.10.197:8001/api/values HTTP/1.1
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Host: 192.168.10.197:8001
Content-Length: 144

{"IpAddress":"192.168.10.230","MacAddress":"5c:cf:7f:d9:2f:c8","Temperature":34.6,"Pressure":1007,"Altitude":48.48573,"PressureAtSeaLevel":1007}

[WiFiEsp] Connecting to 192.168.10.197
[WiFiEsp] Disconnecting  3

In the file debug.h located in the WifiEsp library source code you could alter a define and get more output to your serial console. Open the file and change

#define _ESPLOGLEVEL_ 3

to

#define _ESPLOGLEVEL_ 4

Save the file and recompile/deploy your source code to your Arduino and you will get extensive information about all AT commands the library sends and what the library receives in return.

  • Connection: close tells the server to close the connection once it is done sending the response. If you can't get the response with Connection: close, that's a bug of yours: don't blame that header. BTW, header lines should be terminated with "\r\n", not just "\n". – Edgar Bonet Jul 19 '18 at 8:55
  • Cool, I struggled for a long time with this and experimented with a lot of things, changing from \r\n to \n was one of the things I tried (that didn't work). Only forgot to change it back to what it should be. The only way to get it to work with the ESP8266 and the WifiEsp library was to mark the header with keep-alive though. I have debugged the library and tried to find anything that could affect this but nada, most likely it's some bug in the AT firmware... Everyone is complaining about this issue in all devsites, just wanted to add my 2 cents to it... – Lennart Jansson Jul 19 '18 at 10:28
  • If that's the case, then you should rephrase your answer: “There is a know bug in the XXX library [link to the bug discussion] that prevents it to work with Connection: close, therefore...”. As it stands, your answer implies that using Connection: close is an error. – Edgar Bonet Jul 19 '18 at 10:48
  • Better? I don't have any general link to any discussions around this subject because everyone, everywhere is having a wild goose chase to how to solve this issue, many blame the library but as far as I can see there's no issue with it and it seems to be doing what it is supposed to do :) – Lennart Jansson Jul 19 '18 at 10:54
  • Also changed to \r\n... – Lennart Jansson Jul 19 '18 at 10:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.