I am using the ESP8266 with Arduino IDE and have set up a server at port 200 . The IP is also defined as the same as 192.168.1.100.
ESP8266WebServer server(200);
IPAddress ip(192, 168, 1, 100); //Node static IP
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
server.on("/parseIFTTT", parseIFTTT);
void parseIFTTT() {
String message;
message += server.args();
message += "\n";
for (uint8_t i = 0; i < server.args(); i++) {
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
Serial.println(message);
Serial.println(server.argName(0));
Serial.println(server.arg(0));
server.send(200, "text/plain", "Success " + message);
}
is done to route the parseIFTTT request to this parseIFTTT() method.
I have done port forwarding and using the duckdns to access this server from outside. This is my duckdns address
http://xxxxxx.duckdns.org:200/parseIFTTT
When I make a POST using a POSTMAN tool with content type as text/plain , the body contents are shown in the serial monitor as
plain
--body contents--
But when the same request is made from IFTTT the serial monitor shows nothing but plain as empty .Initially I felt the issue is with IFTTT. But that is not the issue as when I use the WiFiWebServer example in the arduino , using the following code
String req = client.readString();
Serial.println(req);
client.flush();
I see the data from IFTTT as :
POST /parseIFTTT HTTP/1.1
Content-type: text/plain
host: xxxxxx.duckdns.org:200
content-length: 27
x-newrelic-id: XAMGV15QGwQJVllRDgQ=
x-newrelic-transaction: PxQFA1NbAQQJVwJWA1dSB0YdUFIOFQZOEgEPVA5ZBFYGXAwECFgFAFcUG0MHUwoLBAcDAxVs
Connection: close
{"value":"test data from IFTTT"}
So I believe I am doing something wrong with the server.args(). I am under the impression that server.args() should give the body contents used in the POST whether contentType is text/plain or x-www-form-urlencoded.
Am I doing something wrong or with the server.args() can't we get the body data from the POST request ?
There are a few 'gotchas' in the ESP8266WebServer's implementation. I have found the body shows up in the
server.arg("plain")
but only if the class cannot find any key value pairs. The ESP8266WebServer will look for an '=' and only if it cannot find one will it put the body in the "plain" arg.
This arg will contain the full body so you will have to parse the JSON yourself. I have found ArduinoJson to be a very easy to use library to do so.
Short example:
void handleRequest() {
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(server.arg("plain"));
root.printTo(Serial);
}
On a sidenote. If you are testing with a POSTMAN like tool, do not forget to set the 'Content-length'. ESP8266WebServer will treat your body as empty (or of a different length) if it does not correspond with this header value.
Hope this answers your question.