A HTTP Client for the mbed networking libraries with HTTPFile for use with latest networking stack

Fork of HTTPClient by Donatien Garnier

An extension of the HTTPClient that adds HTTPFile. Currently on get is support and only works when getting binary files.

HTTPFile data("/local/firm.bin");
HTTPResult r = client.get("https://217.140.101.20/media/uploads/ollie8/firm.bin", &data);
if (r == HTTP_OK) {
                            
}
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;
 }