A HTTP/HTTPS Client for the mbed networking/CyaSSL ssl library

Dependents:   Anpi dropbox_access php_access_auth TwitterReader ... more

Fork of HTTPClient by Donatien Garnier

HTTP and HTTPS Client Class with wolfSSL, embedded SSL library.

/media/uploads/wolfSSL/wolfssl_logo.png

The class was forked from http://mbed.org/users/donatien/code/HTTPClient/

It, now, accepts url both with "http://" and "https://".

Allocate caller thread with 16kbytes or larger stack for "https" requests.

Rest of the API stays compatible with HTTPClient.

For more about the library, see http://www.wolfssl.com. http://wolfssl.com/yaSSL/Docs.html.

Extended methods:

  • HTTPResult basicAuth(const char* user, const char* password); /* set id/passwd for basic Authentication */
  • 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 */
Revision:
7:4e39864f7b15
Parent:
6:54f79436184f
Child:
8:45c8da29a1cf
--- a/HTTPClient.cpp	Fri Jun 29 10:24:38 2012 +0000
+++ b/HTTPClient.cpp	Fri Jun 29 11:05:21 2012 +0000
@@ -21,10 +21,15 @@
 SOFTWARE.
 */
 
+//Debug is disabled by default
+#if 0
 #define __DEBUG__ 4 //Maximum verbosity
 #ifndef __MODULE__
 #define __MODULE__ "HTTPClient.cpp"
 #endif
+#else
+#define __DEBUG__ 0 //Disabled
+#endif
 
 #include "core/fwk.h"
 
@@ -38,7 +43,7 @@
 #include <cstring>
 
 HTTPClient::HTTPClient() :
-m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
+m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
 {
 
 }
