GDP group 24 node core
Dependencies: EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue
http.cpp
- Committer:
- Trumple
- Date:
- 2015-01-28
- Revision:
- 31:9cf3f1e5ad68
- Parent:
- 27:61e67ab47da5
File content as of revision 31:9cf3f1e5ad68:
#include "mbed.h"
#include "http.h"
#include <string>
#include <vector>
void http::connect()
{
#ifdef DEBUG
printf("[HTTP] Ethernet connecting...\r\n");
#endif
eth.init();
eth.connect();
#ifdef DEBUG
printf("[HTTP] Ethernet connected, IP: %s\r\n", eth.getIPAddress());
#endif
}
bool http::isEthernetConnected()
{
return string(eth.getIPAddress()).size() > 0;
}
string http::get(string address, int port, string url, int replyTimeout)
{
#ifdef DEBUG
printf("[HTTP] Sending GET request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
#endif
TCPSocketConnection sock;
sock.connect(address.c_str(), port);
#ifdef DEBUG
printf("[HTTP] Connected to endpoint...\r\n");
#endif
string httpget = "GET " + url + " HTTP/1.1";
httpget += "\nHost: " + address + "\n\n";
//get a writable char* (I.E. not const char* returned by c_str), put it into a vector
vector<char> writable(httpget.begin(), httpget.end());
writable.push_back('\0');
sock.send_all(&writable[0], writable.size()-1);
string message = this->receiveFromSock(sock, replyTimeout);
sock.close();
return this->parse(message);
}
string http::post(string address, int port, string url, string jsonPayload, int replyTimeout)
{
#ifdef DEBUG
printf("[HTTP] Sending POST request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
#endif
TCPSocketConnection sock;
sock.connect(address.c_str(), port);
#ifdef DEBUG
printf("[HTTP] Connected to endpoint...\r\n");
#endif
char buffer[20];
sprintf(buffer, "%i", jsonPayload.size());
string contentLengthStr = string(buffer);
string httppost = "POST " + url + " HTTP/1.1";
httppost += "\nHost: " + address;
httppost += "\nContent-Type: application/json";
httppost += "\nContent-Length: " + contentLengthStr;
httppost += "\nAuthorization: Key 1";
httppost += "\n\n" + jsonPayload;
//to get a writable char* (I.E. not const char* returned by string.c_str), put it into a vector
vector<char> writable(httppost.begin(), httppost.end());
writable.push_back('\0');
sock.send_all(&writable[0], writable.size()-1);
string message = this->receiveFromSock(sock, replyTimeout);
sock.close();
return this->parse(message);
}
string http::receiveFromSock(TCPSocketConnection sock, int replyTimeout)
{
char buffer[1024];
int receiveByteCount;
string message;
bool headersSet = false;
int contentLength = -1;
string responseBody;
string contentLengthNeedle = "Content-Length: ";
while (true)
{
receiveByteCount = sock.receive(buffer, sizeof(buffer)-1);//spare a byte for null termination byte
//if the connection is closed by the remote client
if (receiveByteCount <= 0)
break;
buffer[receiveByteCount] = '\0';
message += buffer;
//if the response header has been received and includes the required headers
if (!headersSet && message.find("\r\n\r\n") != string::npos && message.find(contentLengthNeedle) != string::npos)
{
//headers have been fully received, ensure this check is not performed again
headersSet = true;
//end point of the "Content-Length: " string, beginning of the integer it specifies
int cl = message.find(contentLengthNeedle) + contentLengthNeedle.size();
//extract the content length from the header
string length = message.substr(cl, message.find_first_of("\r\n", cl) - cl);
contentLength = atoi(length.c_str());
}
//if the headers have been set, extract the message body
if (headersSet)
responseBody = message.substr(message.find("\r\n\r\n"), contentLength);
//if the response body is of the expected length, we're done
if (responseBody.size() >= contentLength)
break;
}
return message;
}
string http::parse(string httpReply)
{
int payloadBegin = httpReply.find("\r\n\r\n");
if (payloadBegin > -1)
{
string payload(httpReply.begin() + payloadBegin + 4, httpReply.end());
return payload;
}
else
{
return "";
}
}
