HTTPClient for CyaSSL
Dependents: kintone-POST kintone-POST
Fork of HTTPClient by
Diff: HTTPClient.cpp
- Revision:
- 22:4b9a4151cc73
- Parent:
- 21:14ecc2b2e282
- Child:
- 26:bf979804b653
diff -r 14ecc2b2e282 -r 4b9a4151cc73 HTTPClient.cpp --- a/HTTPClient.cpp Thu Apr 17 12:23:47 2014 +0000 +++ b/HTTPClient.cpp Sat Jul 12 07:08:10 2014 +0000 @@ -62,9 +62,11 @@ int n ; int i ; #define RECV_RETRY 3 + for(i=0; i<RECV_RETRY; i++) { n = m_sock.receive(buf, sz) ; if(n >= 0)return n ; + wait(0.2) ; } ERR("SocketReceive:%d/%d\n", n, sz) ; return n ; @@ -73,20 +75,45 @@ 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) { + wait(0.3) ; return n ; } else ERR("SocketSend:%d/%d\n", n, sz); return n ; } +static void base64enc(char *out, const char *in) { + const char code[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" ; + int i = 0, x = 0, l = 0; + + for (; *in; in++) { + x = x << 8 | *in; + for (l += 8; l >= 6; l -= 6) { + out[i++] = code[(x >> (l - 6)) & 0x3f]; + } + } + if (l > 0) { + x <<= 6 - l; + out[i++] = code[x & 0x3f]; + } + for (; i % 4;) { + out[i++] = '='; + } + out[i] = '\0' ; +} + HTTPClient::HTTPClient() : m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0) { - //CyaSSL_Debugging_ON() ; + + /* CyaSSL_Debugging_ON() ; */ + ctx = 0 ; ssl = 0 ; + SSLver = 3 ; } HTTPClient::~HTTPClient() @@ -94,13 +121,15 @@ } -#if 0 -void HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification +HTTPResult HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification { + #define AUTHB_SIZE 128 + if((strlen(user) + strlen(password)) >= AUTHB_SIZE) + return HTTP_ERROR ; m_basicAuthUser = user; m_basicAuthPassword = password; + return HTTP_OK ; } -#endif HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking { @@ -139,6 +168,14 @@ header = h ; } +HTTPResult HTTPClient::setSSLversion(int minorV) +{ + if((minorV>=0) && (minorV<=3)) + SSLver = minorV ; + else return HTTP_ERROR ; + return HTTP_OK ; +} + #define CHECK_CONN_ERR(ret) \ do{ \ @@ -168,11 +205,12 @@ CyaSSL_CTX_free(ctx) ; 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; @@ -183,7 +221,7 @@ char scheme[8]; char host[32]; - char path[64]; + char path[80]; int ret ; @@ -194,7 +232,7 @@ return res; } - if(port == 0) { //TODO do handle HTTPS->443 + if(port == 0) { if(strcmp(scheme, "http") == 0) port = HTTP_PORT ; else if(strcmp(scheme, "https") == 0) @@ -223,12 +261,17 @@ } if(port == HTTPS_PORT) { + /* Start SSL connect */ + DBG("SSLmethod=%d", SSLmethod) ; if(ctx == NULL) { - ctx = CyaSSL_CTX_new( - CyaTLSv1_2_client_method - //CyaSSLv3_client_method - ()); + 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 ; + } + ctx = CyaSSL_CTX_new((CYASSL_METHOD *)SSLmethod); if (ctx == NULL) { ERR("unable to get ctx"); return HTTP_CONN; @@ -279,6 +322,7 @@ CHECK_CONN_ERR(ret); } else { snprintf(buf, sizeof(buf), "Content-Length: %d\r\n", pDataOut->getDataLen()); + DBG("Content buf:%s", buf) ; ret = send(buf); CHECK_CONN_ERR(ret); } @@ -288,6 +332,9 @@ ret = send(buf); CHECK_CONN_ERR(ret); } + if(m_basicAuthUser) { + bAuth() ; /* send out Basic Auth header */ + } } //Add user headers @@ -313,15 +360,19 @@ DBG("buf:%s", buf) ; if( pDataOut->getIsChunked() ) { //Write chunk header - char chunkHeader[16]; + char chunkHeader[64]; snprintf(chunkHeader, sizeof(chunkHeader), "%X\r\n", trfLen); //In hex encoding ret = send(chunkHeader); CHECK_CONN_ERR(ret); } else if( trfLen == 0 ) { + DBG("trfLen==0") ; break; } + DBG("trfLen 1=%d", trfLen) ; if( trfLen != 0 ) { + DBG("Sending 1") ; ret = send(buf, trfLen); + DBG("Sent 1") ; CHECK_CONN_ERR(ret); } @@ -331,11 +382,14 @@ } else { writtenLen += trfLen; if( writtenLen >= pDataOut->getDataLen() ) { + DBG("writtenLen=%d", writtenLen) ; break; } + DBG("writtenLen+=trfLen = %d", writtenLen) ; } - + DBG("trfLen 2=%d", trfLen) ; if( trfLen == 0 ) { + DBG("trfLen == 0") ; break; } } @@ -607,16 +661,22 @@ } do { + if((SEND_BUF_SIZE - (send_buf_p - send_buf)) >= len) { cp_len = len ; } else { - cp_len = send_buf_p - send_buf ; + cp_len = SEND_BUF_SIZE - (send_buf_p - send_buf) ; } + DBG("send_buf_p:%x. send_buf+SIZE:%x, len=%d, cp_len=%d", send_buf_p, send_buf+SEND_BUF_SIZE, len, cp_len) ; memcpy(send_buf_p, buf, cp_len) ; send_buf_p += cp_len ; len -= cp_len ; if(send_buf_p == send_buf + SEND_BUF_SIZE) { + if(port == HTTPS_PORT){ + ERR("HTTPClient::send buffer overflow"); + return HTTP_ERROR ; + } ret = flush() ; if(ret)return(ret) ; } @@ -726,3 +786,21 @@ return HTTP_OK; } + +HTTPResult HTTPClient::bAuth(void) +{ + 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) ; + 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); + return HTTP_OK ; +}