iSDIO Library for TOSHIBA FlashAir. include HTTP or HTTPS Client.
Dependents: FlashAir_Twitter Neon_F303K8_04
Fork of HTTPClient by
Diff: HTTPClient.cpp
- Revision:
- 20:51abf34bcc06
- Parent:
- 19:3b1625dbd7e9
--- a/HTTPClient.cpp Sun Dec 14 19:05:31 2014 +0000 +++ b/HTTPClient.cpp Mon Dec 15 12:23:22 2014 +0000 @@ -18,7 +18,7 @@ */ //Debug is disabled by default -#if 0 +#if 1 //Enable debug #include <cstdio> #define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__); @@ -41,15 +41,18 @@ #define MAX(x,y) (((x)>(y))?(x):(y)) #define CHUNK_SIZE 256 +#define HEADER_KEY_MAXLENGTH 64 +#define HEADER_VALUE_MAXLENGTH 128 #include <cstring> #include "HTTPClient.h" HTTPClient::HTTPClient() : - m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) + m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) { - + bufferPos = buffer; + recvCount = 0; } HTTPClient::~HTTPClient() @@ -100,7 +103,6 @@ #define CHECK_CONN_ERR(ret) \ do{ \ if(ret) { \ - m_sock.close(); \ ERR("Connection error (%d)", ret); \ return HTTP_CONN; \ } \ @@ -108,7 +110,6 @@ #define PRTCL_ERR() \ do{ \ - m_sock.close(); \ ERR("Protocol error"); \ return HTTP_PRTCL; \ } while(0) @@ -125,6 +126,7 @@ char scheme[8]; uint16_t port; + uint16_t cmd; char host[32]; char path[64]; //First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?) @@ -137,20 +139,36 @@ if(port == 0) { //TODO do handle HTTPS->443 port = 80; } + if(strcmp(scheme, "http") == 0) { + cmd = 0x21; //SendHTTPMessageByRegister + } else if(strcmp(scheme, "https") == 0) { + cmd = 0x23; //SendHTTPSSLMessageByRegister + } else { + ERR("Not support scheme %s", scheme); + return HTTP_PARSE; + } DBG("Scheme: %s", scheme); DBG("Host: %s", host); DBG("Port: %d", port); + DBG("Cmd: %x", cmd); DBG("Path: %s", path); - //Connect - DBG("Connecting socket to server"); - int ret = m_sock.connect(host, port); - if (ret < 0) { - m_sock.close(); - ERR("Could not connect"); - return HTTP_CONN; - } + int ret; + + //Get card instance + card = SD_iSDIO::getInstance(); + sequenceId = card->getSequenceId(); + + //Create card command + memset(buffer, 0, 1024); + bufferPos = buffer; + bufferPos = put_command_header(bufferPos, 1, 0); + bufferPos = put_command_info_header(bufferPos, cmd, sequenceId, 2); + bufferPos = put_str_arg(bufferPos, host); + + uint8_t* bodyLenPos = bufferPos; + bufferPos += 4; //skip value of data size //Send request DBG("Sending request"); @@ -159,7 +177,6 @@ snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s\r\n", meth, path, host); //Write request ret = send(buf); if(ret) { - m_sock.close(); ERR("Could not write request"); return HTTP_CONN; } @@ -244,6 +261,38 @@ } } + put_u32(bodyLenPos, (bufferPos - bodyLenPos - 4)); + put_command_header(buffer, 1, (bufferPos - buffer)); + +#if 0 + for (int i = 0; i < 0x400; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + if (i == 0x200-1) printf("----\n"); + } + printf((char *)bodyLenPos + 4); + printf("\n"); +#endif + + DBG("Send data size %d", (bufferPos - buffer)); + + if( card->writeExtDataPort(1, 1, 0x000, buffer) != true ) { + ERR("writeExtDataPort error (1)\n"); + return HTTP_PRTCL; + } + if( (bufferPos - buffer) > 512 ) { + if( card->writeExtDataPort(1, 1, 0x000, &buffer[512]) != true ) { + ERR("writeExtDataPort error (2)\n"); + return HTTP_PRTCL; + } + } + + DBG("waitResponse"); + card->waitResponse(sequenceId); + + bufferPos = buffer; + recvCount = 0; + //Receive response DBG("Receiving response"); ret = recv(buf, 1, CHUNK_SIZE - 1, &trfLen); //Read n bytes @@ -285,7 +334,8 @@ PRTCL_ERR(); } - if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) { + //if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) { + if( (m_httpResponseCode < 100) || (m_httpResponseCode >= 600) ) { //Did not return a 2xx code; TODO fetch headers/(&data?) anyway and implement a mean of writing/reading headers WARN("Response code %d", m_httpResponseCode); PRTCL_ERR(); @@ -327,14 +377,14 @@ buf[crlfPos] = '\0'; - char key[32]; - char value[32]; + char key[HEADER_KEY_MAXLENGTH]; + char value[HEADER_VALUE_MAXLENGTH]; //key[31] = '\0'; //value[31] = '\0'; - memset(key, 0, 32); - memset(value, 0, 32); + memset(key, 0, HEADER_KEY_MAXLENGTH); + memset(value, 0, HEADER_VALUE_MAXLENGTH); //int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value); @@ -343,12 +393,12 @@ char* keyEnd = strchr(buf, ':'); if(keyEnd != NULL) { *keyEnd = '\0'; - if(strlen(buf) < 32) { + if(strlen(buf) < HEADER_KEY_MAXLENGTH) { strcpy(key, buf); n++; char* valueStart = keyEnd + 2; if( (valueStart - buf) < crlfPos ) { - if(strlen(valueStart) < 32) { + if(strlen(valueStart) < HEADER_VALUE_MAXLENGTH) { strcpy(value, valueStart); n++; } @@ -356,7 +406,7 @@ } } if ( n == 2 ) { - DBG("Read header : %s: %s\n", key, value); + DBG("Read header : %s: %s", key, value); if( !strcmp(key, "Content-Length") ) { sscanf(value, "%d", &recvContentLength); recvLengthUnknown = false; @@ -484,7 +534,6 @@ } - m_sock.close(); DBG("Completed HTTP transaction"); return HTTP_OK; @@ -495,41 +544,93 @@ DBG("Trying to read between %d and %d bytes", minLen, maxLen); size_t readLen = 0; - if(!m_sock.is_connected()) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server - } + DBG(" recvCount: %d", recvCount); + + if (recvCount == 0) { - int ret; - while(readLen < maxLen) { - if(readLen < minLen) { - DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen); - m_sock.set_blocking(false, m_timeout); - ret = m_sock.receive_all(buf + readLen, minLen - readLen); - } else { - DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen); - m_sock.set_blocking(false, 0); - ret = m_sock.receive(buf + readLen, maxLen - readLen); + // Read header and data. + if (!card->readExtDataPort(1, 1, 0x200, buffer)) { + return HTTP_PRTCL; + } +#if 0 + for (int i = 0; i < 0x200; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + } +#endif + if (buffer[0] != 0x02) { + return HTTP_CONN; } - if( ret > 0) { - readLen += ret; - } else if( ret == 0 ) { - break; + recvTotalSize = get_u32(buffer + 20); + uint32_t recvSize = recvTotalSize > 488 ? 488 : recvTotalSize; + uint32_t pos = 24; + + if (recvSize < maxLen) { + memcpy(buf, &buffer[pos], recvSize); + readLen = recvSize; } else { - if(!m_sock.is_connected()) { - ERR("Connection error (recv returned %d)", ret); - *pReadLen = readLen; - return HTTP_CONN; + memcpy(buf, &buffer[pos], maxLen); + readLen = maxLen; + } + bufferPos = &buffer[pos] + readLen; + recvAvailableSize = recvTotalSize - readLen; + + DBG(" recvTotalSize: %d", recvTotalSize); + DBG(" recvAvailableSize: %d", recvAvailableSize); + + recvCount++; + + } else { + + uint32_t recvSize = 512 - (bufferPos - buffer); + if (recvAvailableSize < recvSize) recvSize = recvAvailableSize; + + DBG(" recvAvailableSize: %d", recvAvailableSize); + DBG(" recvSize: %d", recvSize); + + if (recvSize > 0) { + + if (recvSize < maxLen) { + memcpy(buf, bufferPos, recvSize); + readLen = recvSize; } else { - break; + memcpy(buf, bufferPos, maxLen); + readLen = maxLen; + } + bufferPos += readLen; + recvAvailableSize -= readLen; + + } else if (recvAvailableSize > 0) { + + // Read next data. + if (!card->readExtDataPort(1, 1, 0x200, buffer)) { + return HTTP_PRTCL; } +#if 0 + for (int i = 0; i < 0x200; i++) { + printf("%2x ", buffer[i]); + if ((i & 0xf) == 0xf) printf("\n"); + } +#endif + recvSize = recvAvailableSize > 512 ? 512 : recvAvailableSize; + + if (recvSize < maxLen) { + memcpy(buf, buffer, recvSize); + readLen = recvSize; + } else { + memcpy(buf, buffer, maxLen); + readLen = maxLen; + } + bufferPos = buffer + readLen; + recvAvailableSize -= readLen; + + recvCount++; + } - if(!m_sock.is_connected()) { - break; - } } + DBG("Read %d bytes", readLen); *pReadLen = readLen; return HTTP_OK; @@ -543,22 +644,13 @@ DBG("Trying to write %d bytes", len); size_t writtenLen = 0; - if(!m_sock.is_connected()) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server + if(((buffer + 1024) - bufferPos) >= len) { + writtenLen = len; + } else { + writtenLen = ((buffer + 1024) - bufferPos); } - - m_sock.set_blocking(false, m_timeout); - int ret = m_sock.send_all(buf, len); - if(ret > 0) { - writtenLen += ret; - } else if( ret == 0 ) { - WARN("Connection was closed by server"); - return HTTP_CLOSED; //Connection was closed by server - } else { - ERR("Connection error (send returned %d)", ret); - return HTTP_CONN; - } + memcpy(bufferPos, buf, writtenLen); + bufferPos += writtenLen; DBG("Written %d bytes", writtenLen); return HTTP_OK;