A HTTP Client for the mbed networking libraries with HTTPFile for use with latest networking stack
Fork of HTTPClient by
An extension of the HTTPClient that adds HTTPFile. Currently on get is support and only works when getting binary files.
HTTPFile data("/local/firm.bin"); HTTPResult r = client.get("https://217.140.101.20/media/uploads/ollie8/firm.bin", &data); if (r == HTTP_OK) { }
Diff: HTTPClient.cpp
- Revision:
- 5:791fc3dcb6c4
- Parent:
- 4:c071b05ac026
- Child:
- 6:54f79436184f
--- a/HTTPClient.cpp Thu May 24 16:27:32 2012 +0000 +++ b/HTTPClient.cpp Fri Jun 15 14:24:46 2012 +0000 @@ -77,6 +77,21 @@ return m_httpResponseCode; } +#define CHECK_CONN_ERR(ret) \ + do{ \ + if(ret != OK) { \ + ::close(m_sock); \ + ERR("Connection error (%d)", ret); \ + return NET_CONN; \ + } \ + } while(0) + +#define PRTCL_ERR() \ + do{ \ + ::close(m_sock); \ + ERR("Protocol error"); \ + return NET_PROTOCOL; \ + } while(0) int HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, uint32_t timeout) //Execute request { @@ -111,7 +126,7 @@ //Resolve DNS if needed DBG("Resolving DNS address or populate hard-coded IP address"); - struct hostent *server = socket::gethostbyname(host); + struct hostent *server = ::gethostbyname(host); if(server == NULL) { return NET_NOTFOUND; //Fail @@ -123,7 +138,7 @@ //Create socket DBG("Creating socket"); - m_sock = socket::socket(AF_INET, SOCK_STREAM, 0); //UDP socket + m_sock = ::socket(AF_INET, SOCK_STREAM, 0); //UDP socket if (m_sock < 0) { ERR("Could not create socket"); @@ -133,10 +148,10 @@ //Connect it DBG("Connecting socket to %s:%d", inet_ntoa(m_serverAddr.sin_addr), ntohs(m_serverAddr.sin_port)); - ret = socket::connect(m_sock, (const struct sockaddr *)&m_serverAddr, sizeof(m_serverAddr)); + ret = ::connect(m_sock, (const struct sockaddr *)&m_serverAddr, sizeof(m_serverAddr)); if (ret < 0) { - socket::close(m_sock); + ::close(m_sock); ERR("Could not connect"); return NET_CONN; } @@ -149,7 +164,7 @@ ret = send(line); if(ret) { - socket::close(m_sock); + ::close(m_sock); ERR("Could not write request"); return NET_CONN; } @@ -163,27 +178,27 @@ if( pDataOut->getIsChunked() ) { ret = send("Transfer-Encoding: chunked\r\n"); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } else { snprintf(line, sizeof(line), "Content-Length: %d\r\n", pDataOut->getDataLen()); ret = send(line); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } char type[48]; if( pDataOut->getDataType(type, 48) == OK ) { snprintf(line, sizeof(line), "Content-Type: %s\r\n", type); ret = send(line); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } } //Close headers DBG("Headers sent"); ret = send("\r\n"); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); char buf[CHUNK_SIZE]; size_t trfLen; @@ -201,7 +216,7 @@ //Write chunk header snprintf(line, sizeof(line), "%X\r\n", trfLen); //In hex encoding ret = send(line); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } else if( trfLen == 0 ) { @@ -210,13 +225,13 @@ if( trfLen != 0 ) { ret = send(buf, trfLen); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } if( pDataOut->getIsChunked() ) { ret = send("\r\n"); //Chunk-terminating CRLF - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } else { @@ -238,14 +253,14 @@ //Receive response DBG("Receiving response"); ret = recv(buf, CHUNK_SIZE - 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); buf[trfLen] = '\0'; char* crlfPtr = strstr(buf, "\r\n"); if(crlfPtr == NULL) { - goto prtclerr; + PRTCL_ERR(); } int crlfPos = crlfPtr - buf; @@ -256,14 +271,14 @@ { //Cannot match string, error ERR("Not a correct HTTP answer : %s\n", buf); - goto prtclerr; + PRTCL_ERR(); } if(m_httpResponseCode != 200) { //Cannot match string, error WARN("Response code %d", m_httpResponseCode); - goto prtclerr; + PRTCL_ERR(); } DBG("Reading headers"); @@ -286,12 +301,12 @@ trfLen += newTrfLen; buf[trfLen] = '\0'; DBG("Read %d chars; In buf: [%s]", newTrfLen, buf); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); continue; } else { - goto prtclerr; + PRTCL_ERR(); } } @@ -342,7 +357,7 @@ else { ERR("Could not parse header"); - goto prtclerr; + PRTCL_ERR(); } } @@ -371,12 +386,12 @@ size_t newTrfLen; ret = recv(buf + trfLen, 0, CHUNK_SIZE - trfLen - 1, &newTrfLen); trfLen += newTrfLen; - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); continue; } else { - goto prtclerr; + PRTCL_ERR(); } } buf[crlfPos] = '\0'; @@ -384,7 +399,7 @@ if(n!=1) { ERR("Could not read chunk length"); - goto prtclerr; + PRTCL_ERR(); } memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2)); //Not need to move NULL-terminating char any more @@ -420,7 +435,7 @@ if(readLen) { ret = recv(buf, 1, CHUNK_SIZE - trfLen - 1, &trfLen); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); } } while(readLen); @@ -431,13 +446,13 @@ size_t newTrfLen; //Read missing chars to find end of chunk ret = recv(buf, 2 - trfLen, CHUNK_SIZE, &newTrfLen); - if(ret != OK) goto connerr; + CHECK_CONN_ERR(ret); trfLen += newTrfLen; } if( (buf[0] != '\r') || (buf[1] != '\n') ) { ERR("Format error"); - goto prtclerr; + PRTCL_ERR(); } memmove(buf, &buf[2], trfLen - 2); trfLen -= 2; @@ -449,21 +464,10 @@ } - socket::close(m_sock); + ::close(m_sock); DBG("Completed HTTP transaction"); return OK; - - connerr: - socket::close(m_sock); - ERR("Connection error (%d)", ret); - return NET_CONN; - - prtclerr: - socket::close(m_sock); - ERR("Protocol error"); - return NET_PROTOCOL; - } int HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure @@ -480,14 +484,14 @@ struct timeval t_val; t_val.tv_sec = m_timeout / 1000; t_val.tv_usec = (m_timeout - (t_val.tv_sec * 1000)) * 1000; - int ret = socket::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val); + int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val); if(ret <= 0 || !FD_ISSET(m_sock, &socksSet)) { WARN("Timeout"); return NET_TIMEOUT; //Timeout } - ret = socket::recv(m_sock, buf + readLen, maxLen - readLen, 0); + ret = ::recv(m_sock, buf + readLen, maxLen - readLen, 0); if( ret > 0) { readLen += ret; @@ -527,14 +531,14 @@ struct timeval t_val; t_val.tv_sec = m_timeout / 1000; t_val.tv_usec = (m_timeout - (t_val.tv_sec * 1000)) * 1000; - int ret = socket::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val); + int ret = ::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val); if(ret <= 0 || !FD_ISSET(m_sock, &socksSet)) { WARN("Timeout"); return NET_TIMEOUT; //Timeout } - ret = socket::send(m_sock, buf + writtenLen, len - writtenLen, 0); + ret = ::send(m_sock, buf + writtenLen, len - writtenLen, 0); if( ret > 0) { writtenLen += ret;