POST request with ESP32 returns 301 - nginx

I have a NGINX server on a raspberry pi. I want to send JSON file from my ESP32 board to the NGINX web-server.
In a first step, I have followed this tutorial :
https://techtutorialsx.com/2017/05/20/esp32-http-post-requests/
It gives this code :
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
void setup() {
Serial.begin(115200);
delay(4000); //Delay needed before calling the WiFi.begin
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
}
void loop() {
if(WiFi.status()== WL_CONNECTED){ //Check WiFi connection status
HTTPClient http;
http.begin("http://jsonplaceholder.typicode.com/posts"); //Specify destination for HTTP request
http.addHeader("Content-Type", "text/plain"); //Specify content-type header
int httpResponseCode = http.POST("POSTING from ESP32"); //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(); //Free resources
}else{
Serial.println("Error in WiFi connection");
}
delay(10000); //Send a request every 10 seconds
}
No problem if I use this code with the following line
http.begin("http://jsonplaceholder.typicode.com/posts");
My serial monitor of the ARDUINO's IDE returns :
201
{
"id": 101
}
But, when I only replace the previous line by
http.begin("http://82.145.56.62:151/postfile");
I get on my serial monitor this :
301
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.10.3</center>
</body>
</html>
Would you have an idea of my problem ?
Thank you ,
EDIT
I have gone ahead a little more. I have created a php file in the directory posts. Now I get the HTTP code 200, so my webserver receive the POST request.
New problem : I cannot figure out how to display the POST content on my php file. Would you have an idea ?
Thank you,

I have solved my problem by replacing :
http.addHeader("Content-Type", "text/plain");
by
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

Related

HTTP get Request using ESP8266

