GDP group 24 node core

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers http.cpp Source File

http.cpp

00001 #include "mbed.h"
00002 #include "http.h"
00003 #include <string>
00004 #include <vector>
00005 
00006 void http::connect()
00007 {
00008     #ifdef DEBUG
00009         printf("[HTTP] Ethernet connecting...\r\n");
00010     #endif
00011     
00012     eth.init();
00013     eth.connect();
00014     
00015     #ifdef DEBUG
00016         printf("[HTTP] Ethernet connected, IP: %s\r\n", eth.getIPAddress());
00017     #endif
00018 }
00019 
00020 bool http::isEthernetConnected()
00021 {
00022     return string(eth.getIPAddress()).size() > 0;
00023 }
00024 
00025 string http::get(string address, int port, string url, int replyTimeout)
00026 {
00027     #ifdef DEBUG
00028         printf("[HTTP] Sending GET request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
00029     #endif
00030     
00031     TCPSocketConnection sock;
00032     sock.connect(address.c_str(), port);
00033     
00034     #ifdef DEBUG
00035         printf("[HTTP] Connected to endpoint...\r\n");
00036     #endif
00037     
00038     string httpget = "GET " + url + " HTTP/1.1";
00039     httpget += "\nHost: " + address + "\n\n";
00040     
00041     //get a writable char* (I.E. not const char* returned by c_str), put it into a vector 
00042     vector<char> writable(httpget.begin(), httpget.end());
00043     writable.push_back('\0');
00044     
00045     sock.send_all(&writable[0], writable.size()-1);
00046     
00047     string message = this->receiveFromSock(sock, replyTimeout);
00048       
00049     sock.close();
00050     
00051     return this->parse(message);
00052 }
00053 
00054 string http::post(string address, int port, string url, string jsonPayload, int replyTimeout)
00055 {   
00056     #ifdef DEBUG
00057         printf("[HTTP] Sending POST request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
00058     #endif
00059     
00060     TCPSocketConnection sock;
00061     sock.connect(address.c_str(), port);
00062     
00063     #ifdef DEBUG
00064         printf("[HTTP] Connected to endpoint...\r\n");
00065     #endif
00066     
00067     char buffer[20];
00068     sprintf(buffer, "%i", jsonPayload.size());
00069     string contentLengthStr = string(buffer);
00070     
00071     string httppost = "POST " + url + " HTTP/1.1";
00072     httppost += "\nHost: " + address;
00073     httppost += "\nContent-Type: application/json";
00074     httppost += "\nContent-Length: " + contentLengthStr;
00075     httppost += "\nAuthorization: Key 1";
00076     httppost += "\n\n" + jsonPayload;
00077     
00078     //to get a writable char* (I.E. not const char* returned by string.c_str), put it into a vector 
00079     vector<char> writable(httppost.begin(), httppost.end());
00080     writable.push_back('\0');
00081     
00082     sock.send_all(&writable[0], writable.size()-1);
00083     
00084     string message = this->receiveFromSock(sock, replyTimeout);
00085     
00086     sock.close();
00087     
00088     return this->parse(message);
00089 }
00090 
00091 string http::receiveFromSock(TCPSocketConnection sock, int replyTimeout)
00092 {
00093     char buffer[1024];
00094     int receiveByteCount;
00095     string message;
00096     
00097     bool headersSet = false;
00098     int contentLength = -1;
00099     string responseBody;
00100     
00101     string contentLengthNeedle = "Content-Length: ";
00102     
00103     while (true)
00104     {
00105         receiveByteCount = sock.receive(buffer, sizeof(buffer)-1);//spare a byte for null termination byte
00106         
00107         //if the connection is closed by the remote client
00108         if (receiveByteCount <= 0)
00109             break;
00110             
00111         buffer[receiveByteCount] = '\0';
00112         message += buffer;
00113         
00114         //if the response header has been received and includes the required headers
00115         if (!headersSet && message.find("\r\n\r\n") != string::npos && message.find(contentLengthNeedle) != string::npos)
00116         {
00117             //headers have been fully received, ensure this check is not performed again
00118             headersSet = true;
00119             //end point of the "Content-Length: " string, beginning of the integer it specifies
00120             int cl = message.find(contentLengthNeedle) + contentLengthNeedle.size();
00121             //extract the content length from the header
00122             string length = message.substr(cl, message.find_first_of("\r\n", cl) - cl);
00123             contentLength = atoi(length.c_str());
00124         }
00125         
00126         //if the headers have been set, extract the message body
00127         if (headersSet)
00128             responseBody = message.substr(message.find("\r\n\r\n"), contentLength);
00129         
00130         //if the response body is of the expected length, we're done
00131         if (responseBody.size() >= contentLength)
00132             break;
00133     }
00134     
00135     return message;
00136 }
00137 
00138 string http::parse(string httpReply)
00139 {
00140     int payloadBegin = httpReply.find("\r\n\r\n");
00141     if (payloadBegin > -1)
00142     {
00143         string payload(httpReply.begin() + payloadBegin + 4, httpReply.end());
00144         
00145         return payload;
00146     }
00147     else
00148     {
00149         return "";
00150     }
00151 }