GDP group 24 node core

Dependencies:   EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue

Committer:
Trumple
Date:
Wed Jan 28 21:19:52 2015 +0000
Revision:
31:9cf3f1e5ad68
Parent:
27:61e67ab47da5
Marge master branch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Trumple 1:27b35752c5d0 1 #include "mbed.h"
Trumple 1:27b35752c5d0 2 #include "http.h"
Trumple 1:27b35752c5d0 3 #include <string>
Trumple 1:27b35752c5d0 4 #include <vector>
Trumple 1:27b35752c5d0 5
Trumple 2:1cbb20dd1733 6 void http::connect()
Trumple 1:27b35752c5d0 7 {
Trumple 1:27b35752c5d0 8 #ifdef DEBUG
Trumple 1:27b35752c5d0 9 printf("[HTTP] Ethernet connecting...\r\n");
Trumple 1:27b35752c5d0 10 #endif
Trumple 1:27b35752c5d0 11
Trumple 1:27b35752c5d0 12 eth.init();
Trumple 1:27b35752c5d0 13 eth.connect();
Trumple 1:27b35752c5d0 14
Trumple 1:27b35752c5d0 15 #ifdef DEBUG
Trumple 1:27b35752c5d0 16 printf("[HTTP] Ethernet connected, IP: %s\r\n", eth.getIPAddress());
Trumple 1:27b35752c5d0 17 #endif
Trumple 1:27b35752c5d0 18 }
Trumple 1:27b35752c5d0 19
Trumple 27:61e67ab47da5 20 bool http::isEthernetConnected()
Trumple 27:61e67ab47da5 21 {
Trumple 27:61e67ab47da5 22 return string(eth.getIPAddress()).size() > 0;
Trumple 27:61e67ab47da5 23 }
Trumple 27:61e67ab47da5 24
Trumple 1:27b35752c5d0 25 string http::get(string address, int port, string url, int replyTimeout)
Trumple 1:27b35752c5d0 26 {
Trumple 1:27b35752c5d0 27 #ifdef DEBUG
Trumple 2:1cbb20dd1733 28 printf("[HTTP] Sending GET request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
Trumple 1:27b35752c5d0 29 #endif
Trumple 1:27b35752c5d0 30
Trumple 1:27b35752c5d0 31 TCPSocketConnection sock;
Trumple 1:27b35752c5d0 32 sock.connect(address.c_str(), port);
Trumple 1:27b35752c5d0 33
Trumple 1:27b35752c5d0 34 #ifdef DEBUG
Trumple 1:27b35752c5d0 35 printf("[HTTP] Connected to endpoint...\r\n");
Trumple 1:27b35752c5d0 36 #endif
Trumple 1:27b35752c5d0 37
Trumple 1:27b35752c5d0 38 string httpget = "GET " + url + " HTTP/1.1";
Trumple 1:27b35752c5d0 39 httpget += "\nHost: " + address + "\n\n";
Trumple 1:27b35752c5d0 40
Trumple 1:27b35752c5d0 41 //get a writable char* (I.E. not const char* returned by c_str), put it into a vector
Trumple 1:27b35752c5d0 42 vector<char> writable(httpget.begin(), httpget.end());
Trumple 1:27b35752c5d0 43 writable.push_back('\0');
Trumple 1:27b35752c5d0 44
Trumple 1:27b35752c5d0 45 sock.send_all(&writable[0], writable.size()-1);
Trumple 1:27b35752c5d0 46
Trumple 1:27b35752c5d0 47 string message = this->receiveFromSock(sock, replyTimeout);
Trumple 1:27b35752c5d0 48
Trumple 1:27b35752c5d0 49 sock.close();
Trumple 1:27b35752c5d0 50
Trumple 1:27b35752c5d0 51 return this->parse(message);
Trumple 1:27b35752c5d0 52 }
Trumple 1:27b35752c5d0 53
Trumple 1:27b35752c5d0 54 string http::post(string address, int port, string url, string jsonPayload, int replyTimeout)
Trumple 1:27b35752c5d0 55 {
Trumple 1:27b35752c5d0 56 #ifdef DEBUG
Trumple 2:1cbb20dd1733 57 printf("[HTTP] Sending POST request to %s:%i%s\r\n", address.c_str(), port, url.c_str());
Trumple 1:27b35752c5d0 58 #endif
Trumple 1:27b35752c5d0 59
Trumple 1:27b35752c5d0 60 TCPSocketConnection sock;
Trumple 1:27b35752c5d0 61 sock.connect(address.c_str(), port);
Trumple 1:27b35752c5d0 62
Trumple 1:27b35752c5d0 63 #ifdef DEBUG
Trumple 1:27b35752c5d0 64 printf("[HTTP] Connected to endpoint...\r\n");
Trumple 1:27b35752c5d0 65 #endif
Trumple 1:27b35752c5d0 66
Trumple 2:1cbb20dd1733 67 char buffer[20];
Trumple 2:1cbb20dd1733 68 sprintf(buffer, "%i", jsonPayload.size());
Trumple 2:1cbb20dd1733 69 string contentLengthStr = string(buffer);
Trumple 1:27b35752c5d0 70
Trumple 1:27b35752c5d0 71 string httppost = "POST " + url + " HTTP/1.1";
Trumple 1:27b35752c5d0 72 httppost += "\nHost: " + address;
Trumple 1:27b35752c5d0 73 httppost += "\nContent-Type: application/json";
Trumple 1:27b35752c5d0 74 httppost += "\nContent-Length: " + contentLengthStr;
Trumple 2:1cbb20dd1733 75 httppost += "\nAuthorization: Key 1";
Trumple 1:27b35752c5d0 76 httppost += "\n\n" + jsonPayload;
Trumple 1:27b35752c5d0 77
Trumple 1:27b35752c5d0 78 //to get a writable char* (I.E. not const char* returned by string.c_str), put it into a vector
Trumple 1:27b35752c5d0 79 vector<char> writable(httppost.begin(), httppost.end());
Trumple 1:27b35752c5d0 80 writable.push_back('\0');
Trumple 1:27b35752c5d0 81
Trumple 1:27b35752c5d0 82 sock.send_all(&writable[0], writable.size()-1);
Trumple 1:27b35752c5d0 83
Trumple 1:27b35752c5d0 84 string message = this->receiveFromSock(sock, replyTimeout);
Trumple 1:27b35752c5d0 85
Trumple 1:27b35752c5d0 86 sock.close();
Trumple 1:27b35752c5d0 87
Trumple 1:27b35752c5d0 88 return this->parse(message);
Trumple 1:27b35752c5d0 89 }
Trumple 1:27b35752c5d0 90
Trumple 1:27b35752c5d0 91 string http::receiveFromSock(TCPSocketConnection sock, int replyTimeout)
Trumple 1:27b35752c5d0 92 {
Trumple 1:27b35752c5d0 93 char buffer[1024];
Trumple 1:27b35752c5d0 94 int receiveByteCount;
Trumple 1:27b35752c5d0 95 string message;
Trumple 1:27b35752c5d0 96
Trumple 12:daddfc44a0f5 97 bool headersSet = false;
Trumple 12:daddfc44a0f5 98 int contentLength = -1;
Trumple 12:daddfc44a0f5 99 string responseBody;
Trumple 12:daddfc44a0f5 100
Trumple 12:daddfc44a0f5 101 string contentLengthNeedle = "Content-Length: ";
Trumple 12:daddfc44a0f5 102
Trumple 1:27b35752c5d0 103 while (true)
Trumple 1:27b35752c5d0 104 {
Trumple 1:27b35752c5d0 105 receiveByteCount = sock.receive(buffer, sizeof(buffer)-1);//spare a byte for null termination byte
Trumple 12:daddfc44a0f5 106
Trumple 12:daddfc44a0f5 107 //if the connection is closed by the remote client
Trumple 1:27b35752c5d0 108 if (receiveByteCount <= 0)
Trumple 1:27b35752c5d0 109 break;
Trumple 12:daddfc44a0f5 110
Trumple 1:27b35752c5d0 111 buffer[receiveByteCount] = '\0';
Trumple 1:27b35752c5d0 112 message += buffer;
Trumple 12:daddfc44a0f5 113
Trumple 12:daddfc44a0f5 114 //if the response header has been received and includes the required headers
Trumple 12:daddfc44a0f5 115 if (!headersSet && message.find("\r\n\r\n") != string::npos && message.find(contentLengthNeedle) != string::npos)
Trumple 12:daddfc44a0f5 116 {
Trumple 12:daddfc44a0f5 117 //headers have been fully received, ensure this check is not performed again
Trumple 12:daddfc44a0f5 118 headersSet = true;
Trumple 12:daddfc44a0f5 119 //end point of the "Content-Length: " string, beginning of the integer it specifies
Trumple 12:daddfc44a0f5 120 int cl = message.find(contentLengthNeedle) + contentLengthNeedle.size();
Trumple 12:daddfc44a0f5 121 //extract the content length from the header
Trumple 12:daddfc44a0f5 122 string length = message.substr(cl, message.find_first_of("\r\n", cl) - cl);
Trumple 12:daddfc44a0f5 123 contentLength = atoi(length.c_str());
Trumple 12:daddfc44a0f5 124 }
Trumple 12:daddfc44a0f5 125
Trumple 12:daddfc44a0f5 126 //if the headers have been set, extract the message body
Trumple 12:daddfc44a0f5 127 if (headersSet)
Trumple 12:daddfc44a0f5 128 responseBody = message.substr(message.find("\r\n\r\n"), contentLength);
Trumple 12:daddfc44a0f5 129
Trumple 12:daddfc44a0f5 130 //if the response body is of the expected length, we're done
Trumple 12:daddfc44a0f5 131 if (responseBody.size() >= contentLength)
Trumple 12:daddfc44a0f5 132 break;
Trumple 1:27b35752c5d0 133 }
Trumple 1:27b35752c5d0 134
Trumple 1:27b35752c5d0 135 return message;
Trumple 1:27b35752c5d0 136 }
Trumple 1:27b35752c5d0 137
Trumple 1:27b35752c5d0 138 string http::parse(string httpReply)
Trumple 1:27b35752c5d0 139 {
Trumple 2:1cbb20dd1733 140 int payloadBegin = httpReply.find("\r\n\r\n");
Trumple 2:1cbb20dd1733 141 if (payloadBegin > -1)
Trumple 2:1cbb20dd1733 142 {
Trumple 2:1cbb20dd1733 143 string payload(httpReply.begin() + payloadBegin + 4, httpReply.end());
Trumple 2:1cbb20dd1733 144
Trumple 2:1cbb20dd1733 145 return payload;
Trumple 2:1cbb20dd1733 146 }
Trumple 2:1cbb20dd1733 147 else
Trumple 2:1cbb20dd1733 148 {
Trumple 2:1cbb20dd1733 149 return "";
Trumple 2:1cbb20dd1733 150 }
Trumple 1:27b35752c5d0 151 }