Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SalesforceInterface df-2014-heroku-thermostat-k64f SalesforceInterface
Fork of HTTPClient by
Revision 22:4b9a4151cc73, committed 2014-07-12
- Comitter:
- wolfSSL
- Date:
- Sat Jul 12 07:08:10 2014 +0000
- Parent:
- 21:14ecc2b2e282
- Child:
- 24:1bef4962dd61
- Commit message:
- Add basic authentication;
Changed in this revision
| HTTPClient.cpp | Show annotated file Show diff for this revision Revisions of this file |
| HTTPClient.h | Show annotated file Show diff for this revision Revisions of this file |
--- 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 ;
+}
--- a/HTTPClient.h Thu Apr 17 12:23:47 2014 +0000
+++ b/HTTPClient.h Sat Jul 12 07:08:10 2014 +0000
@@ -58,15 +58,13 @@
HTTPClient();
~HTTPClient();
-#if 0 //TODO add header handlers
/**
Provides a basic authentification feature (Base64 encoded username and password)
Pass two NULL pointers to switch back to no authentication
@param user username to use for authentication, must remain valid durlng the whole HTTP session
@param user password to use for authentication, must remain valid durlng the whole HTTP session
*/
- void basicAuth(const char* user, const char* password); //Basic Authentification
-#endif
+ HTTPResult basicAuth(const char* user, const char* password); //Basic Authentification
//High Level setup functions
/** Execute a GET request on the URL
@@ -122,7 +120,9 @@
@return The HTTP response code of the last request
*/
int getHTTPResponseCode();
- void setHeader(char *header) ;
+
+ void setHeader(char *header) ; /* set http headers */
+ HTTPResult setSSLversion(int minorV) ; /* set SSL/TLS version. 0: SSL3, 1: TLS1.0, 2: TLS1.1, 3: TLS1.2 */
private:
enum HTTP_METH {
@@ -139,7 +139,8 @@
HTTPResult flush(void); //0 on success, err code on failure
HTTPResult parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
void cyassl_free(void) ;
-
+ HTTPResult bAuth(void) ;
+
//Parameters
int m_timeout;
@@ -149,7 +150,9 @@
int m_httpResponseCode;
char * header ;
+
/* for CyaSSL */
+ int SSLver ;
uint16_t port;
struct CYASSL_CTX* ctx ;
struct CYASSL * ssl ;
