GDP group 24 node core
Dependencies: EthernetInterface SDFileSystem mbed-rtos mbed snail MbedJSONValue
http.cpp@23:b57a47c7862a, 2015-01-27 (annotated)
- Committer:
- jakehodges
- Date:
- Tue Jan 27 22:20:46 2015 +0000
- Revision:
- 23:b57a47c7862a
- Parent:
- 12:daddfc44a0f5
- Child:
- 27:61e67ab47da5
Update JSON message to server to include int array. Update sensordata message to reflect changes in SNAIL. Fix SD card location string. Fix I2C id conflict.
Who changed what in which revision?
User | Revision | Line number | New 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 | 1:27b35752c5d0 | 20 | string http::get(string address, int port, string url, int replyTimeout) |
Trumple | 1:27b35752c5d0 | 21 | { |
Trumple | 1:27b35752c5d0 | 22 | #ifdef DEBUG |
Trumple | 2:1cbb20dd1733 | 23 | printf("[HTTP] Sending GET request to %s:%i%s\r\n", address.c_str(), port, url.c_str()); |
Trumple | 1:27b35752c5d0 | 24 | #endif |
Trumple | 1:27b35752c5d0 | 25 | |
Trumple | 1:27b35752c5d0 | 26 | TCPSocketConnection sock; |
Trumple | 1:27b35752c5d0 | 27 | sock.connect(address.c_str(), port); |
Trumple | 1:27b35752c5d0 | 28 | |
Trumple | 1:27b35752c5d0 | 29 | #ifdef DEBUG |
Trumple | 1:27b35752c5d0 | 30 | printf("[HTTP] Connected to endpoint...\r\n"); |
Trumple | 1:27b35752c5d0 | 31 | #endif |
Trumple | 1:27b35752c5d0 | 32 | |
Trumple | 1:27b35752c5d0 | 33 | string httpget = "GET " + url + " HTTP/1.1"; |
Trumple | 1:27b35752c5d0 | 34 | httpget += "\nHost: " + address + "\n\n"; |
Trumple | 1:27b35752c5d0 | 35 | |
Trumple | 1:27b35752c5d0 | 36 | //get a writable char* (I.E. not const char* returned by c_str), put it into a vector |
Trumple | 1:27b35752c5d0 | 37 | vector<char> writable(httpget.begin(), httpget.end()); |
Trumple | 1:27b35752c5d0 | 38 | writable.push_back('\0'); |
Trumple | 1:27b35752c5d0 | 39 | |
Trumple | 1:27b35752c5d0 | 40 | sock.send_all(&writable[0], writable.size()-1); |
Trumple | 1:27b35752c5d0 | 41 | |
Trumple | 1:27b35752c5d0 | 42 | string message = this->receiveFromSock(sock, replyTimeout); |
Trumple | 1:27b35752c5d0 | 43 | |
Trumple | 1:27b35752c5d0 | 44 | sock.close(); |
Trumple | 1:27b35752c5d0 | 45 | |
Trumple | 1:27b35752c5d0 | 46 | return this->parse(message); |
Trumple | 1:27b35752c5d0 | 47 | } |
Trumple | 1:27b35752c5d0 | 48 | |
Trumple | 1:27b35752c5d0 | 49 | string http::post(string address, int port, string url, string jsonPayload, int replyTimeout) |
Trumple | 1:27b35752c5d0 | 50 | { |
Trumple | 1:27b35752c5d0 | 51 | #ifdef DEBUG |
Trumple | 2:1cbb20dd1733 | 52 | printf("[HTTP] Sending POST request to %s:%i%s\r\n", address.c_str(), port, url.c_str()); |
Trumple | 1:27b35752c5d0 | 53 | #endif |
Trumple | 1:27b35752c5d0 | 54 | |
Trumple | 1:27b35752c5d0 | 55 | TCPSocketConnection sock; |
Trumple | 1:27b35752c5d0 | 56 | sock.connect(address.c_str(), port); |
Trumple | 1:27b35752c5d0 | 57 | |
Trumple | 1:27b35752c5d0 | 58 | #ifdef DEBUG |
Trumple | 1:27b35752c5d0 | 59 | printf("[HTTP] Connected to endpoint...\r\n"); |
Trumple | 1:27b35752c5d0 | 60 | #endif |
Trumple | 1:27b35752c5d0 | 61 | |
Trumple | 2:1cbb20dd1733 | 62 | char buffer[20]; |
Trumple | 2:1cbb20dd1733 | 63 | sprintf(buffer, "%i", jsonPayload.size()); |
Trumple | 2:1cbb20dd1733 | 64 | string contentLengthStr = string(buffer); |
Trumple | 1:27b35752c5d0 | 65 | |
Trumple | 1:27b35752c5d0 | 66 | string httppost = "POST " + url + " HTTP/1.1"; |
Trumple | 1:27b35752c5d0 | 67 | httppost += "\nHost: " + address; |
Trumple | 1:27b35752c5d0 | 68 | httppost += "\nContent-Type: application/json"; |
Trumple | 1:27b35752c5d0 | 69 | httppost += "\nContent-Length: " + contentLengthStr; |
Trumple | 2:1cbb20dd1733 | 70 | httppost += "\nAuthorization: Key 1"; |
Trumple | 1:27b35752c5d0 | 71 | httppost += "\n\n" + jsonPayload; |
Trumple | 1:27b35752c5d0 | 72 | |
Trumple | 1:27b35752c5d0 | 73 | //to get a writable char* (I.E. not const char* returned by string.c_str), put it into a vector |
Trumple | 1:27b35752c5d0 | 74 | vector<char> writable(httppost.begin(), httppost.end()); |
Trumple | 1:27b35752c5d0 | 75 | writable.push_back('\0'); |
Trumple | 1:27b35752c5d0 | 76 | |
Trumple | 1:27b35752c5d0 | 77 | sock.send_all(&writable[0], writable.size()-1); |
Trumple | 1:27b35752c5d0 | 78 | |
Trumple | 1:27b35752c5d0 | 79 | string message = this->receiveFromSock(sock, replyTimeout); |
Trumple | 1:27b35752c5d0 | 80 | |
Trumple | 1:27b35752c5d0 | 81 | sock.close(); |
Trumple | 1:27b35752c5d0 | 82 | |
Trumple | 1:27b35752c5d0 | 83 | return this->parse(message); |
Trumple | 1:27b35752c5d0 | 84 | } |
Trumple | 1:27b35752c5d0 | 85 | |
Trumple | 1:27b35752c5d0 | 86 | string http::receiveFromSock(TCPSocketConnection sock, int replyTimeout) |
Trumple | 1:27b35752c5d0 | 87 | { |
Trumple | 1:27b35752c5d0 | 88 | char buffer[1024]; |
Trumple | 1:27b35752c5d0 | 89 | int receiveByteCount; |
Trumple | 1:27b35752c5d0 | 90 | string message; |
Trumple | 1:27b35752c5d0 | 91 | |
Trumple | 12:daddfc44a0f5 | 92 | bool headersSet = false; |
Trumple | 12:daddfc44a0f5 | 93 | int contentLength = -1; |
Trumple | 12:daddfc44a0f5 | 94 | string responseBody; |
Trumple | 12:daddfc44a0f5 | 95 | |
Trumple | 12:daddfc44a0f5 | 96 | string contentLengthNeedle = "Content-Length: "; |
Trumple | 12:daddfc44a0f5 | 97 | |
Trumple | 1:27b35752c5d0 | 98 | while (true) |
Trumple | 1:27b35752c5d0 | 99 | { |
Trumple | 1:27b35752c5d0 | 100 | receiveByteCount = sock.receive(buffer, sizeof(buffer)-1);//spare a byte for null termination byte |
Trumple | 12:daddfc44a0f5 | 101 | |
Trumple | 12:daddfc44a0f5 | 102 | //if the connection is closed by the remote client |
Trumple | 1:27b35752c5d0 | 103 | if (receiveByteCount <= 0) |
Trumple | 1:27b35752c5d0 | 104 | break; |
Trumple | 12:daddfc44a0f5 | 105 | |
Trumple | 1:27b35752c5d0 | 106 | buffer[receiveByteCount] = '\0'; |
Trumple | 1:27b35752c5d0 | 107 | message += buffer; |
Trumple | 12:daddfc44a0f5 | 108 | |
Trumple | 12:daddfc44a0f5 | 109 | //if the response header has been received and includes the required headers |
Trumple | 12:daddfc44a0f5 | 110 | if (!headersSet && message.find("\r\n\r\n") != string::npos && message.find(contentLengthNeedle) != string::npos) |
Trumple | 12:daddfc44a0f5 | 111 | { |
Trumple | 12:daddfc44a0f5 | 112 | //headers have been fully received, ensure this check is not performed again |
Trumple | 12:daddfc44a0f5 | 113 | headersSet = true; |
Trumple | 12:daddfc44a0f5 | 114 | //end point of the "Content-Length: " string, beginning of the integer it specifies |
Trumple | 12:daddfc44a0f5 | 115 | int cl = message.find(contentLengthNeedle) + contentLengthNeedle.size(); |
Trumple | 12:daddfc44a0f5 | 116 | //extract the content length from the header |
Trumple | 12:daddfc44a0f5 | 117 | string length = message.substr(cl, message.find_first_of("\r\n", cl) - cl); |
Trumple | 12:daddfc44a0f5 | 118 | contentLength = atoi(length.c_str()); |
Trumple | 12:daddfc44a0f5 | 119 | } |
Trumple | 12:daddfc44a0f5 | 120 | |
Trumple | 12:daddfc44a0f5 | 121 | //if the headers have been set, extract the message body |
Trumple | 12:daddfc44a0f5 | 122 | if (headersSet) |
Trumple | 12:daddfc44a0f5 | 123 | responseBody = message.substr(message.find("\r\n\r\n"), contentLength); |
Trumple | 12:daddfc44a0f5 | 124 | |
Trumple | 12:daddfc44a0f5 | 125 | //if the response body is of the expected length, we're done |
Trumple | 12:daddfc44a0f5 | 126 | if (responseBody.size() >= contentLength) |
Trumple | 12:daddfc44a0f5 | 127 | break; |
Trumple | 1:27b35752c5d0 | 128 | } |
Trumple | 1:27b35752c5d0 | 129 | |
Trumple | 1:27b35752c5d0 | 130 | return message; |
Trumple | 1:27b35752c5d0 | 131 | } |
Trumple | 1:27b35752c5d0 | 132 | |
Trumple | 1:27b35752c5d0 | 133 | string http::parse(string httpReply) |
Trumple | 1:27b35752c5d0 | 134 | { |
Trumple | 2:1cbb20dd1733 | 135 | int payloadBegin = httpReply.find("\r\n\r\n"); |
Trumple | 2:1cbb20dd1733 | 136 | if (payloadBegin > -1) |
Trumple | 2:1cbb20dd1733 | 137 | { |
Trumple | 2:1cbb20dd1733 | 138 | string payload(httpReply.begin() + payloadBegin + 4, httpReply.end()); |
Trumple | 2:1cbb20dd1733 | 139 | |
Trumple | 2:1cbb20dd1733 | 140 | return payload; |
Trumple | 2:1cbb20dd1733 | 141 | } |
Trumple | 2:1cbb20dd1733 | 142 | else |
Trumple | 2:1cbb20dd1733 | 143 | { |
Trumple | 2:1cbb20dd1733 | 144 | return ""; |
Trumple | 2:1cbb20dd1733 | 145 | } |
Trumple | 1:27b35752c5d0 | 146 | } |