Fork of wolfSSL's HTTPClient fork. Fork!

Dependencies:   CyaSSL

Dependents:   exosite_http_example exosite_http_example

Fork of HTTPClient by wolf SSL

Revision:
31:612864287dd9
Parent:
30:a9ecee69c6b5
--- 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 ;
 }