HTTP POST (Get works fine)

Hey Guys (and girls),

So like most people who start out here i’m having some issues.

I’m basically looking to issue a $_POST request to a page on my web server. When i’m posting if i do a full dump on the server end ( print_r($_POST) ) I’m getting a response of 1?

I can do a GET request without anyone issues. Can anyone take a look and see where i’m going wrong?

In the meantime i’m going to now have a play to see if I can save variables which last over a reboot, and read the HTTP response to the Photon.

String command = "var1=data1&var2=data2";

void setup()
{
  Particle.process();

    waitUntil(WiFi.ready);
    waitFor(Particle.connected, 10000);

  if (client.connect("www.myserver.com", 80))
  {
    
    client.println("POST /index.php/post/ HTTP/1.1");
    client.println("Host: www.myserver.com");
    client.printlnf("Content-Length: %d", command.length());
    client.println("Content-Type: text/plain");
    client.println();
    client.println(command);
    client.flush();
    
    Particle.publish("Data Sent");
  }
  else
  {
    Particle.publish("Connection Failed");
  }
}

Hi @JnyMris

Can you make the same request to the server using the command line tool curl? If so, you can add -v -v to get verbose output from curl and see the request.

Most likely the server wants to see more fields such as Accept: */* or a different content type such as application/x-www-form-urlencoded instead of text.

A way to debug the actual POST request is the use the service requestb.in where you can setup a temporary spot to post to and see the results in your web browser.

@bko Thank you for the super quick response and thank you for your time in helping with this,

This would make sense. I don’t have curl available unfortunately.

Although I have looked into this further and can see what you are saying would make sense.
Review my logs I can see where am i including

client.println(command); - My Web Server files the log as a 400 (bad request).
if i don’t include this the web server log files a 200.

I’ve boosted my Server logs and can see this bad boy:
AH02426: Request header field name is malformed: var1=data1&var2=data2

I’ve removed the & and just tried to pass var1=data but still no joy. I’ve also added the following (which appear to come off browser:

client.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
client.println("Content-Type: application/x-www-form-urlencoded");

But still no joy.

Trying with requestb.in I don’t get anything being populated using the following:

if (client.connect("requestb.in", 443))
  {
    
    client.println("POST /1749qaz1 HTTP/1.1");
    client.println("Host: requestb.in");
    client.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.printlnf("Content-Length: %d", command.length());
    client.println(command);
    client.println();
    client.flush();
    
    Particle.publish("Status","Data Sent");
  }

I feel like i’m missing something so simple here.

Hi @JnyMris

curl is available for every platform (Win/Mac/Linux/iOS/Android) and you should get it for sure. It's a great tool.

For the requestb.in: Port 443 is a SSL port like you would use for HTTPS, not plain HTTP. You don't have a SSL client so posting there isn't going to work. Try posting to port 80 instead. I bet that works.

For your actual server: if you want to pass things like var1=data1 you should use URL encoding as the content type and avoid sending funny characters (or actually URL encode them). Try sending a simple string like "var1=data1" and force the content length to be correct (10 in this case).

@bko Thank you again for the quick response.

So if i run curl with: (I’ve never used curl but here goes:
curl -v http://www.myserver.com/index.php/post --data var1=data1

I get a bunch of stuff back. Do i provide you with all of this? (I cut the top stuff out which are server specific)

> User-Agent: curl/7.52.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes
< HTTP/1.1 200 OK
< Date: Wed, 07 Feb 2018 21:51:04 GMT
< Server: Apache/2.4.18 (Ubuntu)
< Set-Cookie: ci_session=lf0qqa7mkok9ibhprbirosk5s1brm3nc; expires=Wed, 07-Feb-2018 23:51:04 GMT; Max-Age=7200; path=/; HttpOnly
< Expires: Thu, 19 Nov 1981 08:52:00 GMT
< Cache-Control: no-store, no-cache, must-revalidate
< Pragma: no-cache
< Content-Length: 45
< Content-Type: text/html; charset=UTF-8

By running the CURL status above it does pull the post data.

So now if I run:

[CODE]
if (client.connect(“www.myserver.com”, 80))
{

client.println("POST /index.php/post HTTP/1.1");
client.println("Host: www.myserver.com");
client.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
client.println("Content-Type: application/x-www-form-urlencoded");
client.printlnf("Content-Length: 10");
client.println("var1=data1");
client.println();
client.flush();

[/CODE]

I still get: a 400 - AH02426: Request header field name is malformed: var1=data1

curl has a million switches but I generally use this to POST:

 curl -X POST -d "var1=data1" -v http://www.myserver.com/rest_of_url

Which returns a bunch of stuff but the important part is:

> POST /17iun9e2 HTTP/1.1
> Host: requestb.in
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes

Requestb.in show that payload arrived just fine.

EDIT: One more thing: I think you need another blank line ( println(); ) between the content length and the body parameter (“var1=data1”).

1 Like

@bko
Wow,

So good news is it looks like the blank line is done the job.

When trying to connect with the curl method I do get: curl: (5) Could not resolve proxy: POST
.
With that the job is a good one. Thank you so much for your assistance. I just need to figure out how to read the response from the server now. I’m happy to give this a go.

Thank You so much !

1 Like

That is a capital-X in the curl command. Lowercase x sets the proxy.

Glad it is working for you--have fun.

1 Like