It is the new miniTLS program which build the connect with the website httpbin.org

Fork of MiniTLS-HTTPSClient by Donatien Garnier

Committer:
MiniTLS
Date:
Tue Jun 10 14:23:22 2014 +0000
Revision:
0:62a4a8ec4ab5
Child:
1:4309aff9b1db
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MiniTLS 0:62a4a8ec4ab5 1 /* HTTPClient.cpp */
MiniTLS 0:62a4a8ec4ab5 2 /* Copyright (C) 2012 mbed.org, MIT License
MiniTLS 0:62a4a8ec4ab5 3 *
MiniTLS 0:62a4a8ec4ab5 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
MiniTLS 0:62a4a8ec4ab5 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
MiniTLS 0:62a4a8ec4ab5 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
MiniTLS 0:62a4a8ec4ab5 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
MiniTLS 0:62a4a8ec4ab5 8 * furnished to do so, subject to the following conditions:
MiniTLS 0:62a4a8ec4ab5 9 *
MiniTLS 0:62a4a8ec4ab5 10 * The above copyright notice and this permission notice shall be included in all copies or
MiniTLS 0:62a4a8ec4ab5 11 * substantial portions of the Software.
MiniTLS 0:62a4a8ec4ab5 12 *
MiniTLS 0:62a4a8ec4ab5 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
MiniTLS 0:62a4a8ec4ab5 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
MiniTLS 0:62a4a8ec4ab5 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
MiniTLS 0:62a4a8ec4ab5 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
MiniTLS 0:62a4a8ec4ab5 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
MiniTLS 0:62a4a8ec4ab5 18 */
MiniTLS 0:62a4a8ec4ab5 19
MiniTLS 0:62a4a8ec4ab5 20 //Debug is disabled by default
MiniTLS 0:62a4a8ec4ab5 21
MiniTLS 0:62a4a8ec4ab5 22 #define __MODULE__ "HTTPClient"
MiniTLS 0:62a4a8ec4ab5 23 #define __DEBUG__ 4
MiniTLS 0:62a4a8ec4ab5 24
MiniTLS 0:62a4a8ec4ab5 25 #include "core/fwk.h"
MiniTLS 0:62a4a8ec4ab5 26 #include "HTTPClient.h"
MiniTLS 0:62a4a8ec4ab5 27 #include "MiniTLS-GPL/cpp/MiniTLS.h"
MiniTLS 0:62a4a8ec4ab5 28
MiniTLS 0:62a4a8ec4ab5 29 #define HTTP_PORT 80
MiniTLS 0:62a4a8ec4ab5 30 #define HTTPS_PORT 443
MiniTLS 0:62a4a8ec4ab5 31
MiniTLS 0:62a4a8ec4ab5 32 #define OK 0
MiniTLS 0:62a4a8ec4ab5 33 /*
MiniTLS 0:62a4a8ec4ab5 34 #define MIN(x,y) (((x)<(y))?(x):(y))
MiniTLS 0:62a4a8ec4ab5 35 #define MAX(x,y) (((x)>(y))?(x):(y))
MiniTLS 0:62a4a8ec4ab5 36 */
MiniTLS 0:62a4a8ec4ab5 37 #define CHUNK_SIZE 256
MiniTLS 0:62a4a8ec4ab5 38
MiniTLS 0:62a4a8ec4ab5 39 #include <cstring>
MiniTLS 0:62a4a8ec4ab5 40
MiniTLS 0:62a4a8ec4ab5 41 extern MiniTLS miniTLS;
MiniTLS 0:62a4a8ec4ab5 42
MiniTLS 0:62a4a8ec4ab5 43 HTTPClient::HTTPClient() :
MiniTLS 0:62a4a8ec4ab5 44 m_sock(&miniTLS), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
MiniTLS 0:62a4a8ec4ab5 45 {
MiniTLS 0:62a4a8ec4ab5 46
MiniTLS 0:62a4a8ec4ab5 47 }
MiniTLS 0:62a4a8ec4ab5 48
MiniTLS 0:62a4a8ec4ab5 49 HTTPClient::~HTTPClient()
MiniTLS 0:62a4a8ec4ab5 50 {
MiniTLS 0:62a4a8ec4ab5 51
MiniTLS 0:62a4a8ec4ab5 52 }
MiniTLS 0:62a4a8ec4ab5 53
MiniTLS 0:62a4a8ec4ab5 54 #if 0
MiniTLS 0:62a4a8ec4ab5 55 void HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification
MiniTLS 0:62a4a8ec4ab5 56 {
MiniTLS 0:62a4a8ec4ab5 57 m_basicAuthUser = user;
MiniTLS 0:62a4a8ec4ab5 58 m_basicAuthPassword = password;
MiniTLS 0:62a4a8ec4ab5 59 }
MiniTLS 0:62a4a8ec4ab5 60 #endif
MiniTLS 0:62a4a8ec4ab5 61
MiniTLS 0:62a4a8ec4ab5 62 HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
MiniTLS 0:62a4a8ec4ab5 63 {
MiniTLS 0:62a4a8ec4ab5 64 return connect(url, HTTP_GET, NULL, pDataIn, timeout);
MiniTLS 0:62a4a8ec4ab5 65 }
MiniTLS 0:62a4a8ec4ab5 66
MiniTLS 0:62a4a8ec4ab5 67 HTTPResult HTTPClient::get(const char* url, char* result, size_t maxResultLen, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
MiniTLS 0:62a4a8ec4ab5 68 {
MiniTLS 0:62a4a8ec4ab5 69 HTTPText str(result, maxResultLen);
MiniTLS 0:62a4a8ec4ab5 70 return get(url, &str, timeout);
MiniTLS 0:62a4a8ec4ab5 71 }
MiniTLS 0:62a4a8ec4ab5 72
MiniTLS 0:62a4a8ec4ab5 73 HTTPResult HTTPClient::post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
MiniTLS 0:62a4a8ec4ab5 74 {
MiniTLS 0:62a4a8ec4ab5 75 return connect(url, HTTP_POST, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
MiniTLS 0:62a4a8ec4ab5 76 }
MiniTLS 0:62a4a8ec4ab5 77
MiniTLS 0:62a4a8ec4ab5 78 HTTPResult HTTPClient::put(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
MiniTLS 0:62a4a8ec4ab5 79 {
MiniTLS 0:62a4a8ec4ab5 80 return connect(url, HTTP_PUT, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
MiniTLS 0:62a4a8ec4ab5 81 }
MiniTLS 0:62a4a8ec4ab5 82
MiniTLS 0:62a4a8ec4ab5 83 HTTPResult HTTPClient::del(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
MiniTLS 0:62a4a8ec4ab5 84 {
MiniTLS 0:62a4a8ec4ab5 85 return connect(url, HTTP_DELETE, NULL, pDataIn, timeout);
MiniTLS 0:62a4a8ec4ab5 86 }
MiniTLS 0:62a4a8ec4ab5 87
MiniTLS 0:62a4a8ec4ab5 88
MiniTLS 0:62a4a8ec4ab5 89 int HTTPClient::getHTTPResponseCode()
MiniTLS 0:62a4a8ec4ab5 90 {
MiniTLS 0:62a4a8ec4ab5 91 return m_httpResponseCode;
MiniTLS 0:62a4a8ec4ab5 92 }
MiniTLS 0:62a4a8ec4ab5 93
MiniTLS 0:62a4a8ec4ab5 94 #define CHECK_CONN_ERR(ret) \
MiniTLS 0:62a4a8ec4ab5 95 do{ \
MiniTLS 0:62a4a8ec4ab5 96 if(ret) { \
MiniTLS 0:62a4a8ec4ab5 97 m_sock.close(); \
MiniTLS 0:62a4a8ec4ab5 98 ERR("Connection error (%d)", ret); \
MiniTLS 0:62a4a8ec4ab5 99 return HTTP_CONN; \
MiniTLS 0:62a4a8ec4ab5 100 } \
MiniTLS 0:62a4a8ec4ab5 101 } while(0)
MiniTLS 0:62a4a8ec4ab5 102
MiniTLS 0:62a4a8ec4ab5 103 #define PRTCL_ERR() \
MiniTLS 0:62a4a8ec4ab5 104 do{ \
MiniTLS 0:62a4a8ec4ab5 105 m_sock.close(); \
MiniTLS 0:62a4a8ec4ab5 106 ERR("Protocol error"); \
MiniTLS 0:62a4a8ec4ab5 107 return HTTP_PRTCL; \
MiniTLS 0:62a4a8ec4ab5 108 } while(0)
MiniTLS 0:62a4a8ec4ab5 109
MiniTLS 0:62a4a8ec4ab5 110 HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request
MiniTLS 0:62a4a8ec4ab5 111 {
MiniTLS 0:62a4a8ec4ab5 112 m_httpResponseCode = 0; //Invalidate code
MiniTLS 0:62a4a8ec4ab5 113 m_timeout = timeout;
MiniTLS 0:62a4a8ec4ab5 114
MiniTLS 0:62a4a8ec4ab5 115 pDataIn->writeReset();
MiniTLS 0:62a4a8ec4ab5 116 if( pDataOut )
MiniTLS 0:62a4a8ec4ab5 117 {
MiniTLS 0:62a4a8ec4ab5 118 pDataOut->readReset();
MiniTLS 0:62a4a8ec4ab5 119 }
MiniTLS 0:62a4a8ec4ab5 120
MiniTLS 0:62a4a8ec4ab5 121 char scheme[8];
MiniTLS 0:62a4a8ec4ab5 122 uint16_t port;
MiniTLS 0:62a4a8ec4ab5 123 char host[32];
MiniTLS 0:62a4a8ec4ab5 124 char path[64];
MiniTLS 0:62a4a8ec4ab5 125 //First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?)
MiniTLS 0:62a4a8ec4ab5 126 HTTPResult res = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
MiniTLS 0:62a4a8ec4ab5 127 if(res != HTTP_OK)
MiniTLS 0:62a4a8ec4ab5 128 {
MiniTLS 0:62a4a8ec4ab5 129 ERR("parseURL returned %d", res);
MiniTLS 0:62a4a8ec4ab5 130 return res;
MiniTLS 0:62a4a8ec4ab5 131 }
MiniTLS 0:62a4a8ec4ab5 132
MiniTLS 0:62a4a8ec4ab5 133 if(port == 0)
MiniTLS 0:62a4a8ec4ab5 134 {
MiniTLS 0:62a4a8ec4ab5 135 if(!strcmp(scheme, "http"))
MiniTLS 0:62a4a8ec4ab5 136 {
MiniTLS 0:62a4a8ec4ab5 137 port = 80;
MiniTLS 0:62a4a8ec4ab5 138 }
MiniTLS 0:62a4a8ec4ab5 139 else if(!strcmp(scheme, "https"))
MiniTLS 0:62a4a8ec4ab5 140 {
MiniTLS 0:62a4a8ec4ab5 141 port = 443;
MiniTLS 0:62a4a8ec4ab5 142 }
MiniTLS 0:62a4a8ec4ab5 143 else
MiniTLS 0:62a4a8ec4ab5 144 {
MiniTLS 0:62a4a8ec4ab5 145 ERR("Unknown port for scheme");
MiniTLS 0:62a4a8ec4ab5 146 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 147 }
MiniTLS 0:62a4a8ec4ab5 148 }
MiniTLS 0:62a4a8ec4ab5 149
MiniTLS 0:62a4a8ec4ab5 150 DBG("Scheme: %s", scheme);
MiniTLS 0:62a4a8ec4ab5 151 DBG("Host: %s", host);
MiniTLS 0:62a4a8ec4ab5 152 DBG("Port: %d", port);
MiniTLS 0:62a4a8ec4ab5 153 DBG("Path: %s", path);
MiniTLS 0:62a4a8ec4ab5 154
MiniTLS 0:62a4a8ec4ab5 155 //Init socket
MiniTLS 0:62a4a8ec4ab5 156 int ret = m_sock.init();
MiniTLS 0:62a4a8ec4ab5 157 if (ret)
MiniTLS 0:62a4a8ec4ab5 158 {
MiniTLS 0:62a4a8ec4ab5 159 ERR("Could not connect");
MiniTLS 0:62a4a8ec4ab5 160 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 161 }
MiniTLS 0:62a4a8ec4ab5 162
MiniTLS 0:62a4a8ec4ab5 163 //Connect
MiniTLS 0:62a4a8ec4ab5 164 DBG("Connecting socket to server");
MiniTLS 0:62a4a8ec4ab5 165 ret = m_sock.connect(host, port, timeout);
MiniTLS 0:62a4a8ec4ab5 166 if (ret)
MiniTLS 0:62a4a8ec4ab5 167 {
MiniTLS 0:62a4a8ec4ab5 168 m_sock.close();
MiniTLS 0:62a4a8ec4ab5 169 ERR("Could not connect");
MiniTLS 0:62a4a8ec4ab5 170 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 171 }
MiniTLS 0:62a4a8ec4ab5 172
MiniTLS 0:62a4a8ec4ab5 173 //Send request
MiniTLS 0:62a4a8ec4ab5 174 DBG("Sending request");
MiniTLS 0:62a4a8ec4ab5 175 char buf[CHUNK_SIZE];
MiniTLS 0:62a4a8ec4ab5 176 const char* meth = (method==HTTP_GET)?"GET":(method==HTTP_POST)?"POST":(method==HTTP_PUT)?"PUT":(method==HTTP_DELETE)?"DELETE":"";
MiniTLS 0:62a4a8ec4ab5 177 snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request
MiniTLS 0:62a4a8ec4ab5 178 ret = send(buf);
MiniTLS 0:62a4a8ec4ab5 179 if(ret)
MiniTLS 0:62a4a8ec4ab5 180 {
MiniTLS 0:62a4a8ec4ab5 181 m_sock.close();
MiniTLS 0:62a4a8ec4ab5 182 ERR("Could not write request");
MiniTLS 0:62a4a8ec4ab5 183 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 184 }
MiniTLS 0:62a4a8ec4ab5 185
MiniTLS 0:62a4a8ec4ab5 186 //Send all headers
MiniTLS 0:62a4a8ec4ab5 187
MiniTLS 0:62a4a8ec4ab5 188 //Send default headers
MiniTLS 0:62a4a8ec4ab5 189 DBG("Sending headers");
MiniTLS 0:62a4a8ec4ab5 190 if( pDataOut != NULL )
MiniTLS 0:62a4a8ec4ab5 191 {
MiniTLS 0:62a4a8ec4ab5 192 if( pDataOut->getIsChunked() )
MiniTLS 0:62a4a8ec4ab5 193 {
MiniTLS 0:62a4a8ec4ab5 194 ret = send("Transfer-Encoding: chunked\r\n");
MiniTLS 0:62a4a8ec4ab5 195 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 196 }
MiniTLS 0:62a4a8ec4ab5 197 else
MiniTLS 0:62a4a8ec4ab5 198 {
MiniTLS 0:62a4a8ec4ab5 199 snprintf(buf, sizeof(buf), "Content-Length: %d\r\n", pDataOut->getDataLen());
MiniTLS 0:62a4a8ec4ab5 200 ret = send(buf);
MiniTLS 0:62a4a8ec4ab5 201 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 202 }
MiniTLS 0:62a4a8ec4ab5 203 char type[48];
MiniTLS 0:62a4a8ec4ab5 204 if( pDataOut->getDataType(type, 48) == HTTP_OK )
MiniTLS 0:62a4a8ec4ab5 205 {
MiniTLS 0:62a4a8ec4ab5 206 snprintf(buf, sizeof(buf), "Content-Type: %s\r\n", type);
MiniTLS 0:62a4a8ec4ab5 207 ret = send(buf);
MiniTLS 0:62a4a8ec4ab5 208 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 209 }
MiniTLS 0:62a4a8ec4ab5 210
MiniTLS 0:62a4a8ec4ab5 211 //Send specific headers
MiniTLS 0:62a4a8ec4ab5 212 while( pDataOut->getHeader(buf, sizeof(buf) - 3) ) //must have space left for CRLF + 0 terminating char
MiniTLS 0:62a4a8ec4ab5 213 {
MiniTLS 0:62a4a8ec4ab5 214 size_t headerlen = strlen(buf);
MiniTLS 0:62a4a8ec4ab5 215 snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n");
MiniTLS 0:62a4a8ec4ab5 216 ret = send(buf);
MiniTLS 0:62a4a8ec4ab5 217 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 218 }
MiniTLS 0:62a4a8ec4ab5 219 }
MiniTLS 0:62a4a8ec4ab5 220
MiniTLS 0:62a4a8ec4ab5 221 //Send specific headers
MiniTLS 0:62a4a8ec4ab5 222 while( pDataIn->getHeader(buf, sizeof(buf) - 3) )
MiniTLS 0:62a4a8ec4ab5 223 {
MiniTLS 0:62a4a8ec4ab5 224 size_t headerlen = strlen(buf);
MiniTLS 0:62a4a8ec4ab5 225 snprintf(buf + headerlen, sizeof(buf) - headerlen, "\r\n");
MiniTLS 0:62a4a8ec4ab5 226 ret = send(buf);
MiniTLS 0:62a4a8ec4ab5 227 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 228 }
MiniTLS 0:62a4a8ec4ab5 229
MiniTLS 0:62a4a8ec4ab5 230 //Close headers
MiniTLS 0:62a4a8ec4ab5 231 DBG("Headers sent");
MiniTLS 0:62a4a8ec4ab5 232 ret = send("\r\n", 0, true); //Flush
MiniTLS 0:62a4a8ec4ab5 233 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 234
MiniTLS 0:62a4a8ec4ab5 235 size_t trfLen;
MiniTLS 0:62a4a8ec4ab5 236
MiniTLS 0:62a4a8ec4ab5 237 //Send data (if available)
MiniTLS 0:62a4a8ec4ab5 238 if( pDataOut != NULL )
MiniTLS 0:62a4a8ec4ab5 239 {
MiniTLS 0:62a4a8ec4ab5 240 DBG("Sending data");
MiniTLS 0:62a4a8ec4ab5 241 while(true)
MiniTLS 0:62a4a8ec4ab5 242 {
MiniTLS 0:62a4a8ec4ab5 243 size_t writtenLen = 0;
MiniTLS 0:62a4a8ec4ab5 244 pDataOut->read(buf, CHUNK_SIZE, &trfLen);
MiniTLS 0:62a4a8ec4ab5 245 if( pDataOut->getIsChunked() )
MiniTLS 0:62a4a8ec4ab5 246 {
MiniTLS 0:62a4a8ec4ab5 247 //Write chunk header
MiniTLS 0:62a4a8ec4ab5 248 char chunkHeader[16];
MiniTLS 0:62a4a8ec4ab5 249 snprintf(chunkHeader, sizeof(chunkHeader), "%X\r\n", trfLen); //In hex encoding
MiniTLS 0:62a4a8ec4ab5 250 ret = send(chunkHeader);
MiniTLS 0:62a4a8ec4ab5 251 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 252 }
MiniTLS 0:62a4a8ec4ab5 253 else if( trfLen == 0 )
MiniTLS 0:62a4a8ec4ab5 254 {
MiniTLS 0:62a4a8ec4ab5 255 break;
MiniTLS 0:62a4a8ec4ab5 256 }
MiniTLS 0:62a4a8ec4ab5 257 if( trfLen != 0 )
MiniTLS 0:62a4a8ec4ab5 258 {
MiniTLS 0:62a4a8ec4ab5 259 ret = send(buf, trfLen);
MiniTLS 0:62a4a8ec4ab5 260 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 261 }
MiniTLS 0:62a4a8ec4ab5 262
MiniTLS 0:62a4a8ec4ab5 263 if( pDataOut->getIsChunked() )
MiniTLS 0:62a4a8ec4ab5 264 {
MiniTLS 0:62a4a8ec4ab5 265 ret = send("\r\n"); //Chunk-terminating CRLF
MiniTLS 0:62a4a8ec4ab5 266 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 267 }
MiniTLS 0:62a4a8ec4ab5 268 else
MiniTLS 0:62a4a8ec4ab5 269 {
MiniTLS 0:62a4a8ec4ab5 270 writtenLen += trfLen;
MiniTLS 0:62a4a8ec4ab5 271 if( writtenLen >= pDataOut->getDataLen() )
MiniTLS 0:62a4a8ec4ab5 272 {
MiniTLS 0:62a4a8ec4ab5 273 break;
MiniTLS 0:62a4a8ec4ab5 274 }
MiniTLS 0:62a4a8ec4ab5 275 }
MiniTLS 0:62a4a8ec4ab5 276
MiniTLS 0:62a4a8ec4ab5 277 if( trfLen == 0 )
MiniTLS 0:62a4a8ec4ab5 278 {
MiniTLS 0:62a4a8ec4ab5 279 break;
MiniTLS 0:62a4a8ec4ab5 280 }
MiniTLS 0:62a4a8ec4ab5 281 }
MiniTLS 0:62a4a8ec4ab5 282
MiniTLS 0:62a4a8ec4ab5 283 //Flush
MiniTLS 0:62a4a8ec4ab5 284 ret = send(NULL, 0, true);
MiniTLS 0:62a4a8ec4ab5 285 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 286 }
MiniTLS 0:62a4a8ec4ab5 287
MiniTLS 0:62a4a8ec4ab5 288 //Receive response
MiniTLS 0:62a4a8ec4ab5 289 DBG("Receiving response");
MiniTLS 0:62a4a8ec4ab5 290 ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes
MiniTLS 0:62a4a8ec4ab5 291 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 292
MiniTLS 0:62a4a8ec4ab5 293 buf[trfLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 294
MiniTLS 0:62a4a8ec4ab5 295 //Make sure we got the first response line
MiniTLS 0:62a4a8ec4ab5 296 char* crlfPtr = NULL;
MiniTLS 0:62a4a8ec4ab5 297 while( true )
MiniTLS 0:62a4a8ec4ab5 298 {
MiniTLS 0:62a4a8ec4ab5 299 crlfPtr = strstr(buf, "\r\n");
MiniTLS 0:62a4a8ec4ab5 300 if(crlfPtr == NULL)
MiniTLS 0:62a4a8ec4ab5 301 {
MiniTLS 0:62a4a8ec4ab5 302 if( trfLen < CHUNK_SIZE - 1 )
MiniTLS 0:62a4a8ec4ab5 303 {
MiniTLS 0:62a4a8ec4ab5 304 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 305 ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 306 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 307 buf[trfLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 308 DBG("Read %d chars; In buf: [%s]", newTrfLen, buf);
MiniTLS 0:62a4a8ec4ab5 309 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 310 continue;
MiniTLS 0:62a4a8ec4ab5 311 }
MiniTLS 0:62a4a8ec4ab5 312 else
MiniTLS 0:62a4a8ec4ab5 313 {
MiniTLS 0:62a4a8ec4ab5 314 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 315 }
MiniTLS 0:62a4a8ec4ab5 316 }
MiniTLS 0:62a4a8ec4ab5 317 break;
MiniTLS 0:62a4a8ec4ab5 318 }
MiniTLS 0:62a4a8ec4ab5 319
MiniTLS 0:62a4a8ec4ab5 320 int crlfPos = crlfPtr - buf;
MiniTLS 0:62a4a8ec4ab5 321 buf[crlfPos] = '\0';
MiniTLS 0:62a4a8ec4ab5 322
MiniTLS 0:62a4a8ec4ab5 323 //Parse HTTP response
MiniTLS 0:62a4a8ec4ab5 324 //if( sscanf(buf, "HTTP/%*d.%*d %d %*[^\r\n]", &m_httpResponseCode) != 1 )
MiniTLS 0:62a4a8ec4ab5 325 if(crlfPos > 13)
MiniTLS 0:62a4a8ec4ab5 326 {
MiniTLS 0:62a4a8ec4ab5 327 buf[13] = '\0';
MiniTLS 0:62a4a8ec4ab5 328 }
MiniTLS 0:62a4a8ec4ab5 329 if( sscanf(buf, "HTTP/%*d.%*d %d", &m_httpResponseCode) != 1 ) //Kludge for newlib nano
MiniTLS 0:62a4a8ec4ab5 330 {
MiniTLS 0:62a4a8ec4ab5 331 //Cannot match string, error
MiniTLS 0:62a4a8ec4ab5 332 ERR("Not a correct HTTP answer : %s\n", buf);
MiniTLS 0:62a4a8ec4ab5 333 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 334 }
MiniTLS 0:62a4a8ec4ab5 335
MiniTLS 0:62a4a8ec4ab5 336 if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) )
MiniTLS 0:62a4a8ec4ab5 337 {
MiniTLS 0:62a4a8ec4ab5 338 //Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers
MiniTLS 0:62a4a8ec4ab5 339 WARN("Response code %d", m_httpResponseCode);
MiniTLS 0:62a4a8ec4ab5 340 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 341 }
MiniTLS 0:62a4a8ec4ab5 342
MiniTLS 0:62a4a8ec4ab5 343 DBG("Reading headers");
MiniTLS 0:62a4a8ec4ab5 344
MiniTLS 0:62a4a8ec4ab5 345 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 346 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 347
MiniTLS 0:62a4a8ec4ab5 348 size_t recvContentLength = 0;
MiniTLS 0:62a4a8ec4ab5 349 bool recvChunked = false;
MiniTLS 0:62a4a8ec4ab5 350 bool recvLengthUnknown = true;
MiniTLS 0:62a4a8ec4ab5 351 //Now get headers
MiniTLS 0:62a4a8ec4ab5 352 while( true )
MiniTLS 0:62a4a8ec4ab5 353 {
MiniTLS 0:62a4a8ec4ab5 354 crlfPtr = strstr(buf, "\r\n");
MiniTLS 0:62a4a8ec4ab5 355 if(crlfPtr == NULL)
MiniTLS 0:62a4a8ec4ab5 356 {
MiniTLS 0:62a4a8ec4ab5 357 if( trfLen < CHUNK_SIZE - 1 )
MiniTLS 0:62a4a8ec4ab5 358 {
MiniTLS 0:62a4a8ec4ab5 359 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 360 ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 361 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 362 buf[trfLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 363 DBG("Read %d chars; In buf: [%s]", newTrfLen, buf);
MiniTLS 0:62a4a8ec4ab5 364 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 365 continue;
MiniTLS 0:62a4a8ec4ab5 366 }
MiniTLS 0:62a4a8ec4ab5 367 else
MiniTLS 0:62a4a8ec4ab5 368 {
MiniTLS 0:62a4a8ec4ab5 369 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 370 }
MiniTLS 0:62a4a8ec4ab5 371 }
MiniTLS 0:62a4a8ec4ab5 372
MiniTLS 0:62a4a8ec4ab5 373 crlfPos = crlfPtr - buf;
MiniTLS 0:62a4a8ec4ab5 374
MiniTLS 0:62a4a8ec4ab5 375 if(crlfPos == 0) //End of headers
MiniTLS 0:62a4a8ec4ab5 376 {
MiniTLS 0:62a4a8ec4ab5 377 DBG("Headers read");
MiniTLS 0:62a4a8ec4ab5 378 memmove(buf, &buf[2], trfLen - 2 + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 379 trfLen -= 2;
MiniTLS 0:62a4a8ec4ab5 380 break;
MiniTLS 0:62a4a8ec4ab5 381 }
MiniTLS 0:62a4a8ec4ab5 382
MiniTLS 0:62a4a8ec4ab5 383 buf[crlfPos] = '\0';
MiniTLS 0:62a4a8ec4ab5 384
MiniTLS 0:62a4a8ec4ab5 385 char key[32];
MiniTLS 0:62a4a8ec4ab5 386 char value[32];
MiniTLS 0:62a4a8ec4ab5 387
MiniTLS 0:62a4a8ec4ab5 388 //key[31] = '\0';
MiniTLS 0:62a4a8ec4ab5 389 //value[31] = '\0';
MiniTLS 0:62a4a8ec4ab5 390
MiniTLS 0:62a4a8ec4ab5 391 memset(key, 0, 32);
MiniTLS 0:62a4a8ec4ab5 392 memset(value, 0, 32);
MiniTLS 0:62a4a8ec4ab5 393
MiniTLS 0:62a4a8ec4ab5 394 //int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value);
MiniTLS 0:62a4a8ec4ab5 395
MiniTLS 0:62a4a8ec4ab5 396 int n = 0;
MiniTLS 0:62a4a8ec4ab5 397
MiniTLS 0:62a4a8ec4ab5 398 char* keyEnd = strchr(buf, ':');
MiniTLS 0:62a4a8ec4ab5 399 if(keyEnd != NULL)
MiniTLS 0:62a4a8ec4ab5 400 {
MiniTLS 0:62a4a8ec4ab5 401 *keyEnd = '\0';
MiniTLS 0:62a4a8ec4ab5 402 if(strlen(buf) < 32)
MiniTLS 0:62a4a8ec4ab5 403 {
MiniTLS 0:62a4a8ec4ab5 404 strcpy(key, buf);
MiniTLS 0:62a4a8ec4ab5 405 n++;
MiniTLS 0:62a4a8ec4ab5 406 char* valueStart = keyEnd + 2;
MiniTLS 0:62a4a8ec4ab5 407 if( (valueStart - buf) < crlfPos )
MiniTLS 0:62a4a8ec4ab5 408 {
MiniTLS 0:62a4a8ec4ab5 409 if(strlen(valueStart) < 32)
MiniTLS 0:62a4a8ec4ab5 410 {
MiniTLS 0:62a4a8ec4ab5 411 strcpy(value, valueStart);
MiniTLS 0:62a4a8ec4ab5 412 n++;
MiniTLS 0:62a4a8ec4ab5 413 }
MiniTLS 0:62a4a8ec4ab5 414 }
MiniTLS 0:62a4a8ec4ab5 415 }
MiniTLS 0:62a4a8ec4ab5 416 }
MiniTLS 0:62a4a8ec4ab5 417 if ( n == 2 )
MiniTLS 0:62a4a8ec4ab5 418 {
MiniTLS 0:62a4a8ec4ab5 419 DBG("Read header : %s: %s\n", key, value);
MiniTLS 0:62a4a8ec4ab5 420 if( !strcmp(key, "Content-Length") )
MiniTLS 0:62a4a8ec4ab5 421 {
MiniTLS 0:62a4a8ec4ab5 422 sscanf(value, "%d", &recvContentLength);
MiniTLS 0:62a4a8ec4ab5 423 recvLengthUnknown = false;
MiniTLS 0:62a4a8ec4ab5 424 pDataIn->setDataLen(recvContentLength);
MiniTLS 0:62a4a8ec4ab5 425 }
MiniTLS 0:62a4a8ec4ab5 426 else if( !strcmp(key, "Transfer-Encoding") )
MiniTLS 0:62a4a8ec4ab5 427 {
MiniTLS 0:62a4a8ec4ab5 428 if( !strcmp(value, "Chunked") || !strcmp(value, "chunked") )
MiniTLS 0:62a4a8ec4ab5 429 {
MiniTLS 0:62a4a8ec4ab5 430 recvChunked = true;
MiniTLS 0:62a4a8ec4ab5 431 recvLengthUnknown = false;
MiniTLS 0:62a4a8ec4ab5 432 pDataIn->setIsChunked(true);
MiniTLS 0:62a4a8ec4ab5 433 }
MiniTLS 0:62a4a8ec4ab5 434 }
MiniTLS 0:62a4a8ec4ab5 435 else if( !strcmp(key, "Content-Type") )
MiniTLS 0:62a4a8ec4ab5 436 {
MiniTLS 0:62a4a8ec4ab5 437 pDataIn->setDataType(value);
MiniTLS 0:62a4a8ec4ab5 438 }
MiniTLS 0:62a4a8ec4ab5 439
MiniTLS 0:62a4a8ec4ab5 440 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 441 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 442
MiniTLS 0:62a4a8ec4ab5 443 }
MiniTLS 0:62a4a8ec4ab5 444 else
MiniTLS 0:62a4a8ec4ab5 445 {
MiniTLS 0:62a4a8ec4ab5 446 ERR("Could not parse header");
MiniTLS 0:62a4a8ec4ab5 447 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 448 }
MiniTLS 0:62a4a8ec4ab5 449
MiniTLS 0:62a4a8ec4ab5 450 }
MiniTLS 0:62a4a8ec4ab5 451
MiniTLS 0:62a4a8ec4ab5 452 //Receive data
MiniTLS 0:62a4a8ec4ab5 453 DBG("Receiving data");
MiniTLS 0:62a4a8ec4ab5 454 while(true)
MiniTLS 0:62a4a8ec4ab5 455 {
MiniTLS 0:62a4a8ec4ab5 456 size_t readLen = 0;
MiniTLS 0:62a4a8ec4ab5 457
MiniTLS 0:62a4a8ec4ab5 458 if( recvChunked )
MiniTLS 0:62a4a8ec4ab5 459 {
MiniTLS 0:62a4a8ec4ab5 460 //Read chunk header
MiniTLS 0:62a4a8ec4ab5 461 bool foundCrlf;
MiniTLS 0:62a4a8ec4ab5 462 do
MiniTLS 0:62a4a8ec4ab5 463 {
MiniTLS 0:62a4a8ec4ab5 464 foundCrlf = false;
MiniTLS 0:62a4a8ec4ab5 465 crlfPos=0;
MiniTLS 0:62a4a8ec4ab5 466 buf[trfLen]=0;
MiniTLS 0:62a4a8ec4ab5 467 if(trfLen >= 2)
MiniTLS 0:62a4a8ec4ab5 468 {
MiniTLS 0:62a4a8ec4ab5 469 for(; crlfPos < trfLen - 2; crlfPos++)
MiniTLS 0:62a4a8ec4ab5 470 {
MiniTLS 0:62a4a8ec4ab5 471 if( buf[crlfPos] == '\r' && buf[crlfPos + 1] == '\n' )
MiniTLS 0:62a4a8ec4ab5 472 {
MiniTLS 0:62a4a8ec4ab5 473 foundCrlf = true;
MiniTLS 0:62a4a8ec4ab5 474 break;
MiniTLS 0:62a4a8ec4ab5 475 }
MiniTLS 0:62a4a8ec4ab5 476 }
MiniTLS 0:62a4a8ec4ab5 477 }
MiniTLS 0:62a4a8ec4ab5 478 if(!foundCrlf) //Try to read more
MiniTLS 0:62a4a8ec4ab5 479 {
MiniTLS 0:62a4a8ec4ab5 480 if( trfLen < CHUNK_SIZE )
MiniTLS 0:62a4a8ec4ab5 481 {
MiniTLS 0:62a4a8ec4ab5 482 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 483 ret = recv(buf + trfLen, 0, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 484 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 485 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 486 continue;
MiniTLS 0:62a4a8ec4ab5 487 }
MiniTLS 0:62a4a8ec4ab5 488 else
MiniTLS 0:62a4a8ec4ab5 489 {
MiniTLS 0:62a4a8ec4ab5 490 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 491 }
MiniTLS 0:62a4a8ec4ab5 492 }
MiniTLS 0:62a4a8ec4ab5 493 } while(!foundCrlf);
MiniTLS 0:62a4a8ec4ab5 494 buf[crlfPos] = '\0';
MiniTLS 0:62a4a8ec4ab5 495 int n = sscanf(buf, "%x", &readLen);
MiniTLS 0:62a4a8ec4ab5 496 if(n!=1)
MiniTLS 0:62a4a8ec4ab5 497 {
MiniTLS 0:62a4a8ec4ab5 498 ERR("Could not read chunk length");
MiniTLS 0:62a4a8ec4ab5 499 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 500 }
MiniTLS 0:62a4a8ec4ab5 501
MiniTLS 0:62a4a8ec4ab5 502 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2)); //Not need to move NULL-terminating char any more
MiniTLS 0:62a4a8ec4ab5 503 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 504
MiniTLS 0:62a4a8ec4ab5 505 if( readLen == 0 )
MiniTLS 0:62a4a8ec4ab5 506 {
MiniTLS 0:62a4a8ec4ab5 507 //Last chunk
MiniTLS 0:62a4a8ec4ab5 508 break;
MiniTLS 0:62a4a8ec4ab5 509 }
MiniTLS 0:62a4a8ec4ab5 510 }
MiniTLS 0:62a4a8ec4ab5 511 else
MiniTLS 0:62a4a8ec4ab5 512 {
MiniTLS 0:62a4a8ec4ab5 513 readLen = recvContentLength;
MiniTLS 0:62a4a8ec4ab5 514 }
MiniTLS 0:62a4a8ec4ab5 515
MiniTLS 0:62a4a8ec4ab5 516 DBG("Retrieving %d bytes (%d bytes in buffer)", readLen, trfLen);
MiniTLS 0:62a4a8ec4ab5 517
MiniTLS 0:62a4a8ec4ab5 518 do
MiniTLS 0:62a4a8ec4ab5 519 {
MiniTLS 0:62a4a8ec4ab5 520 if(recvLengthUnknown )
MiniTLS 0:62a4a8ec4ab5 521 {
MiniTLS 0:62a4a8ec4ab5 522 readLen = trfLen;
MiniTLS 0:62a4a8ec4ab5 523 }
MiniTLS 0:62a4a8ec4ab5 524 pDataIn->write(buf, MIN(trfLen, readLen));
MiniTLS 0:62a4a8ec4ab5 525 if(!recvLengthUnknown)
MiniTLS 0:62a4a8ec4ab5 526 {
MiniTLS 0:62a4a8ec4ab5 527 if( trfLen > readLen )
MiniTLS 0:62a4a8ec4ab5 528 {
MiniTLS 0:62a4a8ec4ab5 529 memmove(buf, &buf[readLen], trfLen - readLen);
MiniTLS 0:62a4a8ec4ab5 530 trfLen -= readLen;
MiniTLS 0:62a4a8ec4ab5 531 readLen = 0;
MiniTLS 0:62a4a8ec4ab5 532 }
MiniTLS 0:62a4a8ec4ab5 533 else
MiniTLS 0:62a4a8ec4ab5 534 {
MiniTLS 0:62a4a8ec4ab5 535 readLen -= trfLen;
MiniTLS 0:62a4a8ec4ab5 536 }
MiniTLS 0:62a4a8ec4ab5 537 }
MiniTLS 0:62a4a8ec4ab5 538 else
MiniTLS 0:62a4a8ec4ab5 539 {
MiniTLS 0:62a4a8ec4ab5 540 trfLen = 0;
MiniTLS 0:62a4a8ec4ab5 541 }
MiniTLS 0:62a4a8ec4ab5 542
MiniTLS 0:62a4a8ec4ab5 543 if(readLen || recvLengthUnknown)
MiniTLS 0:62a4a8ec4ab5 544 {
MiniTLS 0:62a4a8ec4ab5 545 ret = recv(buf, 1, CHUNK_SIZE - trfLen - 1, &trfLen);
MiniTLS 0:62a4a8ec4ab5 546 if(recvLengthUnknown && (ret == HTTP_CLOSED))
MiniTLS 0:62a4a8ec4ab5 547 {
MiniTLS 0:62a4a8ec4ab5 548 //Write and exit
MiniTLS 0:62a4a8ec4ab5 549 pDataIn->write(buf, trfLen);
MiniTLS 0:62a4a8ec4ab5 550 break;
MiniTLS 0:62a4a8ec4ab5 551 }
MiniTLS 0:62a4a8ec4ab5 552 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 553 if(recvLengthUnknown && (trfLen == 0))
MiniTLS 0:62a4a8ec4ab5 554 {
MiniTLS 0:62a4a8ec4ab5 555 break;
MiniTLS 0:62a4a8ec4ab5 556 }
MiniTLS 0:62a4a8ec4ab5 557 }
MiniTLS 0:62a4a8ec4ab5 558 } while(readLen || recvLengthUnknown);
MiniTLS 0:62a4a8ec4ab5 559
MiniTLS 0:62a4a8ec4ab5 560 if( recvChunked )
MiniTLS 0:62a4a8ec4ab5 561 {
MiniTLS 0:62a4a8ec4ab5 562 if(trfLen < 2)
MiniTLS 0:62a4a8ec4ab5 563 {
MiniTLS 0:62a4a8ec4ab5 564 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 565 //Read missing chars to find end of chunk
MiniTLS 0:62a4a8ec4ab5 566 ret = recv(buf + trfLen, 2 - trfLen, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 567 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 568 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 569 }
MiniTLS 0:62a4a8ec4ab5 570 if( (buf[0] != '\r') || (buf[1] != '\n') )
MiniTLS 0:62a4a8ec4ab5 571 {
MiniTLS 0:62a4a8ec4ab5 572 ERR("Format error");
MiniTLS 0:62a4a8ec4ab5 573 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 574 }
MiniTLS 0:62a4a8ec4ab5 575 memmove(buf, &buf[2], trfLen - 2);
MiniTLS 0:62a4a8ec4ab5 576 trfLen -= 2;
MiniTLS 0:62a4a8ec4ab5 577 }
MiniTLS 0:62a4a8ec4ab5 578 else
MiniTLS 0:62a4a8ec4ab5 579 {
MiniTLS 0:62a4a8ec4ab5 580 break;
MiniTLS 0:62a4a8ec4ab5 581 }
MiniTLS 0:62a4a8ec4ab5 582
MiniTLS 0:62a4a8ec4ab5 583 }
MiniTLS 0:62a4a8ec4ab5 584
MiniTLS 0:62a4a8ec4ab5 585 m_sock.close();
MiniTLS 0:62a4a8ec4ab5 586 DBG("Completed HTTP transaction");
MiniTLS 0:62a4a8ec4ab5 587
MiniTLS 0:62a4a8ec4ab5 588 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 589 }
MiniTLS 0:62a4a8ec4ab5 590
MiniTLS 0:62a4a8ec4ab5 591 HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure
MiniTLS 0:62a4a8ec4ab5 592 {
MiniTLS 0:62a4a8ec4ab5 593 DBG("Trying to read between %d and %d bytes", minLen, maxLen);
MiniTLS 0:62a4a8ec4ab5 594 size_t readLen = 0;
MiniTLS 0:62a4a8ec4ab5 595
MiniTLS 0:62a4a8ec4ab5 596 /* TODO */
MiniTLS 0:62a4a8ec4ab5 597 /*
MiniTLS 0:62a4a8ec4ab5 598 if(!m_sock.is_connected())
MiniTLS 0:62a4a8ec4ab5 599 {
MiniTLS 0:62a4a8ec4ab5 600 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 601 return HTTP_CLOSED; //Connection was closed by server
MiniTLS 0:62a4a8ec4ab5 602 }
MiniTLS 0:62a4a8ec4ab5 603 */
MiniTLS 0:62a4a8ec4ab5 604
MiniTLS 0:62a4a8ec4ab5 605 minitls_err_t ret = m_sock.read((uint8_t*)buf, minLen, maxLen, pReadLen, m_timeout);
MiniTLS 0:62a4a8ec4ab5 606 if(ret)
MiniTLS 0:62a4a8ec4ab5 607 {
MiniTLS 0:62a4a8ec4ab5 608 WARN("TLS Error %d", ret);
MiniTLS 0:62a4a8ec4ab5 609 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 610 }
MiniTLS 0:62a4a8ec4ab5 611
MiniTLS 0:62a4a8ec4ab5 612 DBG("Read %d bytes", *pReadLen);
MiniTLS 0:62a4a8ec4ab5 613
MiniTLS 0:62a4a8ec4ab5 614 if(*pReadLen < minLen)
MiniTLS 0:62a4a8ec4ab5 615 {
MiniTLS 0:62a4a8ec4ab5 616 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 617 return HTTP_CLOSED;
MiniTLS 0:62a4a8ec4ab5 618 }
MiniTLS 0:62a4a8ec4ab5 619
MiniTLS 0:62a4a8ec4ab5 620 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 621 }
MiniTLS 0:62a4a8ec4ab5 622
MiniTLS 0:62a4a8ec4ab5 623 HTTPResult HTTPClient::send(char* buf, size_t len, bool flush) //0 on success, err code on failure
MiniTLS 0:62a4a8ec4ab5 624 {
MiniTLS 0:62a4a8ec4ab5 625 if(len == 0)
MiniTLS 0:62a4a8ec4ab5 626 {
MiniTLS 0:62a4a8ec4ab5 627 len = strlen(buf);
MiniTLS 0:62a4a8ec4ab5 628 }
MiniTLS 0:62a4a8ec4ab5 629
MiniTLS 0:62a4a8ec4ab5 630 size_t writtenLen = 0;
MiniTLS 0:62a4a8ec4ab5 631 minitls_err_t ret;
MiniTLS 0:62a4a8ec4ab5 632 if(len > 0)
MiniTLS 0:62a4a8ec4ab5 633 {
MiniTLS 0:62a4a8ec4ab5 634 ret = m_sock.write((uint8_t*)buf, len, &writtenLen, m_timeout);
MiniTLS 0:62a4a8ec4ab5 635 if(ret)
MiniTLS 0:62a4a8ec4ab5 636 {
MiniTLS 0:62a4a8ec4ab5 637 WARN("TLS Error %d", ret);
MiniTLS 0:62a4a8ec4ab5 638 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 639 }
MiniTLS 0:62a4a8ec4ab5 640
MiniTLS 0:62a4a8ec4ab5 641 DBG("Wrote %d bytes", writtenLen);
MiniTLS 0:62a4a8ec4ab5 642
MiniTLS 0:62a4a8ec4ab5 643 if(writtenLen < len)
MiniTLS 0:62a4a8ec4ab5 644 {
MiniTLS 0:62a4a8ec4ab5 645 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 646 return HTTP_CLOSED;
MiniTLS 0:62a4a8ec4ab5 647 }
MiniTLS 0:62a4a8ec4ab5 648 }
MiniTLS 0:62a4a8ec4ab5 649
MiniTLS 0:62a4a8ec4ab5 650 if(flush)
MiniTLS 0:62a4a8ec4ab5 651 {
MiniTLS 0:62a4a8ec4ab5 652 m_sock.flush(m_timeout);
MiniTLS 0:62a4a8ec4ab5 653 }
MiniTLS 0:62a4a8ec4ab5 654
MiniTLS 0:62a4a8ec4ab5 655 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 656 }
MiniTLS 0:62a4a8ec4ab5 657
MiniTLS 0:62a4a8ec4ab5 658 HTTPResult HTTPClient::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
MiniTLS 0:62a4a8ec4ab5 659 {
MiniTLS 0:62a4a8ec4ab5 660 char* schemePtr = (char*) url;
MiniTLS 0:62a4a8ec4ab5 661 char* hostPtr = (char*) strstr(url, "://");
MiniTLS 0:62a4a8ec4ab5 662 if(hostPtr == NULL)
MiniTLS 0:62a4a8ec4ab5 663 {
MiniTLS 0:62a4a8ec4ab5 664 WARN("Could not find host");
MiniTLS 0:62a4a8ec4ab5 665 return HTTP_PARSE; //URL is invalid
MiniTLS 0:62a4a8ec4ab5 666 }
MiniTLS 0:62a4a8ec4ab5 667
MiniTLS 0:62a4a8ec4ab5 668 if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 669 {
MiniTLS 0:62a4a8ec4ab5 670 WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
MiniTLS 0:62a4a8ec4ab5 671 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 672 }
MiniTLS 0:62a4a8ec4ab5 673 memcpy(scheme, schemePtr, hostPtr - schemePtr);
MiniTLS 0:62a4a8ec4ab5 674 scheme[hostPtr - schemePtr] = '\0';
MiniTLS 0:62a4a8ec4ab5 675
MiniTLS 0:62a4a8ec4ab5 676 hostPtr+=3;
MiniTLS 0:62a4a8ec4ab5 677
MiniTLS 0:62a4a8ec4ab5 678 size_t hostLen = 0;
MiniTLS 0:62a4a8ec4ab5 679
MiniTLS 0:62a4a8ec4ab5 680 char* portPtr = strchr(hostPtr, ':');
MiniTLS 0:62a4a8ec4ab5 681 if( portPtr != NULL )
MiniTLS 0:62a4a8ec4ab5 682 {
MiniTLS 0:62a4a8ec4ab5 683 hostLen = portPtr - hostPtr;
MiniTLS 0:62a4a8ec4ab5 684 portPtr++;
MiniTLS 0:62a4a8ec4ab5 685 if( sscanf(portPtr, "%hu", port) != 1)
MiniTLS 0:62a4a8ec4ab5 686 {
MiniTLS 0:62a4a8ec4ab5 687 WARN("Could not find port");
MiniTLS 0:62a4a8ec4ab5 688 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 689 }
MiniTLS 0:62a4a8ec4ab5 690 }
MiniTLS 0:62a4a8ec4ab5 691 else
MiniTLS 0:62a4a8ec4ab5 692 {
MiniTLS 0:62a4a8ec4ab5 693 *port=0;
MiniTLS 0:62a4a8ec4ab5 694 }
MiniTLS 0:62a4a8ec4ab5 695 char* pathPtr = strchr(hostPtr, '/');
MiniTLS 0:62a4a8ec4ab5 696 if( hostLen == 0 )
MiniTLS 0:62a4a8ec4ab5 697 {
MiniTLS 0:62a4a8ec4ab5 698 hostLen = pathPtr - hostPtr;
MiniTLS 0:62a4a8ec4ab5 699 }
MiniTLS 0:62a4a8ec4ab5 700
MiniTLS 0:62a4a8ec4ab5 701 if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 702 {
MiniTLS 0:62a4a8ec4ab5 703 WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
MiniTLS 0:62a4a8ec4ab5 704 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 705 }
MiniTLS 0:62a4a8ec4ab5 706 memcpy(host, hostPtr, hostLen);
MiniTLS 0:62a4a8ec4ab5 707 host[hostLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 708
MiniTLS 0:62a4a8ec4ab5 709 size_t pathLen;
MiniTLS 0:62a4a8ec4ab5 710 char* fragmentPtr = strchr(hostPtr, '#');
MiniTLS 0:62a4a8ec4ab5 711 if(fragmentPtr != NULL)
MiniTLS 0:62a4a8ec4ab5 712 {
MiniTLS 0:62a4a8ec4ab5 713 pathLen = fragmentPtr - pathPtr;
MiniTLS 0:62a4a8ec4ab5 714 }
MiniTLS 0:62a4a8ec4ab5 715 else
MiniTLS 0:62a4a8ec4ab5 716 {
MiniTLS 0:62a4a8ec4ab5 717 pathLen = strlen(pathPtr);
MiniTLS 0:62a4a8ec4ab5 718 }
MiniTLS 0:62a4a8ec4ab5 719
MiniTLS 0:62a4a8ec4ab5 720 if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 721 {
MiniTLS 0:62a4a8ec4ab5 722 WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
MiniTLS 0:62a4a8ec4ab5 723 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 724 }
MiniTLS 0:62a4a8ec4ab5 725 memcpy(path, pathPtr, pathLen);
MiniTLS 0:62a4a8ec4ab5 726 path[pathLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 727
MiniTLS 0:62a4a8ec4ab5 728 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 729 }