Ethernet Shield + HTML Form POST

I am wondering if there is any way to read the post values of the Ethernet Shield's server. I am able to successfully use GET variables from the browser directly to the server, but I can not get the value of POST variables from a different server to the Ethernet Shield server. Does anyone know if this is possible and if so, how?

HTML Form (stored on separate Ubuntu server, not Arduino) https://github.com/Arduinology/Arduino-Home-Automation/blob/master/index.php Line 26-29 is the form that submits a POST of "0=1",

Arduino Code: https://github.com/Arduinology/Arduino-Home-Automation/blob/master/HomeAutomation/HomeAutomation.pde Line 79 starts the function that is supposed to read POST and GET values.

Full Project Code: https://github.com/Arduinology/Arduino-Home-Automation

Issue with POST: POST / HTTP/1.1 Host: 192.168.1.202 Connection: keep-alive Content-Length: 3 Cache-Control: max-age=0 Origin: http://localhost User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 Content-Type: application/x-www-form-urlencoded Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Referer: http://localhost/Arduino-Home-Automation/index.php Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

You can clearly see that Content-Length is 3, this changes with the length of the form POST, so if POST was 11=1 then Content-Length would be 4.

Works with GET Now when I user the url such as 192.168.1.202/?0=1 I am presented with: GET /?0=1 HTTP/1.1 Host: 192.168.1.202 Connection: keep-alive User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/14.0.835.202 Safari/535.1 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8 Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 0

Clearly you can see that the get value is easily readable from the output above. Any ideas why POST does not work like this?

After you send the POST or GET stuff, you send a double CR-LF. With a POST, then you send your variables. I changed O to test. Something like this:

client.write("POST / HTTP/1.1\r\nHost: 192.168.1.202\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 6\r\n\r\n")
client.write("test=1");

I forgot the server side. The variables shold be after the double CR-LF in all that.

SurferTim: After you send the POST or GET stuff, you send a double CR-LF. With a POST, then you send your variables. I changed O to test. Something like this:

client.write("POST / HTTP/1.1\r\nHost: 192.168.1.202\r\nContent-Type: application/x-www-form-urlencoded\r\nContent-Length: 6\r\n\r\n")
client.write("test=1");

The post is being sent from a PHP file that has an HTML form, not from the Arduino Web Server. I am not writing the output, I am doing client.print to get the result I posted above.

I was editing my last post about the server side.

The variables should be after the double CR-LF following that header stuff. It isn't? Some server code stops reading when it gets the "empty line". POST needs to read at least one more line.

SurferTim: I was editing my last post about the server side.

The variables should be after the double CR-LF following that header stuff. It isn't? Some server code stops reading when it gets the "empty line". POST needs to read at least one more line.

I think I understand what you are talking about, I will tweak the code a bit later today and post additional feedback. Thanks for your help thus far.

This is from the webserver example for the ethernet shield

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http GET request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {

// You need to read another line to get the variables for a POST request, then

          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
void checkForClient(char *buf){
  memset(buf, 0, 16);
  int i = 0;
  Client client = server.available();
  if (client) {
    boolean currentLineIsBlank = true;
    boolean sentHeader = false;
    while (client.connected()) {
      if (client.available()) {
        if(!sentHeader){
          // send a standard http response header
          [b]client.println("HTTP/1.1eman 200 OK");
          client.println("Content-Type: text/html");
          client.println();[/b]
          sentHeader = true;
        }
        [b]char c = client.read();[/b]
        client.print(c);
        if(reading && c == ' ') reading = false;
        if(c == '?') reading = true; //found the ?, begin reading the info
        if(reading){
          buf[i] = c;
          i++;
        }
        [b]if (c == '\n' && currentLineIsBlank)  break;
        if (c == '\n') {
          currentLineIsBlank = true;
        }
        else if (c != '\r') {
          currentLineIsBlank = false;
        }[/b]
      }
    }
    delay(5);
    setValues(buf, client);
    client.println("
");
    automation1(pin_id, value, client);
    client.stop();
  } 
}

I use all of that, and then my own code to get the functionality I am looking for.

This leaves the read loop here. Nothing after the "empty line" is read. Replace this:

if (c == '\n' && currentLineIsBlank)  break;

with something like this:

if (c == '\n' && currentLineIsBlank)
{
// it is after the double cr-lf that the variables are
// read another line!
   while(client.available())
   {
      c = client.read();
      // save the variables somewhere
   }
   break;
}

Great, worked like a charm. Thank you for this. Project is back on track.

Great, worked will appreciate!! Thanks!!