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

Fork of MiniTLS-HTTPSClient by Donatien Garnier

Committer:
shiyilei
Date:
Fri Feb 06 06:18:13 2015 +0000
Revision:
1:4309aff9b1db
Parent:
0:62a4a8ec4ab5
This is the new MiniTLS program which build the connection with the website httpbin.org

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
shiyilei 1:4309aff9b1db 336
shiyilei 1:4309aff9b1db 337 if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) )
shiyilei 1:4309aff9b1db 338 {
MiniTLS 0:62a4a8ec4ab5 339 //Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers
MiniTLS 0:62a4a8ec4ab5 340 WARN("Response code %d", m_httpResponseCode);
MiniTLS 0:62a4a8ec4ab5 341 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 342 }
MiniTLS 0:62a4a8ec4ab5 343
MiniTLS 0:62a4a8ec4ab5 344 DBG("Reading headers");
MiniTLS 0:62a4a8ec4ab5 345
MiniTLS 0:62a4a8ec4ab5 346 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 347 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 348
MiniTLS 0:62a4a8ec4ab5 349 size_t recvContentLength = 0;
MiniTLS 0:62a4a8ec4ab5 350 bool recvChunked = false;
MiniTLS 0:62a4a8ec4ab5 351 bool recvLengthUnknown = true;
MiniTLS 0:62a4a8ec4ab5 352 //Now get headers
MiniTLS 0:62a4a8ec4ab5 353 while( true )
MiniTLS 0:62a4a8ec4ab5 354 {
MiniTLS 0:62a4a8ec4ab5 355 crlfPtr = strstr(buf, "\r\n");
MiniTLS 0:62a4a8ec4ab5 356 if(crlfPtr == NULL)
MiniTLS 0:62a4a8ec4ab5 357 {
MiniTLS 0:62a4a8ec4ab5 358 if( trfLen < CHUNK_SIZE - 1 )
MiniTLS 0:62a4a8ec4ab5 359 {
MiniTLS 0:62a4a8ec4ab5 360 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 361 ret = recv(buf + trfLen, 1, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 362 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 363 buf[trfLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 364 DBG("Read %d chars; In buf: [%s]", newTrfLen, buf);
MiniTLS 0:62a4a8ec4ab5 365 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 366 continue;
MiniTLS 0:62a4a8ec4ab5 367 }
MiniTLS 0:62a4a8ec4ab5 368 else
MiniTLS 0:62a4a8ec4ab5 369 {
MiniTLS 0:62a4a8ec4ab5 370 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 371 }
MiniTLS 0:62a4a8ec4ab5 372 }
MiniTLS 0:62a4a8ec4ab5 373
MiniTLS 0:62a4a8ec4ab5 374 crlfPos = crlfPtr - buf;
MiniTLS 0:62a4a8ec4ab5 375
MiniTLS 0:62a4a8ec4ab5 376 if(crlfPos == 0) //End of headers
MiniTLS 0:62a4a8ec4ab5 377 {
MiniTLS 0:62a4a8ec4ab5 378 DBG("Headers read");
MiniTLS 0:62a4a8ec4ab5 379 memmove(buf, &buf[2], trfLen - 2 + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 380 trfLen -= 2;
MiniTLS 0:62a4a8ec4ab5 381 break;
MiniTLS 0:62a4a8ec4ab5 382 }
MiniTLS 0:62a4a8ec4ab5 383
MiniTLS 0:62a4a8ec4ab5 384 buf[crlfPos] = '\0';
MiniTLS 0:62a4a8ec4ab5 385
MiniTLS 0:62a4a8ec4ab5 386 char key[32];
MiniTLS 0:62a4a8ec4ab5 387 char value[32];
MiniTLS 0:62a4a8ec4ab5 388
MiniTLS 0:62a4a8ec4ab5 389 //key[31] = '\0';
MiniTLS 0:62a4a8ec4ab5 390 //value[31] = '\0';
MiniTLS 0:62a4a8ec4ab5 391
MiniTLS 0:62a4a8ec4ab5 392 memset(key, 0, 32);
MiniTLS 0:62a4a8ec4ab5 393 memset(value, 0, 32);
MiniTLS 0:62a4a8ec4ab5 394
MiniTLS 0:62a4a8ec4ab5 395 //int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value);
MiniTLS 0:62a4a8ec4ab5 396
MiniTLS 0:62a4a8ec4ab5 397 int n = 0;
MiniTLS 0:62a4a8ec4ab5 398
MiniTLS 0:62a4a8ec4ab5 399 char* keyEnd = strchr(buf, ':');
MiniTLS 0:62a4a8ec4ab5 400 if(keyEnd != NULL)
MiniTLS 0:62a4a8ec4ab5 401 {
MiniTLS 0:62a4a8ec4ab5 402 *keyEnd = '\0';
shiyilei 1:4309aff9b1db 403 if(strlen(buf) < 50)
MiniTLS 0:62a4a8ec4ab5 404 {
MiniTLS 0:62a4a8ec4ab5 405 strcpy(key, buf);
MiniTLS 0:62a4a8ec4ab5 406 n++;
MiniTLS 0:62a4a8ec4ab5 407 char* valueStart = keyEnd + 2;
MiniTLS 0:62a4a8ec4ab5 408 if( (valueStart - buf) < crlfPos )
MiniTLS 0:62a4a8ec4ab5 409 {
shiyilei 1:4309aff9b1db 410 printf("valuestart=%d\r\n",strlen(valueStart));
MiniTLS 0:62a4a8ec4ab5 411 if(strlen(valueStart) < 32)
MiniTLS 0:62a4a8ec4ab5 412 {
MiniTLS 0:62a4a8ec4ab5 413 strcpy(value, valueStart);
MiniTLS 0:62a4a8ec4ab5 414 n++;
MiniTLS 0:62a4a8ec4ab5 415 }
MiniTLS 0:62a4a8ec4ab5 416 }
MiniTLS 0:62a4a8ec4ab5 417 }
MiniTLS 0:62a4a8ec4ab5 418 }
shiyilei 1:4309aff9b1db 419 printf("n=%d\r\n",n);
MiniTLS 0:62a4a8ec4ab5 420 if ( n == 2 )
MiniTLS 0:62a4a8ec4ab5 421 {
MiniTLS 0:62a4a8ec4ab5 422 DBG("Read header : %s: %s\n", key, value);
MiniTLS 0:62a4a8ec4ab5 423 if( !strcmp(key, "Content-Length") )
MiniTLS 0:62a4a8ec4ab5 424 {
MiniTLS 0:62a4a8ec4ab5 425 sscanf(value, "%d", &recvContentLength);
MiniTLS 0:62a4a8ec4ab5 426 recvLengthUnknown = false;
MiniTLS 0:62a4a8ec4ab5 427 pDataIn->setDataLen(recvContentLength);
MiniTLS 0:62a4a8ec4ab5 428 }
MiniTLS 0:62a4a8ec4ab5 429 else if( !strcmp(key, "Transfer-Encoding") )
MiniTLS 0:62a4a8ec4ab5 430 {
MiniTLS 0:62a4a8ec4ab5 431 if( !strcmp(value, "Chunked") || !strcmp(value, "chunked") )
MiniTLS 0:62a4a8ec4ab5 432 {
MiniTLS 0:62a4a8ec4ab5 433 recvChunked = true;
MiniTLS 0:62a4a8ec4ab5 434 recvLengthUnknown = false;
MiniTLS 0:62a4a8ec4ab5 435 pDataIn->setIsChunked(true);
MiniTLS 0:62a4a8ec4ab5 436 }
MiniTLS 0:62a4a8ec4ab5 437 }
MiniTLS 0:62a4a8ec4ab5 438 else if( !strcmp(key, "Content-Type") )
MiniTLS 0:62a4a8ec4ab5 439 {
MiniTLS 0:62a4a8ec4ab5 440 pDataIn->setDataType(value);
MiniTLS 0:62a4a8ec4ab5 441 }
MiniTLS 0:62a4a8ec4ab5 442
MiniTLS 0:62a4a8ec4ab5 443 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well
MiniTLS 0:62a4a8ec4ab5 444 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 445
MiniTLS 0:62a4a8ec4ab5 446 }
MiniTLS 0:62a4a8ec4ab5 447 else
MiniTLS 0:62a4a8ec4ab5 448 {
MiniTLS 0:62a4a8ec4ab5 449 ERR("Could not parse header");
MiniTLS 0:62a4a8ec4ab5 450 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 451 }
MiniTLS 0:62a4a8ec4ab5 452
MiniTLS 0:62a4a8ec4ab5 453 }
MiniTLS 0:62a4a8ec4ab5 454
MiniTLS 0:62a4a8ec4ab5 455 //Receive data
MiniTLS 0:62a4a8ec4ab5 456 DBG("Receiving data");
MiniTLS 0:62a4a8ec4ab5 457 while(true)
MiniTLS 0:62a4a8ec4ab5 458 {
MiniTLS 0:62a4a8ec4ab5 459 size_t readLen = 0;
MiniTLS 0:62a4a8ec4ab5 460
MiniTLS 0:62a4a8ec4ab5 461 if( recvChunked )
MiniTLS 0:62a4a8ec4ab5 462 {
MiniTLS 0:62a4a8ec4ab5 463 //Read chunk header
MiniTLS 0:62a4a8ec4ab5 464 bool foundCrlf;
MiniTLS 0:62a4a8ec4ab5 465 do
MiniTLS 0:62a4a8ec4ab5 466 {
MiniTLS 0:62a4a8ec4ab5 467 foundCrlf = false;
MiniTLS 0:62a4a8ec4ab5 468 crlfPos=0;
MiniTLS 0:62a4a8ec4ab5 469 buf[trfLen]=0;
MiniTLS 0:62a4a8ec4ab5 470 if(trfLen >= 2)
MiniTLS 0:62a4a8ec4ab5 471 {
MiniTLS 0:62a4a8ec4ab5 472 for(; crlfPos < trfLen - 2; crlfPos++)
MiniTLS 0:62a4a8ec4ab5 473 {
MiniTLS 0:62a4a8ec4ab5 474 if( buf[crlfPos] == '\r' && buf[crlfPos + 1] == '\n' )
MiniTLS 0:62a4a8ec4ab5 475 {
MiniTLS 0:62a4a8ec4ab5 476 foundCrlf = true;
MiniTLS 0:62a4a8ec4ab5 477 break;
MiniTLS 0:62a4a8ec4ab5 478 }
MiniTLS 0:62a4a8ec4ab5 479 }
MiniTLS 0:62a4a8ec4ab5 480 }
MiniTLS 0:62a4a8ec4ab5 481 if(!foundCrlf) //Try to read more
MiniTLS 0:62a4a8ec4ab5 482 {
MiniTLS 0:62a4a8ec4ab5 483 if( trfLen < CHUNK_SIZE )
MiniTLS 0:62a4a8ec4ab5 484 {
MiniTLS 0:62a4a8ec4ab5 485 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 486 ret = recv(buf + trfLen, 0, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 487 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 488 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 489 continue;
MiniTLS 0:62a4a8ec4ab5 490 }
MiniTLS 0:62a4a8ec4ab5 491 else
MiniTLS 0:62a4a8ec4ab5 492 {
MiniTLS 0:62a4a8ec4ab5 493 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 494 }
MiniTLS 0:62a4a8ec4ab5 495 }
MiniTLS 0:62a4a8ec4ab5 496 } while(!foundCrlf);
MiniTLS 0:62a4a8ec4ab5 497 buf[crlfPos] = '\0';
MiniTLS 0:62a4a8ec4ab5 498 int n = sscanf(buf, "%x", &readLen);
MiniTLS 0:62a4a8ec4ab5 499 if(n!=1)
MiniTLS 0:62a4a8ec4ab5 500 {
MiniTLS 0:62a4a8ec4ab5 501 ERR("Could not read chunk length");
MiniTLS 0:62a4a8ec4ab5 502 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 503 }
MiniTLS 0:62a4a8ec4ab5 504
MiniTLS 0:62a4a8ec4ab5 505 memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2)); //Not need to move NULL-terminating char any more
MiniTLS 0:62a4a8ec4ab5 506 trfLen -= (crlfPos + 2);
MiniTLS 0:62a4a8ec4ab5 507
MiniTLS 0:62a4a8ec4ab5 508 if( readLen == 0 )
MiniTLS 0:62a4a8ec4ab5 509 {
MiniTLS 0:62a4a8ec4ab5 510 //Last chunk
MiniTLS 0:62a4a8ec4ab5 511 break;
MiniTLS 0:62a4a8ec4ab5 512 }
MiniTLS 0:62a4a8ec4ab5 513 }
MiniTLS 0:62a4a8ec4ab5 514 else
MiniTLS 0:62a4a8ec4ab5 515 {
MiniTLS 0:62a4a8ec4ab5 516 readLen = recvContentLength;
MiniTLS 0:62a4a8ec4ab5 517 }
MiniTLS 0:62a4a8ec4ab5 518
MiniTLS 0:62a4a8ec4ab5 519 DBG("Retrieving %d bytes (%d bytes in buffer)", readLen, trfLen);
MiniTLS 0:62a4a8ec4ab5 520
MiniTLS 0:62a4a8ec4ab5 521 do
MiniTLS 0:62a4a8ec4ab5 522 {
MiniTLS 0:62a4a8ec4ab5 523 if(recvLengthUnknown )
MiniTLS 0:62a4a8ec4ab5 524 {
MiniTLS 0:62a4a8ec4ab5 525 readLen = trfLen;
MiniTLS 0:62a4a8ec4ab5 526 }
MiniTLS 0:62a4a8ec4ab5 527 pDataIn->write(buf, MIN(trfLen, readLen));
MiniTLS 0:62a4a8ec4ab5 528 if(!recvLengthUnknown)
MiniTLS 0:62a4a8ec4ab5 529 {
MiniTLS 0:62a4a8ec4ab5 530 if( trfLen > readLen )
MiniTLS 0:62a4a8ec4ab5 531 {
MiniTLS 0:62a4a8ec4ab5 532 memmove(buf, &buf[readLen], trfLen - readLen);
MiniTLS 0:62a4a8ec4ab5 533 trfLen -= readLen;
MiniTLS 0:62a4a8ec4ab5 534 readLen = 0;
MiniTLS 0:62a4a8ec4ab5 535 }
MiniTLS 0:62a4a8ec4ab5 536 else
MiniTLS 0:62a4a8ec4ab5 537 {
MiniTLS 0:62a4a8ec4ab5 538 readLen -= trfLen;
MiniTLS 0:62a4a8ec4ab5 539 }
MiniTLS 0:62a4a8ec4ab5 540 }
MiniTLS 0:62a4a8ec4ab5 541 else
MiniTLS 0:62a4a8ec4ab5 542 {
MiniTLS 0:62a4a8ec4ab5 543 trfLen = 0;
MiniTLS 0:62a4a8ec4ab5 544 }
MiniTLS 0:62a4a8ec4ab5 545
MiniTLS 0:62a4a8ec4ab5 546 if(readLen || recvLengthUnknown)
MiniTLS 0:62a4a8ec4ab5 547 {
MiniTLS 0:62a4a8ec4ab5 548 ret = recv(buf, 1, CHUNK_SIZE - trfLen - 1, &trfLen);
MiniTLS 0:62a4a8ec4ab5 549 if(recvLengthUnknown && (ret == HTTP_CLOSED))
MiniTLS 0:62a4a8ec4ab5 550 {
MiniTLS 0:62a4a8ec4ab5 551 //Write and exit
MiniTLS 0:62a4a8ec4ab5 552 pDataIn->write(buf, trfLen);
MiniTLS 0:62a4a8ec4ab5 553 break;
MiniTLS 0:62a4a8ec4ab5 554 }
MiniTLS 0:62a4a8ec4ab5 555 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 556 if(recvLengthUnknown && (trfLen == 0))
MiniTLS 0:62a4a8ec4ab5 557 {
MiniTLS 0:62a4a8ec4ab5 558 break;
MiniTLS 0:62a4a8ec4ab5 559 }
MiniTLS 0:62a4a8ec4ab5 560 }
MiniTLS 0:62a4a8ec4ab5 561 } while(readLen || recvLengthUnknown);
MiniTLS 0:62a4a8ec4ab5 562
MiniTLS 0:62a4a8ec4ab5 563 if( recvChunked )
MiniTLS 0:62a4a8ec4ab5 564 {
MiniTLS 0:62a4a8ec4ab5 565 if(trfLen < 2)
MiniTLS 0:62a4a8ec4ab5 566 {
MiniTLS 0:62a4a8ec4ab5 567 size_t newTrfLen;
MiniTLS 0:62a4a8ec4ab5 568 //Read missing chars to find end of chunk
MiniTLS 0:62a4a8ec4ab5 569 ret = recv(buf + trfLen, 2 - trfLen, CHUNK_SIZE - trfLen - 1, &newTrfLen);
MiniTLS 0:62a4a8ec4ab5 570 CHECK_CONN_ERR(ret);
MiniTLS 0:62a4a8ec4ab5 571 trfLen += newTrfLen;
MiniTLS 0:62a4a8ec4ab5 572 }
MiniTLS 0:62a4a8ec4ab5 573 if( (buf[0] != '\r') || (buf[1] != '\n') )
MiniTLS 0:62a4a8ec4ab5 574 {
MiniTLS 0:62a4a8ec4ab5 575 ERR("Format error");
MiniTLS 0:62a4a8ec4ab5 576 PRTCL_ERR();
MiniTLS 0:62a4a8ec4ab5 577 }
MiniTLS 0:62a4a8ec4ab5 578 memmove(buf, &buf[2], trfLen - 2);
MiniTLS 0:62a4a8ec4ab5 579 trfLen -= 2;
MiniTLS 0:62a4a8ec4ab5 580 }
MiniTLS 0:62a4a8ec4ab5 581 else
MiniTLS 0:62a4a8ec4ab5 582 {
MiniTLS 0:62a4a8ec4ab5 583 break;
MiniTLS 0:62a4a8ec4ab5 584 }
MiniTLS 0:62a4a8ec4ab5 585
MiniTLS 0:62a4a8ec4ab5 586 }
MiniTLS 0:62a4a8ec4ab5 587
MiniTLS 0:62a4a8ec4ab5 588 m_sock.close();
MiniTLS 0:62a4a8ec4ab5 589 DBG("Completed HTTP transaction");
MiniTLS 0:62a4a8ec4ab5 590
MiniTLS 0:62a4a8ec4ab5 591 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 592 }
MiniTLS 0:62a4a8ec4ab5 593
MiniTLS 0:62a4a8ec4ab5 594 HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure
MiniTLS 0:62a4a8ec4ab5 595 {
MiniTLS 0:62a4a8ec4ab5 596 DBG("Trying to read between %d and %d bytes", minLen, maxLen);
MiniTLS 0:62a4a8ec4ab5 597 size_t readLen = 0;
MiniTLS 0:62a4a8ec4ab5 598
MiniTLS 0:62a4a8ec4ab5 599 /* TODO */
MiniTLS 0:62a4a8ec4ab5 600 /*
MiniTLS 0:62a4a8ec4ab5 601 if(!m_sock.is_connected())
MiniTLS 0:62a4a8ec4ab5 602 {
MiniTLS 0:62a4a8ec4ab5 603 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 604 return HTTP_CLOSED; //Connection was closed by server
MiniTLS 0:62a4a8ec4ab5 605 }
MiniTLS 0:62a4a8ec4ab5 606 */
MiniTLS 0:62a4a8ec4ab5 607
MiniTLS 0:62a4a8ec4ab5 608 minitls_err_t ret = m_sock.read((uint8_t*)buf, minLen, maxLen, pReadLen, m_timeout);
MiniTLS 0:62a4a8ec4ab5 609 if(ret)
MiniTLS 0:62a4a8ec4ab5 610 {
MiniTLS 0:62a4a8ec4ab5 611 WARN("TLS Error %d", ret);
MiniTLS 0:62a4a8ec4ab5 612 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 613 }
MiniTLS 0:62a4a8ec4ab5 614
MiniTLS 0:62a4a8ec4ab5 615 DBG("Read %d bytes", *pReadLen);
MiniTLS 0:62a4a8ec4ab5 616
MiniTLS 0:62a4a8ec4ab5 617 if(*pReadLen < minLen)
MiniTLS 0:62a4a8ec4ab5 618 {
MiniTLS 0:62a4a8ec4ab5 619 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 620 return HTTP_CLOSED;
MiniTLS 0:62a4a8ec4ab5 621 }
MiniTLS 0:62a4a8ec4ab5 622
MiniTLS 0:62a4a8ec4ab5 623 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 624 }
MiniTLS 0:62a4a8ec4ab5 625
MiniTLS 0:62a4a8ec4ab5 626 HTTPResult HTTPClient::send(char* buf, size_t len, bool flush) //0 on success, err code on failure
MiniTLS 0:62a4a8ec4ab5 627 {
MiniTLS 0:62a4a8ec4ab5 628 if(len == 0)
MiniTLS 0:62a4a8ec4ab5 629 {
MiniTLS 0:62a4a8ec4ab5 630 len = strlen(buf);
MiniTLS 0:62a4a8ec4ab5 631 }
MiniTLS 0:62a4a8ec4ab5 632
MiniTLS 0:62a4a8ec4ab5 633 size_t writtenLen = 0;
MiniTLS 0:62a4a8ec4ab5 634 minitls_err_t ret;
MiniTLS 0:62a4a8ec4ab5 635 if(len > 0)
MiniTLS 0:62a4a8ec4ab5 636 {
MiniTLS 0:62a4a8ec4ab5 637 ret = m_sock.write((uint8_t*)buf, len, &writtenLen, m_timeout);
MiniTLS 0:62a4a8ec4ab5 638 if(ret)
MiniTLS 0:62a4a8ec4ab5 639 {
MiniTLS 0:62a4a8ec4ab5 640 WARN("TLS Error %d", ret);
MiniTLS 0:62a4a8ec4ab5 641 return HTTP_CONN;
MiniTLS 0:62a4a8ec4ab5 642 }
MiniTLS 0:62a4a8ec4ab5 643
MiniTLS 0:62a4a8ec4ab5 644 DBG("Wrote %d bytes", writtenLen);
MiniTLS 0:62a4a8ec4ab5 645
MiniTLS 0:62a4a8ec4ab5 646 if(writtenLen < len)
MiniTLS 0:62a4a8ec4ab5 647 {
MiniTLS 0:62a4a8ec4ab5 648 WARN("Connection was closed by server");
MiniTLS 0:62a4a8ec4ab5 649 return HTTP_CLOSED;
MiniTLS 0:62a4a8ec4ab5 650 }
MiniTLS 0:62a4a8ec4ab5 651 }
MiniTLS 0:62a4a8ec4ab5 652
MiniTLS 0:62a4a8ec4ab5 653 if(flush)
MiniTLS 0:62a4a8ec4ab5 654 {
MiniTLS 0:62a4a8ec4ab5 655 m_sock.flush(m_timeout);
MiniTLS 0:62a4a8ec4ab5 656 }
MiniTLS 0:62a4a8ec4ab5 657
MiniTLS 0:62a4a8ec4ab5 658 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 659 }
MiniTLS 0:62a4a8ec4ab5 660
MiniTLS 0:62a4a8ec4ab5 661 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 662 {
MiniTLS 0:62a4a8ec4ab5 663 char* schemePtr = (char*) url;
MiniTLS 0:62a4a8ec4ab5 664 char* hostPtr = (char*) strstr(url, "://");
MiniTLS 0:62a4a8ec4ab5 665 if(hostPtr == NULL)
MiniTLS 0:62a4a8ec4ab5 666 {
MiniTLS 0:62a4a8ec4ab5 667 WARN("Could not find host");
MiniTLS 0:62a4a8ec4ab5 668 return HTTP_PARSE; //URL is invalid
MiniTLS 0:62a4a8ec4ab5 669 }
MiniTLS 0:62a4a8ec4ab5 670
MiniTLS 0:62a4a8ec4ab5 671 if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 672 {
MiniTLS 0:62a4a8ec4ab5 673 WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
MiniTLS 0:62a4a8ec4ab5 674 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 675 }
MiniTLS 0:62a4a8ec4ab5 676 memcpy(scheme, schemePtr, hostPtr - schemePtr);
MiniTLS 0:62a4a8ec4ab5 677 scheme[hostPtr - schemePtr] = '\0';
MiniTLS 0:62a4a8ec4ab5 678
MiniTLS 0:62a4a8ec4ab5 679 hostPtr+=3;
MiniTLS 0:62a4a8ec4ab5 680
MiniTLS 0:62a4a8ec4ab5 681 size_t hostLen = 0;
MiniTLS 0:62a4a8ec4ab5 682
MiniTLS 0:62a4a8ec4ab5 683 char* portPtr = strchr(hostPtr, ':');
MiniTLS 0:62a4a8ec4ab5 684 if( portPtr != NULL )
MiniTLS 0:62a4a8ec4ab5 685 {
MiniTLS 0:62a4a8ec4ab5 686 hostLen = portPtr - hostPtr;
MiniTLS 0:62a4a8ec4ab5 687 portPtr++;
MiniTLS 0:62a4a8ec4ab5 688 if( sscanf(portPtr, "%hu", port) != 1)
MiniTLS 0:62a4a8ec4ab5 689 {
MiniTLS 0:62a4a8ec4ab5 690 WARN("Could not find port");
MiniTLS 0:62a4a8ec4ab5 691 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 692 }
MiniTLS 0:62a4a8ec4ab5 693 }
MiniTLS 0:62a4a8ec4ab5 694 else
MiniTLS 0:62a4a8ec4ab5 695 {
MiniTLS 0:62a4a8ec4ab5 696 *port=0;
MiniTLS 0:62a4a8ec4ab5 697 }
MiniTLS 0:62a4a8ec4ab5 698 char* pathPtr = strchr(hostPtr, '/');
MiniTLS 0:62a4a8ec4ab5 699 if( hostLen == 0 )
MiniTLS 0:62a4a8ec4ab5 700 {
MiniTLS 0:62a4a8ec4ab5 701 hostLen = pathPtr - hostPtr;
MiniTLS 0:62a4a8ec4ab5 702 }
MiniTLS 0:62a4a8ec4ab5 703
MiniTLS 0:62a4a8ec4ab5 704 if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 705 {
MiniTLS 0:62a4a8ec4ab5 706 WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
MiniTLS 0:62a4a8ec4ab5 707 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 708 }
MiniTLS 0:62a4a8ec4ab5 709 memcpy(host, hostPtr, hostLen);
MiniTLS 0:62a4a8ec4ab5 710 host[hostLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 711
MiniTLS 0:62a4a8ec4ab5 712 size_t pathLen;
MiniTLS 0:62a4a8ec4ab5 713 char* fragmentPtr = strchr(hostPtr, '#');
MiniTLS 0:62a4a8ec4ab5 714 if(fragmentPtr != NULL)
MiniTLS 0:62a4a8ec4ab5 715 {
MiniTLS 0:62a4a8ec4ab5 716 pathLen = fragmentPtr - pathPtr;
MiniTLS 0:62a4a8ec4ab5 717 }
MiniTLS 0:62a4a8ec4ab5 718 else
MiniTLS 0:62a4a8ec4ab5 719 {
MiniTLS 0:62a4a8ec4ab5 720 pathLen = strlen(pathPtr);
MiniTLS 0:62a4a8ec4ab5 721 }
MiniTLS 0:62a4a8ec4ab5 722
MiniTLS 0:62a4a8ec4ab5 723 if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
MiniTLS 0:62a4a8ec4ab5 724 {
MiniTLS 0:62a4a8ec4ab5 725 WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
MiniTLS 0:62a4a8ec4ab5 726 return HTTP_PARSE;
MiniTLS 0:62a4a8ec4ab5 727 }
MiniTLS 0:62a4a8ec4ab5 728 memcpy(path, pathPtr, pathLen);
MiniTLS 0:62a4a8ec4ab5 729 path[pathLen] = '\0';
MiniTLS 0:62a4a8ec4ab5 730
MiniTLS 0:62a4a8ec4ab5 731 return HTTP_OK;
MiniTLS 0:62a4a8ec4ab5 732 }