The code from https://github.com/vpcola/Nucleo
HttpClient.cpp@0:5464d5e415e5, 2014-10-08 (annotated)
- Committer:
- sinrab
- Date:
- Wed Oct 08 11:00:24 2014 +0000
- Revision:
- 0:5464d5e415e5
The code from https://github.com/vpcola/Nucleo
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
sinrab | 0:5464d5e415e5 | 1 | #include "HttpClient.h" |
sinrab | 0:5464d5e415e5 | 2 | #include "Utility.h" |
sinrab | 0:5464d5e415e5 | 3 | #include <string> |
sinrab | 0:5464d5e415e5 | 4 | #include <cstring> |
sinrab | 0:5464d5e415e5 | 5 | #include <vector> |
sinrab | 0:5464d5e415e5 | 6 | |
sinrab | 0:5464d5e415e5 | 7 | extern Serial pc; |
sinrab | 0:5464d5e415e5 | 8 | |
sinrab | 0:5464d5e415e5 | 9 | #if 1 |
sinrab | 0:5464d5e415e5 | 10 | //Enable debug |
sinrab | 0:5464d5e415e5 | 11 | #include <cstdio> |
sinrab | 0:5464d5e415e5 | 12 | #define DBG(x, ...) pc.printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__); |
sinrab | 0:5464d5e415e5 | 13 | #define WARN(x, ...) pc.printf("[HTTPClient : WARN]"x"\r\n", ##__VA_ARGS__); |
sinrab | 0:5464d5e415e5 | 14 | #define ERR(x, ...) pc.printf("[HTTPClient : ERR]"x"\r\n", ##__VA_ARGS__); |
sinrab | 0:5464d5e415e5 | 15 | #else |
sinrab | 0:5464d5e415e5 | 16 | //Disable debug |
sinrab | 0:5464d5e415e5 | 17 | #define DBG(x, ...) |
sinrab | 0:5464d5e415e5 | 18 | #define WARN(x, ...) |
sinrab | 0:5464d5e415e5 | 19 | #define ERR(x, ...) |
sinrab | 0:5464d5e415e5 | 20 | #endif |
sinrab | 0:5464d5e415e5 | 21 | |
sinrab | 0:5464d5e415e5 | 22 | |
sinrab | 0:5464d5e415e5 | 23 | |
sinrab | 0:5464d5e415e5 | 24 | |
sinrab | 0:5464d5e415e5 | 25 | HttpClient::HttpClient(const char * hostname) |
sinrab | 0:5464d5e415e5 | 26 | : _hostname(hostname) |
sinrab | 0:5464d5e415e5 | 27 | { |
sinrab | 0:5464d5e415e5 | 28 | } |
sinrab | 0:5464d5e415e5 | 29 | |
sinrab | 0:5464d5e415e5 | 30 | int HttpClient::get(const char * url, char * buffer, size_t buf_len, HeaderInfo & hinfo, int timeout) |
sinrab | 0:5464d5e415e5 | 31 | { |
sinrab | 0:5464d5e415e5 | 32 | char scheme[8]; |
sinrab | 0:5464d5e415e5 | 33 | uint16_t port; |
sinrab | 0:5464d5e415e5 | 34 | char host[32]; |
sinrab | 0:5464d5e415e5 | 35 | char path[64]; |
sinrab | 0:5464d5e415e5 | 36 | |
sinrab | 0:5464d5e415e5 | 37 | _timeout = timeout; |
sinrab | 0:5464d5e415e5 | 38 | |
sinrab | 0:5464d5e415e5 | 39 | if(parse_url(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path))) |
sinrab | 0:5464d5e415e5 | 40 | { |
sinrab | 0:5464d5e415e5 | 41 | ERR("Error parsing URL"); |
sinrab | 0:5464d5e415e5 | 42 | return -1; |
sinrab | 0:5464d5e415e5 | 43 | } |
sinrab | 0:5464d5e415e5 | 44 | |
sinrab | 0:5464d5e415e5 | 45 | if(port == 0) //TODO do handle HTTPS->443 |
sinrab | 0:5464d5e415e5 | 46 | { |
sinrab | 0:5464d5e415e5 | 47 | port = 80; |
sinrab | 0:5464d5e415e5 | 48 | } |
sinrab | 0:5464d5e415e5 | 49 | |
sinrab | 0:5464d5e415e5 | 50 | DBG("Scheme: %s", scheme); |
sinrab | 0:5464d5e415e5 | 51 | DBG("Host: %s", host); |
sinrab | 0:5464d5e415e5 | 52 | DBG("Port: %d", port); |
sinrab | 0:5464d5e415e5 | 53 | DBG("Path: %s", path); |
sinrab | 0:5464d5e415e5 | 54 | |
sinrab | 0:5464d5e415e5 | 55 | // Connect to server |
sinrab | 0:5464d5e415e5 | 56 | int ret = m_sock.connect(host, port); |
sinrab | 0:5464d5e415e5 | 57 | if (ret < 0) |
sinrab | 0:5464d5e415e5 | 58 | { |
sinrab | 0:5464d5e415e5 | 59 | m_sock.close(); |
sinrab | 0:5464d5e415e5 | 60 | ERR("Could not connect"); |
sinrab | 0:5464d5e415e5 | 61 | return -1; |
sinrab | 0:5464d5e415e5 | 62 | } |
sinrab | 0:5464d5e415e5 | 63 | |
sinrab | 0:5464d5e415e5 | 64 | //Send request |
sinrab | 0:5464d5e415e5 | 65 | std::string req_header = build_http_headers("GET", (const char *) path); |
sinrab | 0:5464d5e415e5 | 66 | ret = send((char *) req_header.c_str(), req_header.size()); |
sinrab | 0:5464d5e415e5 | 67 | if(ret) |
sinrab | 0:5464d5e415e5 | 68 | { |
sinrab | 0:5464d5e415e5 | 69 | m_sock.close(); |
sinrab | 0:5464d5e415e5 | 70 | ERR("Could not write request\r\n"); |
sinrab | 0:5464d5e415e5 | 71 | return -1; |
sinrab | 0:5464d5e415e5 | 72 | } |
sinrab | 0:5464d5e415e5 | 73 | // Process the response |
sinrab | 0:5464d5e415e5 | 74 | // First get the header |
sinrab | 0:5464d5e415e5 | 75 | DBG("Reading HTTP header ...\r\n"); |
sinrab | 0:5464d5e415e5 | 76 | char header_buf[512]; |
sinrab | 0:5464d5e415e5 | 77 | int header_line = 0, numread = 0; |
sinrab | 0:5464d5e415e5 | 78 | |
sinrab | 0:5464d5e415e5 | 79 | do { |
sinrab | 0:5464d5e415e5 | 80 | memset(header_buf, 0, sizeof(header_buf)); |
sinrab | 0:5464d5e415e5 | 81 | numread = recv_until(header_buf, sizeof(header_buf), '\n'); |
sinrab | 0:5464d5e415e5 | 82 | // remove trailing \r\n |
sinrab | 0:5464d5e415e5 | 83 | std::string line(header_buf, numread); |
sinrab | 0:5464d5e415e5 | 84 | line = trim(line, " \t\r\n"); |
sinrab | 0:5464d5e415e5 | 85 | |
sinrab | 0:5464d5e415e5 | 86 | DBG("Header line [%s]\r\n", line.c_str()); |
sinrab | 0:5464d5e415e5 | 87 | parse_headers(line, hinfo, header_line); |
sinrab | 0:5464d5e415e5 | 88 | header_line++; |
sinrab | 0:5464d5e415e5 | 89 | }while(numread > 2); // empty line for \r\n |
sinrab | 0:5464d5e415e5 | 90 | |
sinrab | 0:5464d5e415e5 | 91 | // Show the header information |
sinrab | 0:5464d5e415e5 | 92 | DBG("Http response: %d\r\n", hinfo.http_response); |
sinrab | 0:5464d5e415e5 | 93 | DBG("Http response text: %s\r\n", hinfo.http_response_text.c_str()); |
sinrab | 0:5464d5e415e5 | 94 | for(std::map<std::string, std::string>::iterator it = hinfo.http_info.begin(); |
sinrab | 0:5464d5e415e5 | 95 | it != hinfo.http_info.end(); |
sinrab | 0:5464d5e415e5 | 96 | it++) |
sinrab | 0:5464d5e415e5 | 97 | { |
sinrab | 0:5464d5e415e5 | 98 | DBG("Key [%s] : Value [%s]\r\n", it->first.c_str(), it->second.c_str()); |
sinrab | 0:5464d5e415e5 | 99 | } |
sinrab | 0:5464d5e415e5 | 100 | |
sinrab | 0:5464d5e415e5 | 101 | // Read the rest of the data based on content type |
sinrab | 0:5464d5e415e5 | 102 | return read_data(hinfo, buffer, buf_len); |
sinrab | 0:5464d5e415e5 | 103 | |
sinrab | 0:5464d5e415e5 | 104 | } |
sinrab | 0:5464d5e415e5 | 105 | |
sinrab | 0:5464d5e415e5 | 106 | int HttpClient::read_data(HeaderInfo & hinfo, char * buffer, size_t buf_len) |
sinrab | 0:5464d5e415e5 | 107 | { |
sinrab | 0:5464d5e415e5 | 108 | int chunk_size = 0; |
sinrab | 0:5464d5e415e5 | 109 | char tmp_buf[10]; // just for reading the \r\n values |
sinrab | 0:5464d5e415e5 | 110 | char * buf_ptr = buffer; |
sinrab | 0:5464d5e415e5 | 111 | int numread = 0; |
sinrab | 0:5464d5e415e5 | 112 | |
sinrab | 0:5464d5e415e5 | 113 | m_sock.set_blocking(false, _timeout); |
sinrab | 0:5464d5e415e5 | 114 | if (hinfo.http_info["Transfer-Encoding"] == "chunked") |
sinrab | 0:5464d5e415e5 | 115 | { |
sinrab | 0:5464d5e415e5 | 116 | do { |
sinrab | 0:5464d5e415e5 | 117 | // read the chunk size |
sinrab | 0:5464d5e415e5 | 118 | DBG("Reading chunk size ...\r\n"); |
sinrab | 0:5464d5e415e5 | 119 | if ( m_sock.receive_until(tmp_buf, 10, '\n') > 0) |
sinrab | 0:5464d5e415e5 | 120 | { |
sinrab | 0:5464d5e415e5 | 121 | chunk_size = strtoul(tmp_buf, NULL, 16); |
sinrab | 0:5464d5e415e5 | 122 | DBG("Chunk size: %d\r\n", chunk_size); |
sinrab | 0:5464d5e415e5 | 123 | }else |
sinrab | 0:5464d5e415e5 | 124 | break; |
sinrab | 0:5464d5e415e5 | 125 | |
sinrab | 0:5464d5e415e5 | 126 | if (chunk_size > 0) |
sinrab | 0:5464d5e415e5 | 127 | { |
sinrab | 0:5464d5e415e5 | 128 | // read one char at a time untill chunk size |
sinrab | 0:5464d5e415e5 | 129 | int cur_read2 = 0; |
sinrab | 0:5464d5e415e5 | 130 | do { |
sinrab | 0:5464d5e415e5 | 131 | if (m_sock.receive(buf_ptr,1) < 0) |
sinrab | 0:5464d5e415e5 | 132 | { |
sinrab | 0:5464d5e415e5 | 133 | DBG("Error reading chunks with total read [%d]...\r\n", numread); |
sinrab | 0:5464d5e415e5 | 134 | return -1; |
sinrab | 0:5464d5e415e5 | 135 | } |
sinrab | 0:5464d5e415e5 | 136 | cur_read2 ++; |
sinrab | 0:5464d5e415e5 | 137 | buf_ptr ++; |
sinrab | 0:5464d5e415e5 | 138 | }while(cur_read2 < chunk_size); |
sinrab | 0:5464d5e415e5 | 139 | DBG("Read %d chunk\r\n", cur_read2); |
sinrab | 0:5464d5e415e5 | 140 | } |
sinrab | 0:5464d5e415e5 | 141 | |
sinrab | 0:5464d5e415e5 | 142 | numread += chunk_size; |
sinrab | 0:5464d5e415e5 | 143 | DBG("Consuming new lines ...\r\n"); |
sinrab | 0:5464d5e415e5 | 144 | // Consume the next new line |
sinrab | 0:5464d5e415e5 | 145 | m_sock.receive_until(tmp_buf, 10, '\n'); |
sinrab | 0:5464d5e415e5 | 146 | |
sinrab | 0:5464d5e415e5 | 147 | }while((chunk_size > 0) && ((buf_ptr - buffer) < buf_len)); |
sinrab | 0:5464d5e415e5 | 148 | |
sinrab | 0:5464d5e415e5 | 149 | }else |
sinrab | 0:5464d5e415e5 | 150 | { |
sinrab | 0:5464d5e415e5 | 151 | DBG("Reading complete data in one go ...\r\n"); |
sinrab | 0:5464d5e415e5 | 152 | numread = m_sock.receive_all(buffer, buf_len); |
sinrab | 0:5464d5e415e5 | 153 | } |
sinrab | 0:5464d5e415e5 | 154 | |
sinrab | 0:5464d5e415e5 | 155 | DBG("Read %d bytes", numread); |
sinrab | 0:5464d5e415e5 | 156 | |
sinrab | 0:5464d5e415e5 | 157 | // Finally close the socket |
sinrab | 0:5464d5e415e5 | 158 | m_sock.close(); |
sinrab | 0:5464d5e415e5 | 159 | |
sinrab | 0:5464d5e415e5 | 160 | return numread; |
sinrab | 0:5464d5e415e5 | 161 | } |
sinrab | 0:5464d5e415e5 | 162 | |
sinrab | 0:5464d5e415e5 | 163 | int HttpClient::parse_headers(std::string header_line, HeaderInfo & hinfo, int lineno) |
sinrab | 0:5464d5e415e5 | 164 | { |
sinrab | 0:5464d5e415e5 | 165 | std::vector<std::string> tokens; |
sinrab | 0:5464d5e415e5 | 166 | // remove the trailing \n |
sinrab | 0:5464d5e415e5 | 167 | |
sinrab | 0:5464d5e415e5 | 168 | if (lineno == 0) |
sinrab | 0:5464d5e415e5 | 169 | { |
sinrab | 0:5464d5e415e5 | 170 | // Tokenize the first line using spaces |
sinrab | 0:5464d5e415e5 | 171 | split(tokens, header_line, " "); |
sinrab | 0:5464d5e415e5 | 172 | if (tokens.size() == 3) |
sinrab | 0:5464d5e415e5 | 173 | { |
sinrab | 0:5464d5e415e5 | 174 | //for(int i=0; i < tokens.size() ; i++) |
sinrab | 0:5464d5e415e5 | 175 | // pc.printf("Token[%d] = [%s]\r\n", i, tokens[i].c_str()); |
sinrab | 0:5464d5e415e5 | 176 | |
sinrab | 0:5464d5e415e5 | 177 | // The second part is the http response |
sinrab | 0:5464d5e415e5 | 178 | hinfo.http_response = atol(tokens[1].c_str()); |
sinrab | 0:5464d5e415e5 | 179 | DBG("HTTP response [%d]\r\n", hinfo.http_response); |
sinrab | 0:5464d5e415e5 | 180 | hinfo.http_response_text = trim(tokens[2]); |
sinrab | 0:5464d5e415e5 | 181 | DBG("HTTP text [%s]\r\n", hinfo.http_response_text.c_str()); |
sinrab | 0:5464d5e415e5 | 182 | } |
sinrab | 0:5464d5e415e5 | 183 | }else |
sinrab | 0:5464d5e415e5 | 184 | { |
sinrab | 0:5464d5e415e5 | 185 | |
sinrab | 0:5464d5e415e5 | 186 | // Scan for key value pairs |
sinrab | 0:5464d5e415e5 | 187 | split(tokens, header_line, ":"); |
sinrab | 0:5464d5e415e5 | 188 | if (tokens.size() == 2) |
sinrab | 0:5464d5e415e5 | 189 | { |
sinrab | 0:5464d5e415e5 | 190 | //for(int i=0; i < tokens.size() ; i++) |
sinrab | 0:5464d5e415e5 | 191 | // pc.printf("Token[%d] = [%s]\r\n", i, tokens[i].c_str()); |
sinrab | 0:5464d5e415e5 | 192 | |
sinrab | 0:5464d5e415e5 | 193 | std::string key = trim(tokens[0]); |
sinrab | 0:5464d5e415e5 | 194 | std::string value = trim(tokens[1]); |
sinrab | 0:5464d5e415e5 | 195 | |
sinrab | 0:5464d5e415e5 | 196 | hinfo.http_info[key] = value; |
sinrab | 0:5464d5e415e5 | 197 | } |
sinrab | 0:5464d5e415e5 | 198 | } |
sinrab | 0:5464d5e415e5 | 199 | |
sinrab | 0:5464d5e415e5 | 200 | return 0; |
sinrab | 0:5464d5e415e5 | 201 | } |
sinrab | 0:5464d5e415e5 | 202 | |
sinrab | 0:5464d5e415e5 | 203 | std::string HttpClient::build_http_headers(std::string type, std::string path) |
sinrab | 0:5464d5e415e5 | 204 | { |
sinrab | 0:5464d5e415e5 | 205 | std::string request_hdr = type + " " + path + " " + "HTTP/1.1" + "\r\n"; |
sinrab | 0:5464d5e415e5 | 206 | request_hdr += "Host:" + _hostname + "\r\n"; |
sinrab | 0:5464d5e415e5 | 207 | request_hdr += "\r\n"; // empty line terminates the header |
sinrab | 0:5464d5e415e5 | 208 | |
sinrab | 0:5464d5e415e5 | 209 | return request_hdr; |
sinrab | 0:5464d5e415e5 | 210 | |
sinrab | 0:5464d5e415e5 | 211 | } |
sinrab | 0:5464d5e415e5 | 212 | |
sinrab | 0:5464d5e415e5 | 213 | int HttpClient::parse_url(const char* url, char* scheme, |
sinrab | 0:5464d5e415e5 | 214 | size_t scheme_len, |
sinrab | 0:5464d5e415e5 | 215 | char* host, |
sinrab | 0:5464d5e415e5 | 216 | size_t host_len, |
sinrab | 0:5464d5e415e5 | 217 | uint16_t* port, |
sinrab | 0:5464d5e415e5 | 218 | char* path, |
sinrab | 0:5464d5e415e5 | 219 | size_t path_len) //Parse URL |
sinrab | 0:5464d5e415e5 | 220 | { |
sinrab | 0:5464d5e415e5 | 221 | char* schemePtr = (char*) url; |
sinrab | 0:5464d5e415e5 | 222 | char* hostPtr = (char*) strstr(url, "://"); |
sinrab | 0:5464d5e415e5 | 223 | if(hostPtr == NULL) |
sinrab | 0:5464d5e415e5 | 224 | { |
sinrab | 0:5464d5e415e5 | 225 | ERR("Invalid URL [%s]\r\n", url); |
sinrab | 0:5464d5e415e5 | 226 | return -1; //URL is invalid |
sinrab | 0:5464d5e415e5 | 227 | } |
sinrab | 0:5464d5e415e5 | 228 | |
sinrab | 0:5464d5e415e5 | 229 | if( scheme_len < hostPtr - schemePtr + 1 ) //including NULL-terminating char |
sinrab | 0:5464d5e415e5 | 230 | { |
sinrab | 0:5464d5e415e5 | 231 | ERR("Scheme str is too small (%d >= %d)\r\n", scheme_len, hostPtr - schemePtr + 1); |
sinrab | 0:5464d5e415e5 | 232 | return -1; |
sinrab | 0:5464d5e415e5 | 233 | } |
sinrab | 0:5464d5e415e5 | 234 | memcpy(scheme, schemePtr, hostPtr - schemePtr); |
sinrab | 0:5464d5e415e5 | 235 | scheme[hostPtr - schemePtr] = '\0'; |
sinrab | 0:5464d5e415e5 | 236 | |
sinrab | 0:5464d5e415e5 | 237 | hostPtr+=3; |
sinrab | 0:5464d5e415e5 | 238 | |
sinrab | 0:5464d5e415e5 | 239 | size_t hostLen = 0; |
sinrab | 0:5464d5e415e5 | 240 | |
sinrab | 0:5464d5e415e5 | 241 | char* portPtr = strchr(hostPtr, ':'); |
sinrab | 0:5464d5e415e5 | 242 | if( portPtr != NULL ) |
sinrab | 0:5464d5e415e5 | 243 | { |
sinrab | 0:5464d5e415e5 | 244 | hostLen = portPtr - hostPtr; |
sinrab | 0:5464d5e415e5 | 245 | portPtr++; |
sinrab | 0:5464d5e415e5 | 246 | if( sscanf(portPtr, "%hu", port) != 1) |
sinrab | 0:5464d5e415e5 | 247 | { |
sinrab | 0:5464d5e415e5 | 248 | ERR("Could not find port\r\n"); |
sinrab | 0:5464d5e415e5 | 249 | return -1; |
sinrab | 0:5464d5e415e5 | 250 | } |
sinrab | 0:5464d5e415e5 | 251 | } |
sinrab | 0:5464d5e415e5 | 252 | else |
sinrab | 0:5464d5e415e5 | 253 | { |
sinrab | 0:5464d5e415e5 | 254 | *port=0; |
sinrab | 0:5464d5e415e5 | 255 | } |
sinrab | 0:5464d5e415e5 | 256 | char* pathPtr = strchr(hostPtr, '/'); |
sinrab | 0:5464d5e415e5 | 257 | if( hostLen == 0 ) |
sinrab | 0:5464d5e415e5 | 258 | { |
sinrab | 0:5464d5e415e5 | 259 | hostLen = pathPtr - hostPtr; |
sinrab | 0:5464d5e415e5 | 260 | } |
sinrab | 0:5464d5e415e5 | 261 | |
sinrab | 0:5464d5e415e5 | 262 | if( host_len < hostLen + 1 ) //including NULL-terminating char |
sinrab | 0:5464d5e415e5 | 263 | { |
sinrab | 0:5464d5e415e5 | 264 | ERR("Host str is too small (%d >= %d)\r\n", host_len, hostLen + 1); |
sinrab | 0:5464d5e415e5 | 265 | return -1; |
sinrab | 0:5464d5e415e5 | 266 | } |
sinrab | 0:5464d5e415e5 | 267 | memcpy(host, hostPtr, hostLen); |
sinrab | 0:5464d5e415e5 | 268 | host[hostLen] = '\0'; |
sinrab | 0:5464d5e415e5 | 269 | |
sinrab | 0:5464d5e415e5 | 270 | size_t pathLen; |
sinrab | 0:5464d5e415e5 | 271 | char* fragmentPtr = strchr(hostPtr, '#'); |
sinrab | 0:5464d5e415e5 | 272 | if(fragmentPtr != NULL) |
sinrab | 0:5464d5e415e5 | 273 | { |
sinrab | 0:5464d5e415e5 | 274 | pathLen = fragmentPtr - pathPtr; |
sinrab | 0:5464d5e415e5 | 275 | } |
sinrab | 0:5464d5e415e5 | 276 | else |
sinrab | 0:5464d5e415e5 | 277 | { |
sinrab | 0:5464d5e415e5 | 278 | pathLen = strlen(pathPtr); |
sinrab | 0:5464d5e415e5 | 279 | } |
sinrab | 0:5464d5e415e5 | 280 | |
sinrab | 0:5464d5e415e5 | 281 | if( path_len < pathLen + 1 ) //including NULL-terminating char |
sinrab | 0:5464d5e415e5 | 282 | { |
sinrab | 0:5464d5e415e5 | 283 | ERR("Path str is too small (%d >= %d)\r\n", path_len, pathLen + 1); |
sinrab | 0:5464d5e415e5 | 284 | return -1; |
sinrab | 0:5464d5e415e5 | 285 | } |
sinrab | 0:5464d5e415e5 | 286 | memcpy(path, pathPtr, pathLen); |
sinrab | 0:5464d5e415e5 | 287 | path[pathLen] = '\0'; |
sinrab | 0:5464d5e415e5 | 288 | |
sinrab | 0:5464d5e415e5 | 289 | return 0; |
sinrab | 0:5464d5e415e5 | 290 | } |
sinrab | 0:5464d5e415e5 | 291 | |
sinrab | 0:5464d5e415e5 | 292 | int HttpClient::recv_until(char * buf, size_t len, char term) |
sinrab | 0:5464d5e415e5 | 293 | { |
sinrab | 0:5464d5e415e5 | 294 | int numread = 0; |
sinrab | 0:5464d5e415e5 | 295 | if(!m_sock.is_connected()) |
sinrab | 0:5464d5e415e5 | 296 | { |
sinrab | 0:5464d5e415e5 | 297 | ERR("Connection was closed by server\r\n"); |
sinrab | 0:5464d5e415e5 | 298 | return -1; //Connection was closed by server |
sinrab | 0:5464d5e415e5 | 299 | } |
sinrab | 0:5464d5e415e5 | 300 | |
sinrab | 0:5464d5e415e5 | 301 | m_sock.set_blocking(false, _timeout); |
sinrab | 0:5464d5e415e5 | 302 | int ret = m_sock.receive_until(buf, len, term); |
sinrab | 0:5464d5e415e5 | 303 | if(ret > 0) |
sinrab | 0:5464d5e415e5 | 304 | { |
sinrab | 0:5464d5e415e5 | 305 | numread += ret; |
sinrab | 0:5464d5e415e5 | 306 | } |
sinrab | 0:5464d5e415e5 | 307 | else if( ret == 0 ) |
sinrab | 0:5464d5e415e5 | 308 | { |
sinrab | 0:5464d5e415e5 | 309 | ERR("Connection was closed by server\r\n"); |
sinrab | 0:5464d5e415e5 | 310 | return -1; //Connection was closed by server |
sinrab | 0:5464d5e415e5 | 311 | } |
sinrab | 0:5464d5e415e5 | 312 | else |
sinrab | 0:5464d5e415e5 | 313 | { |
sinrab | 0:5464d5e415e5 | 314 | ERR("Connection error (recv returned %d)\r\n", ret); |
sinrab | 0:5464d5e415e5 | 315 | return -1; |
sinrab | 0:5464d5e415e5 | 316 | } |
sinrab | 0:5464d5e415e5 | 317 | |
sinrab | 0:5464d5e415e5 | 318 | DBG("Received %d bytes", numread); |
sinrab | 0:5464d5e415e5 | 319 | return numread; |
sinrab | 0:5464d5e415e5 | 320 | } |
sinrab | 0:5464d5e415e5 | 321 | |
sinrab | 0:5464d5e415e5 | 322 | int HttpClient::send(char* buf, size_t len) //0 on success, err code on failure |
sinrab | 0:5464d5e415e5 | 323 | { |
sinrab | 0:5464d5e415e5 | 324 | if(len == 0) |
sinrab | 0:5464d5e415e5 | 325 | { |
sinrab | 0:5464d5e415e5 | 326 | len = strlen(buf); |
sinrab | 0:5464d5e415e5 | 327 | } |
sinrab | 0:5464d5e415e5 | 328 | //pc.printf("Trying to write %d bytes\r\n", len); |
sinrab | 0:5464d5e415e5 | 329 | size_t writtenLen = 0; |
sinrab | 0:5464d5e415e5 | 330 | |
sinrab | 0:5464d5e415e5 | 331 | if(!m_sock.is_connected()) |
sinrab | 0:5464d5e415e5 | 332 | { |
sinrab | 0:5464d5e415e5 | 333 | ERR("Connection was closed by server\r\n"); |
sinrab | 0:5464d5e415e5 | 334 | return -1; //Connection was closed by server |
sinrab | 0:5464d5e415e5 | 335 | } |
sinrab | 0:5464d5e415e5 | 336 | |
sinrab | 0:5464d5e415e5 | 337 | m_sock.set_blocking(false, _timeout); |
sinrab | 0:5464d5e415e5 | 338 | int ret = m_sock.send_all(buf, len); |
sinrab | 0:5464d5e415e5 | 339 | if(ret > 0) |
sinrab | 0:5464d5e415e5 | 340 | { |
sinrab | 0:5464d5e415e5 | 341 | writtenLen += ret; |
sinrab | 0:5464d5e415e5 | 342 | } |
sinrab | 0:5464d5e415e5 | 343 | else if( ret == 0 ) |
sinrab | 0:5464d5e415e5 | 344 | { |
sinrab | 0:5464d5e415e5 | 345 | ERR("Connection was closed by server\r\n"); |
sinrab | 0:5464d5e415e5 | 346 | return -1; //Connection was closed by server |
sinrab | 0:5464d5e415e5 | 347 | } |
sinrab | 0:5464d5e415e5 | 348 | else |
sinrab | 0:5464d5e415e5 | 349 | { |
sinrab | 0:5464d5e415e5 | 350 | ERR("Connection error (send returned %d)\r\n", ret); |
sinrab | 0:5464d5e415e5 | 351 | return -1; |
sinrab | 0:5464d5e415e5 | 352 | } |
sinrab | 0:5464d5e415e5 | 353 | |
sinrab | 0:5464d5e415e5 | 354 | DBG("Written %d bytes\r\n", writtenLen); |
sinrab | 0:5464d5e415e5 | 355 | return 0; |
sinrab | 0:5464d5e415e5 | 356 | } |
sinrab | 0:5464d5e415e5 | 357 |