Receiving a http POST Message?

Is it possible to get the POST payload from an HTTP POST message into an arduino + ethernet shield? Technically, I'm using a ethernet pro from sparkfun, but same difference. I can receive the message but don't know how to access the payload component. Appreciate any pointers.

The POST data is in the body of the POST request. It is after the empty line.
Here is a webserver program. I added a comment and serial output where the POST data is retrieved.

/*
A simple web server using an Arduino Wiznet Ethernet shield. 
For Arduino IDE V1.0 only. Previous IDE versions require mods to this code.

Original code created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe
 modified 18 Jan 2012
 by Tim Dicus 
*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,1,10 );
IPAddress gateway( 192,168,1,1 );
IPAddress subnet( 255,255,255,0 );
IPAddress dns( 192,168,1,1 );

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

void setup()
{
  Serial.begin(9600);

  // set SPI SS pins on w5100 and SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // start the SD interface here if you want.
  // Add the SD.h library above
  // SD.begin(4);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  // disable w5100 SPI so SD SPI can work with it
  digitalWrite(10,HIGH);
  delay(2000);
  server.begin();

  Serial.println("setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while(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 request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {

// Here is where the POST data is.  
          while(client.available())
          {
             Serial.write(client.read());
          }
          Serial.println();

          Serial.println("Sending response");
          // send a standard http response header
          client.println("HTTP/1.0 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML><BODY>TEST OK!</BODY></HTML>");
          client.stop();
        }
        else if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    Serial.println("Disconnected");
  }
}

Edit: I change Serial.print() to Serial.write(). The print may display a decimal ASCII code for each character.

Sorry so long to respond back - thanks SurferTim, that seems to be just the ticket. But I am still a bit confused. The POST content is in binary it appears and I'm not sure what I need to do to actually work with the payload. In my case the POST payload is a json object/string that I need to parse and extract specific values from but the first step is that I need to convert from the binary format into an ascii format - I suspect I need to use the atoi function, but am not understanding how to use atoi on the characters.

Thanks

Did you change the Serial.print() to Serial.write()?

POST content is not in binary. It is in ASCII.

I added a form to the posted code so a browser can be used to send post data and the serial monitor can be used to see what is received by the arduino.

/*
A simple web server using an Arduino Wiznet Ethernet shield. 
For Arduino IDE V1.0 only. Previous IDE versions require mods to this code.

Original code created 18 Dec 2009
 by David A. Mellis
 modified 4 Sep 2010
 by Tom Igoe
 modified 18 Jan 2012
 by Tim Dicus 
*/

#include <SPI.h>
#include <Ethernet.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip( 192,168,1,102 );
IPAddress gateway( 192,168,1,1 );
IPAddress subnet( 255,255,255,0 );
IPAddress dns( 192,168,1,1 );

// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(84);

void setup()
{
  Serial.begin(9600);

  // set SPI SS pins on w5100 and SD
  pinMode(10,OUTPUT);
  digitalWrite(10,HIGH);
  pinMode(4,OUTPUT);
  digitalWrite(4,HIGH);

  // start the SD interface here if you want.
  // Add the SD.h library above
  // SD.begin(4);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, dns, gateway, subnet);
  // disable w5100 SPI so SD SPI can work with it
  digitalWrite(10,HIGH);
  delay(2000);
  server.begin();

  Serial.println("setup finished");
}

void loop()
{
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("Client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      while(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 request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {

// Here is where the POST data is.  
          while(client.available())
          {
             Serial.write(client.read());
          }
          Serial.println();

          Serial.println("Sending response");
          // send a standard http response header
          client.println("HTTP/1.0 200 OK");
          client.println("Content-Type: text/html");
          client.println();
          client.println("<HTML><BODY>TEST OK!");
          
          
//form added to send data from browser and view received data in serial monitor          
client.println("<FORM ACTION=\"http://192.168.1.102:84\" METHOD=\"post\">");
client.println("Name: <INPUT TYPE=\"TEXT\" NAME=\"Name\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\">
");
client.println("Email: <INPUT TYPE=\"TEXT\" NAME=\"Email\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\">
");
client.println("<INPUT TYPE=\"SUBMIT\" NAME=\"submit\" VALUE=\"Sign Me Up!\">");
client.println("</FORM>");
client.println("
");
          
          client.stop();
        }
        else if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    Serial.println("Disconnected");
  }
}

got it - thanks for the help.

Nice addition zoomkat

here's what I'm really trying to do incase you guys are feeling ambitious!

I'd like to create a module that works like the router layers do in node.js. The idea is that you can associate a url path with a specific function and just pass the request and response. I'd like to be able to separate out various methods to specialized handlers - e.g. post, get, etc - this is mostly for json.

pseudo code would look something like this
// this code would be in the setup block after then ethernet bit was enabled
router = Router(ethernet);
router.addRoute('/hmauto/lights',PUT,funcHandleLights );
router.addRoute('/hmauto/sound/volume',PUT,funcHandleSoundVol );

// inside of the loop
router.check(); // this would contain the client connection string functionality

// then the specific functions
function funcHandleLights(Request, Response) {
// code to handle lights request
}

function funcHandleSoundVol(Request, Response) {
// code to handle sound request
}

in a nutshell you can think of this is a little attempt at building node.js like functionality into an arduino…

Anyway, thanks again for the help!

Someone have a way to do that? Couldn't find a library that work like this.

wenger:
got it - thanks for the help.

Nice addition zoomkat

here's what I'm really trying to do incase you guys are feeling ambitious!

I'd like to create a module that works like the router layers do in node.js. The idea is that you can associate a url path with a specific function and just pass the request and response. I'd like to be able to separate out various methods to specialized handlers - e.g. post, get, etc - this is mostly for json.

pseudo code would look something like this
// this code would be in the setup block after then ethernet bit was enabled
router = Router(ethernet);
router.addRoute('/hmauto/lights',PUT,funcHandleLights );
router.addRoute('/hmauto/sound/volume',PUT,funcHandleSoundVol );

// inside of the loop
router.check(); // this would contain the client connection string functionality

// then the specific functions
function funcHandleLights(Request, Response) {
// code to handle lights request
}

function funcHandleSoundVol(Request, Response) {
// code to handle sound request
}

in a nutshell you can think of this is a little attempt at building node.js like functionality into an arduino…

Anyway, thanks again for the help!