Why I am unable to send get request. It always response 400.The URL are okay there is no problem in it. Actually I need to send data using get request. I have tried my best to find the solution but I didn't get any idea about it. Please anyone can help me with the code
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>//this header is used to send get request and see response
#include <WiFiClient.h>
const char* ssid = "myssid";
const char* password = "mypswd";
String host_url="https://api-test.technofield.net";
String url1="/api/data?token=TEST_TOKEN_123&data=";
int httpPort=80;
void setup() {
Serial.begin(9600);
WiFi.begin(ssid, password); //Connect to my WiFi router
Serial.println("");
Serial.print("Connecting"); //initiall step just displaying connecting
// Wait for connection
while (WiFi.status() != WL_CONNECTED) { //the llop wiil execute till wifi is not connected
delay(500);
Serial.print(".");
}
//If connection successful show IP address in serial monitor
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);// connected to given ssid
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //IP address assigned to your ESP
}
void loop(){
if(WiFi.status()==WL_CONNECTED){ //we will perform action if wifi is connected
HTTPClient http; //intialize object of HTTPclient which is importent
String data="Sunil Kumar Yadav";
//String token="TEST_TOKEN_123";
url1=url1+data;
//full APi url is created you can manipulate those above data and token vaiable.
http.begin(host_url,httpPort,url1);//specify the request,begin the request
int httpCode=http.GET(); //Send the request
// if (httpCode>0){ //lets see the response from server
// String payload = http.getString();//store response on payload variable
// Serial.print("==============");//just for seperating the wifi connection status and server response
// Serial.println(payload);//print the response payload
// }
Serial.print(httpCode);
http.end();//if there is begin there will be end ,it will Close the connection
}
delay(500); //send the request in every 2sec, you can change it according to your need
//you can also specify the time so that it will be easy to identify on which time data is send
}
Following is the output:
301
==============<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
I dont know how to solve this.
There's one (of several) example how to do this with HTTPs here: https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266HTTPClient/examples/BasicHttpsClient/BasicHttpsClient.ino
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>
const char* ssid = "myssid";
const char* password = "mypswd";
String url = "https://api-test.technofield.net/api/data?token=TEST_TOKEN_123&data=";
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.println("");
Serial.print("Connecting");
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void loop() {
if (WiFi.status() == WL_CONNECTED) {
WiFiClientSecure client;
client.setInsecure();
HTTPClient https;
String data = "Sunil%20Kumar%20Yadav";
String fullUrl = url + data;
Serial.println("Requesting " + fullUrl);
if (https.begin(client, fullUrl)) {
int httpCode = https.GET();
Serial.println("============== Response code: " + String(httpCode));
if (httpCode > 0) {
Serial.println(https.getString());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
delay(5000);
}
import WiFiClientSecure.h
note how I set client.setInsecure(); which you shouldn't in your real code, rather us the root certificate of your end point as shown here https://github.com/esp8266/Arduino/blob/master/libraries/ESP8266WiFi/examples/HTTPSRequest/HTTPSRequest.ino#L29
you should URL-encode the data parameter like so String data = "Sunil%20Kumar%20Yadav"

How to read chunked http response in ESP32

Basically I want to develop code for sending a GET request to an API using ESP32 (Arduino framework).
However the HTTP response is going to be very large (JSON object), hence I have used the transfer encoding: chunked
header. My question is how to read and process the chunked response, the below code gives an the following
error:
Connecting to WiFi..
Connected to the WiFi network
-11
Error on HTTP request
-11
This error does not occour if the header is not added
#include<Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
const char* ssid = ""; // my access point
const char* password = ""; //my password
const String URL = ""; //the api url
void setup() {
Serial.begin(115200);
delay(4000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
//sw.begin(115200);
}
void loop() {
if ((WiFi.status() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin(URL); //Specify the URL
http.addHeader("Transfer-Encoding", "Chunked"); // for getting chunked data
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
String payload = http.getString();
Serial.println(httpCode);
Serial.println(payload);
}
else {
Serial.println(httpCode);
Serial.println("Error on HTTP request");
}
http.end();
}
delay(10000);
}

Sending a proper Post request from Arduino

I am trying to send a Post request from my Arduino Mega using the Ethernet shield, I tried already many many codes all over the internet but I haven't done yet
Also did it already from a NodeMCU-ESP8266 but I don't know why with the mega is getting so tricky
From this code everything goes well except that I never get the POST request, I am using this website 'requestcatcher' to test the POST request
#include <Ethernet.h>
#include <SPI.h>
// Conf. mac
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// Server to Post
char server[] = "http://abc.requestcatcher.com/test";
// Starting Ethernet client
EthernetClient client;
// =============== Connecting to internet =============== //
void setup() {
// Open serial communications and wait for port to open:
// wait for serial port to connect. Needed for native USB port only
Serial.begin(9600);
while (!Serial) {
;
}
// Connecting to internet
if (Ethernet.begin (mac) == 0) {
Serial.println("Can’t connect via DHCP");
}
// Give the Ethernet shield a second to initialize
delay(1000);
// Printing the IP Adress
Serial.print ("IP Address: ");
Serial.println(Ethernet.localIP());
}
/////============= Sending Post request ============= ////
void loop() {
Serial.println(" - Post request in process - ");
if (client.connect(server, 80) {
Serial.print(" Sending Post request ");
client.println("POST /test HTTP/1.1");
client.println("Host: abc.requestcatcher.com/");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: ");
client.println();
}
else {
Serial.println("Can’t reach the server");
}
// Wait 10 secs
delay(10000);
}
Arduino prints via serial something like this
IP Adress: 192.168.100.40
- Post request in process -
Sending Post request
- Post request in process -
Sending Post request
- Post request in process -
Sending Post request
So I think that means that the Arduino connects successfully to the internet and also 'client.connect(server, 80)' goes true since it prints 'Sending Post request', but I don't know why request catcher never gets any of the post requests, I tested 'requestcatcher' with online apps and as well with the NodeMCU and it gets the post request from all except the Arduino so I think something must be wrong around here:
client.println("POST /test HTTP/1.1");
client.println("Host: abc.requestcatcher.com/");
client.println("Content-Type: application/x-www-form-urlencoded");
client.println("Content-Length: ");
client.println();
Please help, any hint would be very helpful
You must to delete ; and close bracket in this part of code if (client.connect(server, 80); { => if (client.connect(server, 80)) {...}
I checked the protocol for the headers so here it's how finally worked
if (client.connect(server, 80)) {
Serial.print(" Sending Post request ");
client.println("POST /test HTTP/1.0");
client.println("Host: abc.requestcatcher.com");
client.println("Connection: close");
client.println("Content-Length: 0"); //------- I missed 0
client.println("Content-Type: application/x-www-form-urlencoded");
client.println(""); //------- I missed ""
Serial.println("Server response");
char c = client.read();
Serial.println(c);
client.stop();
}
Too bad that form the server response I get "⸮" when requestcatcher actually sends "request caught"I not very sure about the lines after the http request, Could you give a little push with that?.
but also and THIS IS VERY IMPORTANT I made a mistake right on the top, I didn't know that this would count as a typo but it does the server must be written this way otherwise the server will never get the POST request
char server[] = "abc.requestcatcher.com";
Avoid setting your server like this
char server[] ="http://abc.requestcatcher.com/test";
char server[] ="abc.requestcatcher.com/";

GPRS module sendTCPData returns 403 Forbidden server error

I'm trying to fetch data from web server using Arduino Uno. I'm using SIM800L module to connect via GPRS. Following is the code I used to connect to web server.
#include <gprs.h>
#include <SoftwareSerial.h>
char http_cmd[] = "GET canopussl.com/info.php HTTP/1.1\r\n\r\n";
char buffer[512];
GPRS gprs;
void setup() {
Serial.begin(9600);
while(!Serial);
Serial.println("GPRS - HTTP Connection Test...");
gprs.preInit();
while(0 != gprs.init()) {
delay(1000);
Serial.println("init error");
}
while(!gprs.join("dialogbb")) { //change "cmnet" to your own APN
Serial.println("Error joining GPRS network");
delay(2000);
}
// successful DHCP
Serial.print("IP Address is ");
Serial.println(gprs.getIPAddress());
Serial.println("Init success, connecting to canopussl.com ...");
if(0 == gprs.connectTCP("canopussl.com", 80)) {
Serial.println("Successfully connected to canopussl.com!");
}else{
Serial.println("connect error");
while(1);
}
Serial.println("waiting to fetch...");
if(0 == gprs.sendTCPData(http_cmd))
{
gprs.serialDebug();
}
gprs.closeTCP();
gprs.shutTCP();
Serial.println("close");
}
void loop() {
}
The output was this.
GPRS - HTTP Connection Test...
IP Address is 10.84.3.49
Init success, connecting to canopussl.com ...
Successfully connected to canopussl.com!
waiting to fetch...
HTTP/1.0 403 Forbidden
Cache-Control: no-cache
Connection: close
Content-Type: text/html
<html><body><h1>403 Forbidden</h1>
Request forbidden by administrative rules.
</body></html>
CLOSED
How I have to modify the HTTP header to receive the normal output from server?
You are not sending the mandatory Host header.
Your HTTP request should look like:
char http_cmd[] = "GET /info.php HTTP/1.1\r\nHost: canopussl.com\r\n\r\n";

Wemos D1 404 Not Found - but it is there

I am trying to connect my Wemos D1 to a website to get some data, but I am getting a 404 Not Found Error. I made sure that the url is correct, but I am stilling getting errors. I looked at the errors in the log, but they are empty.
#include <ESP8266WiFi.h>
const char* ssid = "SSID"; // SSID of local network
const char* password = "xxxxx"; // Password on network
String APIKEY = "xxxx";
WiFiClient client;
char servername[]="notreal.com"; // fake host for sample
String result;
int readKey;
int count;
int cursorPosition;
int button;
int x = 0;
void setup() {
//Setup Serial
Serial.begin(9600);
//Connecting to server and get current temperature and set temperature
lcd.print(" Connecting");
Serial.println("Connecting");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("NOT CONNECTED");
lcd.setCursor(cursorPosition,2);
lcd.print(".");
cursorPosition++;
}
getData();
//Serial.println("Connected");*/
delay(1000);
}
void loop() {
//Do Something
}
void getData() //client function to send/receive GET request data.
{
if (client.connect(servername, 80)) { //starts client connection, checks for connection
client.println("GET /data/getData.php?API="+APIKEY);
client.println("HTTP/1.1");
client.println("Host: notreal.com");
client.println("Connection: close");
client.println();
}
else {
Serial.println("connection failed"); //error message if no client connect
Serial.println();
}
while(client.connected() && !client.available()) delay(1); //waits for data
while (client.connected() || client.available()) { //connected or data available
char c = client.read(); //gets byte from ethernet buffer
result = result+c;
}
client.stop(); //stop client
result.replace('[', ' ');
result.replace(']', ' ');
Serial.println(result);
}
This is what I get in the serial:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /nest/getTemp.php was not found on this server.</p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
</body></html>
This is in the error log:
[host.com] [Fri Aug 05 03:57:33 2016] [error] [client 24.28.29.44] client denied by server configuration: /home/domains/host.com/.htaccess
I checked the server setting and according to support, everything should be set for remote access.

Resources