httpServer example program for WIZwiki-W7500 Only LED control
Dependents: httpServer-WIZwiki-W7500
This library is for HTTP server.
Refer to Example program(https://developer.mbed.org/teams/WIZnet/code/httpServer-WIZwiki-W7500/)
Diff: HTTPConnection.cpp
- Revision:
- 0:e59cc54df17c
- Child:
- 1:772534e3b627
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPConnection.cpp Mon Jun 29 09:03:40 2015 +0000
@@ -0,0 +1,287 @@
+/* HTTPConnection.cpp */
+
+#include "mbed.h"
+#include "HTTPConnection.h"
+//#define DEBUG
+#include "hl_debug.h"
+
+#include <vector>
+using std::vector;
+
+using std::string;
+
+
+
+const struct HTTPRequestConfig {
+ const char* request_string;
+ HTTPRequestType request_type;
+} g_requestConfig[] = {
+ { "GET", HTTP_RT_GET },
+ { "POST", HTTP_RT_POST},
+ { "PUT", HTTP_RT_PUT},
+ { "OPTIONS",HTTP_RT_OPTIONS},
+ { "HEAD", HTTP_RT_HEAD},
+ { "DELETE", HTTP_RT_DELETE},
+ { "TRACE", HTTP_RT_TRACE},
+ { "CONNECT",HTTP_RT_CONNECT}
+};
+
+
+HTTPConnection::HTTPConnection(TCPSocketConnection& clnt) : m_Tcp(clnt)
+{
+}
+
+
+HTTPConnection::~HTTPConnection()
+{
+ close();
+}
+
+void HTTPConnection::close()
+{
+ m_Msg.headers.clear();
+}
+
+int HTTPConnection::poll()
+{
+ static char buffer[256] = {};
+ int rcvd= 0;
+ int ret = 0;
+ int attri_len = 0;
+
+ INFO("Waiting for new data in connection");
+ // Try receiving request line
+ rcvd = receiveLine(buffer, 255, 3000);
+ if (rcvd == -1) {
+ // there was an error, probably the connection was closed, so close this connection as well
+ INFO("No more data available. Will close this connection now.");
+ close();
+ return -1;
+ }
+
+ // The Request has not yet been received so try it
+ rcvd = parse(buffer);
+ if (rcvd == -1) {
+ // Invalid content received, so close the connection
+ INFO("Invalid message received, so sending negative response and closing connection !");
+ //sprintf(buffer,"HTTP/1.1 400 BadRequest\n\rContent-Length: %d\n\rContent-Type: text\n\r\n\r\n\r",0);
+ m_Tcp.set_blocking(true, 1500);
+ //m_Tcp.send(buffer,strlen(buffer));
+ close();
+ rcvd = -1;
+ return -1;
+ }
+ // The request has been received, try receive the body
+ while(rcvd > 0) {
+ rcvd = receiveLine((char*)buffer, 255, 3000);
+ // First check if we received an empty line. This would indicate the end of the message or message body.
+ if (rcvd < 0) {
+ // there was an empty line, so we can start with performing the request
+ INFO("Request Header was received completely. Performing request.");
+ rcvd = 0;
+ break;
+ }
+ else {
+ // add message body
+ ret = parseHeader(buffer);
+ if (ret == 0) {
+
+ }
+ else {
+ attri_len = ret;
+ }
+ }
+ }
+
+ //Receive attribute data
+ if( attri_len != 0 )
+ {
+ m_Tcp.receive( m_Msg.attri, attri_len );
+ }
+
+ INFO("Leaving poll function!");
+ return rcvd;
+}
+
+int HTTPConnection::receiveLine(char* szLine, int nMaxLen, int nTimeout, char cLineTerm)
+{
+ if ((szLine == NULL) || (nMaxLen == 0))
+ return -1;
+
+ szLine[0] = 0;
+ m_Tcp.set_blocking(false);
+
+ if (!m_Tcp.is_connected()) {
+ error("NOT COnnected anymore");
+ return -1;
+ }
+ Timer tm;
+ int i;
+
+ // Try to receive up to the max number of characters
+ for (i = 0 ; i < nMaxLen-1 ; i++) {
+ int c;
+ c = m_Tcp.receive( szLine + i, 1 );
+ // Check that - if no character was currently received - the timeout period is reached.
+ if ((c == 0) || (c==-1)) {
+ // no character was read, so check if operation timed out
+ if (tm.read_ms() > nTimeout) {
+ // Operation timed out
+ INFO("Timeout occured in function 'receiveLine'.");
+ return -1;
+ }
+ }
+
+ // Check if line terminating character was received
+ if (szLine[i] == cLineTerm)
+ {
+ break;
+ }
+ }
+
+ // Terminate with \0
+ szLine[i] = 0;
+
+ // Trim for '\r' linefeed at the end
+ if( (i >0) && (szLine[i-1] == '\r')) {
+ i--;
+ szLine[i] = 0;
+ }
+
+ // return number of characters received in the line or return -2 if an empty line was received
+ if ((i == 0) || ((i==1) &&(szLine[0] == '\r')))
+ {
+ // empty line received, so return -2
+ return -2;
+ }
+ return i;
+}
+
+int HTTPConnection::parse(char* buffer)
+{
+ // Check if buffer is invalid or its content not long enough.
+ if ((buffer == NULL) || (strlen(buffer) < 4)) {
+ ERR("Buffer content is invalid or too short.");
+ return -1;
+ }
+
+ std::vector<std::string> args;
+ args.clear();
+
+ int argno = 0;
+ // decompose string into a list of arguments
+ char s = 0; // current starting char
+ int nLen = strlen(buffer)+1;
+
+
+ //for(int i = 0; i < nLen; i++)
+ //printf("%d : %c\r\n", i, buffer[i]);
+
+
+ for (int i = 0 ; i < nLen ; i++) {
+ if ((buffer[i] == ' ') || (buffer[i] == '\n') || (buffer[i] == 0)) {
+ // new arg found
+ buffer[i] = 0;
+ if (argno++ == 1) {
+ // its the uri
+ // parse the uri args
+ parseUriArgs(&buffer[s], m_Msg.args);
+ }
+ INFO("Found argument \"%s\"", &buffer[s]);
+ args.push_back(&buffer[s]);
+ s = i+1;
+ }
+ }
+
+ // store the uri and the HTTP version
+ m_Msg.uri = args[1];
+ m_Msg.version = args[2];
+
+ // Find matching request type
+ for (int i = 0 ; i < sizeof(g_requestConfig)/sizeof(struct HTTPRequestConfig) ; i++) {
+ if (args.at(0) == g_requestConfig[i].request_string) {
+ m_Msg.request = g_requestConfig[i].request_type;
+ }
+ }
+ args.clear();
+
+ return 1;
+}
+
+
+int HTTPConnection::parseHeader(char *buffer)
+{
+ // Check if the buffer is invalid or if the content is too short to be meaningful
+ if ((strlen(buffer) <3) || (buffer == NULL))
+ return -1;
+
+ //Find Content length
+ if(strncmp(buffer, "Content-Length", 14) == 0)
+ {
+ m_Msg.attri_len = atoi(&buffer[16]);
+ return m_Msg.attri_len;
+ }
+ /*
+ for (int i = 0 ; i < buflen ; i++) {
+ if (buffer[i] == ':') {
+ // touple found
+ buffer[i] = 0;
+ value_start = i+1;
+ m_Msg.headers[buffer] = &buffer[value_start];
+
+ INFO("Header name=\"%s\" : value=\"%s\".", buffer, &buffer[value_start]);
+ return 0;
+ }
+ }
+ */
+ return 0;
+ //ERR("Did not recieve a valid header : \"%s\".", buffer);
+ //return -1;
+}
+
+int HTTPConnection::parseUriArgs(char *buffer, map<string,string>&args)
+{
+ // Check if the buffer is invalid or if the content is too short to be meaningful
+ if ((strlen(buffer) <3) || (buffer == NULL))
+ return -1;
+
+ int args_start = -1;
+ int value_start = -1;
+ int buflen = strlen(buffer) +1;
+ const char* argname = NULL;
+ const char* valuename = NULL;
+ for (int i = 0; i < buflen ; i++) {
+ if (args_start == -1) { // args section not yet found
+ if (buffer[i] == '?') { // starts with a question mark, so got it
+ buffer[i] = 0;
+ args_start = i; // set the start of the args section
+ INFO("Argument section found !");
+ }
+ }
+ else { // search arg-value touples
+ if (argname == NULL) { // arg-name found ?
+ if (buffer[i] == '=') {
+ // yes, separate the arg-name
+ buffer[i] = 0;
+ argname = &buffer[args_start];
+ value_start = i+1;
+ INFO("Argument name %s", argname);
+ }
+ }
+ else { // search for end of value
+ if ((buffer[i] == '&') || (buffer[i] == 0) || (buffer[i] == '\r') || (buffer[i] == '\n')) {
+ buffer[i] = 0;
+ valuename = &buffer[value_start];
+ INFO("Argument value %s", valuename);
+ args[argname] = valuename;
+ // reset all indicators
+ argname = NULL;
+ valuename = NULL;
+ }
+ }
+ }
+ }
+
+
+ return 0;
+}