2

I started to work with HTTPClient and the WiFly library to connect to an SSID and then send POST data to a server. When I was sending the data to my localhost, it was working on localhost, but when changing the URL to a server I am getting this response:

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>openresty</center>
</body>
</html>

My code is the following:

#define HTTP_POST_URL "http://URL/insert.php"
#define HTTP_POST_DATA "181"
SoftwareSerial uart(2, 3);
WiFly wifly(uart);
HTTPClient client;
char get;

while (client.post(HTTP_POST_URL, HTTP_POST_DATA, 10000) < 0) {}

Looking at the constructor of POST in the HTTPClient library it is possible to use POST without defining the header and it will automatically create a default header:

int HTTPClient::post(const char *url, const char *data, int timeout)
{
  return connect(url, "POST", NULL, data, timeout);
}

int HTTPClient::post(const char *url, const char *headers, const char *data, int timeout)
{
  return connect(url, "POST", headers, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *data, int timeout)
{
  return connect(url, method, NULL, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *headers, const char *data, int timeout)
{
  char host[HTTP_MAX_HOST_LEN];
  uint16_t port;
  char path[HTTP_MAX_PATH_LEN];
  
  if (parseURL(url, host, sizeof(host), &port, path, sizeof(path)) != 0) {
    DBG("Failed to parse URL.\r\n");
    return -1;
  }
  
  if (!wifly->connect(host, port, timeout)) {
    DBG("Failed to connect.\r\n");
    return -2;
  }
  
  // Send request
  char buf[HTTP_MAX_BUF_LEN];
  snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\n", method, path);
  wifly->send(buf);
  
  // Send all headers
  snprintf(buf, sizeof(buf), "Host: %s\r\nConnection: close\r\n", host);
  wifly->send(buf);
  
  if (data != NULL) {
    snprintf(buf, sizeof(buf), "Content-Length: %d\r\nContent-Type: text/plain\r\n", strlen(data));
    wifly->send(buf);
  }
  
  if (headers != NULL) {
    wifly->send(headers);
  }
  
  // Close headers
  wifly->send("\r\n");
  
  // Send body
  if (data != NULL) {
    wifly->send(data);
  }
  
  return 0;
}

So I am not sure why it worked on localhost but on the hosting.

EDIT:

after logging it to console, this is the request I am sending:

POST /insert_gsr.php HTTP/1.1

Host: www.mywebsite.com
Connection: close

Content-Length: 3
Content-Type: text/plain

EDIT 2:

The example code: https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/wifly_http.ino

is also throwing the same error.

  • 1
    When you get a code 400 that means that you are reaching the server, but your request format is not correct. Without providing information about that endpoint we cannot say how the request has to look like. And what do you mean with sending to my localhost? Do you have code on that mimics the actual servers function? Or do you mean that you just get a code 200 with "it works"? Currently I don't see why localhost should be relevant here – chrisl Jan 17 '22 at 21:40
  • first I tested out the PHP script where I want to send my POST data on localhost using XAMPP, then I uploaded the same script to my server where it no longer works after I change the URL I am connecting to that of the server. You can see the request I am sending at the bottom of my question. I also used an online API tester tool where I sent the same format of the request as from the Arduino, where it works. – Chris Fodor Jan 17 '22 at 21:44
  • Since the code you posted works in 2 out of 3 cases, I would ask about the server code which it doesn’t work with and not the code you posted. I would also perform a test using curl against the script which your code can’t talk to. – romkey Jan 17 '22 at 22:19
  • So with localhost you mean your PC? Have you tested the PHP script on your server (without the Arduino; connecting from your PC to your server)? Did that work? – chrisl Jan 17 '22 at 22:23
  • Yes the localhost was an apache server running on my PC on the same WiFi the Arduino connected to. And yes, the script works when calling directly from the browser. My theory is that it worked local, because the request didn´t leave the gateway and the format request gets validated when talking to a remote server. Neverthless, the logged request looks valid to me. – Chris Fodor Jan 18 '22 at 08:20
  • The new link in your edit 2 doesn't work for me. Are you sure it is correct? – chrisl Jan 18 '22 at 10:59
  • Can you show us how you tested the php script with the request from your PC to your server? The error is definitely that the request is not correct and that might show us, what the difference is. – chrisl Jan 18 '22 at 11:00
  • I´ve have updated the link for the example. The example is also not working and getting the same errror, therefore it is not my PHP script that is not working. I think the library: https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/HTTPClient.cpp is not setting the correct headers, I tried to send more header details, like accept or user-agent but still getting incorrect request – Chris Fodor Jan 18 '22 at 11:58
  • if we can make the example from github work from edit 2, it will also work for my code, the library is quite old and I think its not setting headers according to today's standards and in my opinion, needs modification – Chris Fodor Jan 18 '22 at 11:59
  • Do the headers really have blank lines in there, or is that just an artefact of logging? – Majenko Jan 18 '22 at 14:34
  • its just the log. Each line ends with \r\n – Chris Fodor Jan 18 '22 at 18:54
  • Please show us how exactly you have done the successful test from your PC. You obviously don't build the correct request, but we cannot really help you unless we know how exactly the request has to look. If we got the request that works and the one that doesn't work side by side we would look for differences. And what headers are needed depends on your server setup (which you didn't show) and not on the Arduino code. – chrisl Jan 18 '22 at 21:24
  • The request is built here: https://github.com/Seeed-Studio/WiFi_Shield/blob/master/Examples/wifly_http/HTTPClient.cpp and I believe if we can make the example code work in edit 2 (a request for HTTP bin site), it will also work for my server, as it seems to be the common problem. The entire project can be downloaded and tested from the linked GitHub repository. So if you can make the code work from EDIT 2, it will also work for me as only the destination URL was changed in my code. I tried it with no luck. – Chris Fodor Jan 18 '22 at 21:57
  • @chrisfodor Did you get this to work? I had a similar problem with httpclient due to the target URL being out on the internet and I had not told httpclient the gateway IP, umask etc. – kiwiron Mar 04 '22 at 05:03
  • @kiwiron no, I did not get this to work, I turned my attention away from the problem and I will be using localhost, but communicating with a server would be better. – Chris Fodor Mar 19 '22 at 17:59

0 Answers0