Fork of wolfSSL's HTTPClient fork. Fork!
Dependents: exosite_http_example exosite_http_example
Fork of HTTPClient by
Diff: HTTPClient.cpp
- Revision:
- 31:612864287dd9
- Parent:
- 30:a9ecee69c6b5
diff -r a9ecee69c6b5 -r 612864287dd9 HTTPClient.cpp --- a/HTTPClient.cpp Fri Dec 05 07:03:47 2014 +0000 +++ b/HTTPClient.cpp Tue Jan 20 14:13:07 2015 +0000 @@ -75,7 +75,7 @@ static int SocketSend(CYASSL* ssl, char *buf, int sz, void *ctx) { int n ; - + wait(0.1) ; n = m_sock.send(buf, sz); if(n > 0) { @@ -85,8 +85,7 @@ return n ; } -static void base64enc(char *out, const char *in) -{ +static void base64enc(char *out, const char *in) { const char code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ; int i = 0, x = 0, l = 0; @@ -111,14 +110,10 @@ { /* CyaSSL_Debugging_ON() ; */ - + ctx = 0 ; ssl = 0 ; - SSLver = 3 ; - m_basicAuthUser = NULL ; - redirect_url = NULL ; - redirect = 0 ; - header = NULL ; + SSLver = 3 ; } HTTPClient::~HTTPClient() @@ -128,7 +123,7 @@ HTTPResult HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification { -#define AUTHB_SIZE 128 + #define AUTHB_SIZE 128 if((strlen(user) + strlen(password)) >= AUTHB_SIZE) return HTTP_ERROR ; m_basicAuthUser = user; @@ -168,20 +163,15 @@ return m_httpResponseCode; } -void HTTPClient::setHeader(const char * h) +void HTTPClient::setHeader(int idx, char * h) { - header = h ; + if (idx < MAX_HEADER_COUNT) + header[idx] = h; } -void HTTPClient::setLocationBuf(char * url, int size) +HTTPResult HTTPClient::setSSLversion(int minorV) { - redirect_url = url ; - redirect_url_size = size ; -} - -HTTPResult HTTPClient::setSSLversion(int minorV) -{ - if((minorV>=0) && (minorV<=3)) + if((minorV>=0) && (minorV<=3)) SSLver = minorV ; else return HTTP_ERROR ; return HTTP_OK ; @@ -217,14 +207,13 @@ ctx = NULL ; } CyaSSL_Cleanup() ; -} +} HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request { CYASSL_METHOD * SSLmethod ; m_httpResponseCode = 0; //Invalidate code m_timeout = timeout; - redirect = 0 ; pDataIn->writeReset(); if( pDataOut ) { @@ -275,21 +264,13 @@ if(port == HTTPS_PORT) { /* Start SSL connect */ - DBG("SSLver=%d", SSLver) ; + DBG("SSLmethod=%d", SSLmethod) ; if(ctx == NULL) { switch(SSLver) { - case 0 : - SSLmethod = CyaSSLv3_client_method() ; - break ; - case 1 : - SSLmethod = CyaTLSv1_client_method() ; - break ; - case 2 : - SSLmethod = CyaTLSv1_1_client_method() ; - break ; - case 3 : - SSLmethod = CyaTLSv1_2_client_method() ; - break ; + case 0 : SSLmethod = CyaSSLv3_client_method() ; break ; + case 1 : SSLmethod = CyaTLSv1_client_method() ; break ; + case 2 : SSLmethod = CyaTLSv1_1_client_method() ; break ; + case 3 : SSLmethod = CyaTLSv1_2_client_method() ; break ; } ctx = CyaSSL_CTX_new((CYASSL_METHOD *)SSLmethod); if (ctx == NULL) { @@ -332,15 +313,10 @@ return HTTP_CONN; } - wait(0.1) ; - //Send all headers //Send default headers DBG("Sending headers"); - if(m_basicAuthUser) { - bAuth() ; /* send out Basic Auth header */ - } if( pDataOut != NULL ) { if( pDataOut->getIsChunked() ) { ret = send("Transfer-Encoding: chunked\r\n"); @@ -357,11 +333,14 @@ ret = send(buf); CHECK_CONN_ERR(ret); } + if(m_basicAuthUser) { + bAuth() ; /* send out Basic Auth header */ + } } //Add user headers - if(header) { - ret = send((char *)header); + for(int i = 0; i < MAX_HEADER_COUNT && header[i] != 0; i++) { + ret = send(header[i]); CHECK_CONN_ERR(ret); } @@ -443,7 +422,7 @@ PRTCL_ERR(); } - if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 400) ) { + if( (m_httpResponseCode < 200) || (m_httpResponseCode >= 300) ) { //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(); @@ -468,29 +447,13 @@ DBG("Read %d chars; In buf: [%s]", newTrfLen, buf); CHECK_CONN_ERR(ret); continue; - } else { // Too large header. Skip to the next. - WARN("Header too large [%20s]. Skip to the next.\n", buf) ; - while(true) { - ret = recv(buf, 1, CHUNK_SIZE-1, &trfLen); - buf[trfLen] = '\0' ; - crlfPtr = strstr(buf, "\r\n"); - if(crlfPtr != NULL) { - crlfPos = crlfPtr - buf; - memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well - trfLen -= (crlfPos + 2); - DBG("Got next header(%d)[%s]", trfLen, buf) ; - break ; - } else { - DBG("Skipped[%s]\n", buf) ; - continue ; - } - } - continue ; // to fill out rest of buff + } else { + PRTCL_ERR(); } } crlfPos = crlfPtr - buf; - DBG("crlfPos=%d", crlfPos) ; + if(crlfPos == 0) { //End of headers DBG("Headers read"); memmove(buf, &buf[2], trfLen - 2 + 1); //Be sure to move NULL-terminating char as well @@ -507,30 +470,23 @@ value[31] = '\0'; int n = sscanf(buf, "%31[^:]: %31[^\r\n]", key, value); - DBG("Read header(%d) : %s: %s\n", n, key, value); if ( n == 2 ) { - //DBG("Read header : %s: %s\n", key, value); - char *k, *v ; - for(k=key ; *k != '\0'; k++)*k = toupper(*k) ; - for(v=value ; *v != '\0'; v++)*v = toupper(*v) ; - if( !strcmp(key, "CONTENT-LENGTH") ) { + DBG("Read header : %s: %s\n", key, value); + if( !strcmp(key, "Content-Length") ) { sscanf(value, "%d", &recvContentLength); pDataIn->setDataLen(recvContentLength); - } else if( !strcmp(key, "TRANSFER-ENCODING") ) { - if( !strcmp(value, "CHUNKED") ) { + } else if( !strcmp(key, "Transfer-Encoding") ) { + if( !strcmp(value, "Chunked") || !strcmp(value, "chunked") ) { recvChunked = true; pDataIn->setIsChunked(true); } - } else if( !strcmp(key, "CONTENT-TYPE") ) { + } else if( !strcmp(key, "Content-Type") ) { pDataIn->setDataType(value); - } else if( !strcmp(key, "LOCATION") && redirect_url) { - sscanf(buf, "%31[^:]: %128[^\r\n]", key, redirect_url); - DBG("Redirect %s: %s", key, redirect_url) ; - redirect = 1 ; } + memmove(buf, &buf[crlfPos+2], trfLen - (crlfPos + 2) + 1); //Be sure to move NULL-terminating char as well trfLen -= (crlfPos + 2); - DBG("next header(trfLen:%d)[%s]", trfLen, buf) ; + } else { ERR("Could not parse header"); PRTCL_ERR(); @@ -629,15 +585,15 @@ cyassl_free() ; m_sock.close(); DBG("Completed HTTP transaction"); - if(redirect)return HTTP_REDIRECT ; - else return HTTP_OK; + + return HTTP_OK; } HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure { DBG("Trying to read between %d and %d bytes", minLen, maxLen); size_t readLen = 0; - maxLen = maxLen == 0 ? 1 : maxLen ; + if(!m_sock.is_connected()) { WARN("Connection was closed by server"); return HTTP_CLOSED; //Connection was closed by server @@ -718,7 +674,7 @@ len -= cp_len ; if(send_buf_p == send_buf + SEND_BUF_SIZE) { - if(port == HTTPS_PORT) { + if(port == HTTPS_PORT){ ERR("HTTPClient::send buffer overflow"); return HTTP_ERROR ; } @@ -837,16 +793,15 @@ HTTPResult ret ; char b_auth[(int)((AUTHB_SIZE+3)*4/3+1)] ; char base64buff[AUTHB_SIZE+3] ; - + ret = send("Authorization: Basic ") ; CHECK_CONN_ERR(ret); sprintf(base64buff, "%s:%s", m_basicAuthUser, m_basicAuthPassword) ; - DBG("bAuth: %s", base64buff) ; base64enc(b_auth, base64buff) ; b_auth[strlen(b_auth)+1] = '\0' ; b_auth[strlen(b_auth)] = '\n' ; DBG("b_auth:%s", b_auth) ; ret = send(b_auth) ; - CHECK_CONN_ERR(ret); + CHECK_CONN_ERR(ret); return HTTP_OK ; }