@@ -79,8 +84,8 @@
 
 #define CHECK_CONN_ERR(ret) \
   do{ \
-    if(ret != OK) { \
-      ::close(m_sock); \
+    if(ret) { \
+      m_sock.close(); \
       ERR("Connection error (%d)", ret); \
       return NET_CONN; \
     } \
@@ -88,7 +93,7 @@
 
 #define PRTCL_ERR() \
   do{ \
-    ::close(m_sock); \
+    m_sock.close(); \
     ERR("Protocol error"); \
     return NET_PROTOCOL; \
   } while(0)
@@ -104,7 +109,7 @@
   char path[64];
   //First we need to parse the url (http[s]://host[:port][/[path]]) -- HTTPS not supported (yet?)
   int ret = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
-  if(ret != OK)
+  if(ret)
   {
     ERR("parseURL returned %d", ret);
     return ret;
@@ -120,38 +125,12 @@
   DBG("Port: %d", port);
   DBG("Path: %s", path);
 
-  //Now populate structure
-  std::memset(&m_serverAddr, 0, sizeof(struct sockaddr_in));
-
-  //Resolve DNS if needed
-
-  DBG("Resolving DNS address or populate hard-coded IP address");
-  struct hostent *server = ::gethostbyname(host);
-  if(server == NULL)
-  {
-    return NET_NOTFOUND; //Fail
-  }
-  memcpy((char*)&m_serverAddr.sin_addr.s_addr, (char*)server->h_addr_list[0], server->h_length);
-
-  m_serverAddr.sin_family = AF_INET;
-  m_serverAddr.sin_port = htons(port);
-
-  //Create socket
-  DBG("Creating socket");
-  m_sock = ::socket(AF_INET, SOCK_STREAM, 0); //TCP socket
-  if (m_sock < 0)
-  {
-    ERR("Could not create socket");
-    return NET_OOM;
-  }
-  DBG("Handle is %d", m_sock);
-
-  //Connect it
-  DBG("Connecting socket to %s:%d", inet_ntoa(m_serverAddr.sin_addr), ntohs(m_serverAddr.sin_port));
-  ret = ::connect(m_sock, (const struct sockaddr *)&m_serverAddr, sizeof(m_serverAddr));
+  //Connect
+  DBG("Connecting socket to server");
+  ret = m_sock.connect(host, port);
   if (ret < 0)
   {
-    ::close(m_sock);
+    m_sock.close();
     ERR("Could not connect");
     return NET_CONN;
   }
@@ -164,7 +143,7 @@
   ret = send(line);
   if(ret)
   {
-    ::close(m_sock);
+    m_sock.close();
     ERR("Could not write request");
     return NET_CONN;
   }
@@ -464,7 +443,7 @@
 
   }
 
-  ::close(m_sock);
+  m_sock.close();
   DBG("Completed HTTP transaction");
 
   return OK;
@@ -474,24 +453,19 @@
 {
   DBG("Trying to read between %d and %d bytes", minLen, maxLen);
   size_t readLen = 0;
-  while(readLen < minLen)
+  
+  int ret;
+  while(readLen < maxLen)
   {
-    //Wait for socket to be readable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-    struct timeval t_val;
-    t_val.tv_sec = m_timeout / 1000;
-    t_val.tv_usec = (m_timeout - (t_val.tv_sec * 1000)) * 1000;
-    int ret = ::select(FD_SETSIZE, &socksSet, NULL, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
+    if(readLen < minLen)
     {
-      WARN("Timeout");
-      return NET_TIMEOUT; //Timeout
+      ret = m_sock.receive(buf + readLen, minLen - readLen, m_timeout);
     }
-
-    ret = ::recv(m_sock, buf + readLen, maxLen - readLen, 0);
+    else
+    {
+      ret = m_sock.receive(buf + readLen, maxLen - readLen, 0);
+    }
+    
     if( ret > 0)
     {
       readLen += ret;
@@ -499,6 +473,39 @@
     }
     else if( ret == 0 )
     {
+      break;
+    }
+    else
+    {
+      ERR("Connection error (recv returned %d)", ret);
+      *pReadLen = readLen;
+      return NET_CONN;
+    }
+  }
+  DBG("Read %d bytes", readLen);
+  *pReadLen = readLen;
+  return OK;
+}
+
+int HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure
+{
+  if(len == 0)
+  {
+    len = strlen(buf);
+  }
+  DBG("Trying to write %d bytes", len);
+  size_t writtenLen = 0;
+  
+  int ret;
+  do
+  {
+    ret = m_sock.send(buf + writtenLen, len - writtenLen, m_timeout);
+    if(ret > 0)
+    {
+      writtenLen += ret;
+    }
+    else if( ret == 0 )
+    {
       WARN("Connection was closed by server");
       return NET_CLOSED; //Connection was closed by server
     }
@@ -507,54 +514,8 @@
       ERR("Connection error (recv returned %d)", ret);
       return NET_CONN;
     }
-  }
-  *pReadLen = readLen;
-  DBG("Read %d bytes", readLen);
-  return OK;
-}
-
-int HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure
-{
-  if(len == 0)
-  {
-    len = strlen(buf);
-  }
-  DBG("Trying to write %d bytes", len);
-  size_t writtenLen = 0;
-  while(writtenLen < len)
-  {
-    //Wait for socket to be writeable
-    //Creating FS set
-    fd_set socksSet;
-    FD_ZERO(&socksSet);
-    FD_SET(m_sock, &socksSet);
-    struct timeval t_val;
-    t_val.tv_sec = m_timeout / 1000;
-    t_val.tv_usec = (m_timeout - (t_val.tv_sec * 1000)) * 1000;
-    int ret = ::select(FD_SETSIZE, NULL, &socksSet, NULL, &t_val);
-    if(ret <= 0 || !FD_ISSET(m_sock, &socksSet))
-    {
-      WARN("Timeout");
-      return NET_TIMEOUT; //Timeout
-    }
-
-    ret = ::send(m_sock, buf + writtenLen, len - writtenLen, 0);
-    if( ret > 0)
-    {
-      writtenLen += ret;
-      continue;
-    }
-    else if( ret == 0 )
-    {
-      WARN("Connection was closed by server");
-      return NET_CLOSED; //Connection was closed by server
-    }
-    else
-    {
-      ERR("Connection error (recv returned %d)", ret);
-      return NET_CONN;
-    }
-  }
+  } while(writtenLen < len);
+  
   DBG("Written %d bytes", writtenLen);
   return OK;
 }