A HTTP Client for the mbed networking libraries

Dependents:   HTTPClient_Wifly_HelloWorld HTTPPoster HTTPClient_HelloWorld mpod_nhk_english ... more

Fork of HTTPClientLib by Donatien Garnier

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Fri Jun 29 11:05:21 2012 +0000
Parent:
6:54f79436184f
Child:
8:45c8da29a1cf
Commit message:
Update to using new C++ Socket API

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	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;
 }
--- a/HTTPClient.h	Fri Jun 29 10:24:38 2012 +0000
+++ b/HTTPClient.h	Fri Jun 29 11:05:21 2012 +0000
@@ -28,7 +28,7 @@
 #ifndef HTTP_CLIENT_H
 #define HTTP_CLIENT_H
 
-#include "bsd_socket.h"
+#include "TCPSocket.h"
 
 #define HTTP_CLIENT_DEFAULT_TIMEOUT 4000
 
@@ -124,15 +124,14 @@
   int parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
 
   //Parameters
-  int m_sock;
+  TCPSocket m_sock;
+  
   uint32_t m_timeout;
 
   const char* m_basicAuthUser;
   const char* m_basicAuthPassword;
   int m_httpResponseCode;
 
-  struct sockaddr_in m_serverAddr;
-
 };
 
 //Including data containers here for more convenience