test

Dependencies:   BME280 SB1602E

Fork of MultiIoTBoardLib by Junichi Katsu

Committer:
jksoft
Date:
Fri Jul 28 02:23:25 2017 +0000
Revision:
0:bad9495b4215
First edition

Who changed what in which revision?

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