Fixed custom headers and Basic authorization, added support for redirection, functional file download interface can be used for SW updates and more.

Dependents:   Sample_HTTPClient Sample_HTTPClient LWM2M_NanoService_Ethernet LWM2M_NanoService_Ethernet ... more

Fork of HTTPClient by Vincent Wochnik

More recent changes - added iCal processing.

Derivative of a derivative, however this one works when it comes to supplying Basic authorization to access a protected resource. Some additional changes to the debug interface to clean it up for consistency with many other components I have.

Files at this revision

API Documentation at this revision

Comitter:
donatien
Date:
Sun Aug 05 15:30:07 2012 +0000
Parent:
11:390362de8c3f
Child:
13:be61104f4e91
Commit message:
Updated to match the newest 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	Mon Jul 30 15:16:51 2012 +0000
+++ b/HTTPClient.cpp	Sun Aug 05 15:30:07 2012 +0000
@@ -19,17 +19,20 @@
 
 //Debug is disabled by default
 #if 0
-#define DBG(x, ...) 
-#define WARN(x, ...)
-#define ERR(x, ...) 
-#else
+//Enable debug
 #include <cstdio>
 #define DBG(x, ...) std::printf("[HTTPClient : DBG]"x"\r\n", ##__VA_ARGS__); 
 #define WARN(x, ...) std::printf("[HTTPClient : WARN]"x"\r\n", ##__VA_ARGS__); 
 #define ERR(x, ...) std::printf("[HTTPClient : ERR]"x"\r\n", ##__VA_ARGS__); 
+
+#else
+//Disable debug
+#define DBG(x, ...) 
+#define WARN(x, ...)
+#define ERR(x, ...) 
+
 #endif
 
-#define HTTP_REQUEST_TIMEOUT 30000
 #define HTTP_PORT 80
 
 #define OK 0
@@ -62,18 +65,18 @@
 }
 #endif
 
-HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
+HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   return connect(url, HTTP_GET, NULL, pDataIn, timeout);
 }
 
-HTTPResult HTTPClient::get(const char* url, char* result, size_t maxResultLen, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
+HTTPResult HTTPClient::get(const char* url, char* result, size_t maxResultLen, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   HTTPText str(result, maxResultLen);
   return get(url, &str, timeout);
 }
 
-HTTPResult HTTPClient::post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
+HTTPResult HTTPClient::post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   return connect(url, HTTP_POST, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
 }
@@ -99,8 +102,8 @@
     return HTTP_PRTCL; \
   } while(0)
 
-HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, uint32_t timeout) //Execute request
-{
+HTTPResult HTTPClient::connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout) //Execute request
+{ 
   m_httpResponseCode = 0; //Invalidate code
   m_timeout = timeout;
 
@@ -454,23 +457,32 @@
 {
   DBG("Trying to read between %d and %d bytes", minLen, maxLen);
   size_t readLen = 0;
-  
+      
+  if(!m_sock.is_connected())
+  {
+    WARN("Connection was closed by server");
+    return HTTP_CLOSED; //Connection was closed by server 
+  }
+    
   int ret;
   while(readLen < maxLen)
   {
     if(readLen < minLen)
     {
-      ret = m_sock.receive_all(buf + readLen, minLen - readLen, m_timeout);
+      DBG("Trying to read at most %d bytes [Blocking]", minLen - readLen);
+      m_sock.set_blocking(true, m_timeout);
+      ret = m_sock.receive_all(buf + readLen, minLen - readLen);
     }
     else
     {
-      ret = m_sock.receive(buf + readLen, maxLen - readLen, 0);
+      DBG("Trying to read at most %d bytes [Not blocking]", maxLen - readLen);
+      m_sock.set_blocking(false);
+      ret = m_sock.receive(buf + readLen, maxLen - readLen);
     }
     
     if( ret > 0)
     {
       readLen += ret;
-      continue;
     }
     else if( ret == 0 )
     {
@@ -478,9 +490,21 @@
     }
     else
     {
-      ERR("Connection error (recv returned %d)", ret);
-      *pReadLen = readLen;
-      return HTTP_CONN;
+      if(!m_sock.is_connected())
+      {
+        ERR("Connection error (recv returned %d)", ret);
+        *pReadLen = readLen;
+        return HTTP_CONN;
+      }
+      else
+      {
+        break;      
+      }
+    }
+    
+    if(!m_sock.is_connected())
+    {
+      break;
     }
   }
   DBG("Read %d bytes", readLen);
@@ -496,26 +520,29 @@
   }
   DBG("Trying to write %d bytes", len);
   size_t writtenLen = 0;
+    
+  if(!m_sock.is_connected())
+  {
+    WARN("Connection was closed by server");
+    return HTTP_CLOSED; //Connection was closed by server 
+  }
   
-  int ret;
-  do
+  m_sock.set_blocking(true, m_timeout);
+  int ret = m_sock.send_all(buf, len);
+  if(ret > 0)
   {
-    ret = m_sock.send_all(buf + writtenLen, len - writtenLen, m_timeout);
-    if(ret > 0)
-    {
-      writtenLen += ret;
-    }
-    else if( ret == 0 )
-    {
-      WARN("Connection was closed by server");
-      return HTTP_CLOSED; //Connection was closed by server
-    }
-    else
-    {
-      ERR("Connection error (recv returned %d)", ret);
-      return HTTP_CONN;
-    }
-  } while(writtenLen < len);
+    writtenLen += ret;
+  }
+  else if( ret == 0 )
+  {
+    WARN("Connection was closed by server");
+    return HTTP_CLOSED; //Connection was closed by server
+  }
+  else
+  {
+    ERR("Connection error (send returned %d)", ret);
+    return HTTP_CONN;
+  }
   
   DBG("Written %d bytes", writtenLen);
   return HTTP_OK;
--- a/HTTPClient.h	Mon Jul 30 15:16:51 2012 +0000
+++ b/HTTPClient.h	Sun Aug 05 15:30:07 2012 +0000
@@ -26,7 +26,7 @@
 
 #include "TCPSocketConnection.h"
 
-#define HTTP_CLIENT_DEFAULT_TIMEOUT 4000
+#define HTTP_CLIENT_DEFAULT_TIMEOUT 15000
 
 class HTTPData;
 
@@ -77,9 +77,9 @@
   @param url : url on which to execute the request
   @param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
-  @return 0 on success, NET error (<0) on failure
+  @return 0 on success, HTTP error (<0) on failure
   */
-  HTTPResult get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
+  HTTPResult get(const char* url, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
   
   /** Execute a GET request on the url
   Blocks until completion
@@ -88,9 +88,9 @@
   @param result : pointer to a char array in which the result will be stored
   @param maxResultLen : length of the char array (including space for the NULL-terminating char)
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
-  @return 0 on success, NET error on failure
+  @return 0 on success, HTTP error (<0) on failure
   */
-  HTTPResult get(const char* url, char* result, size_t maxResultLen, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
+  HTTPResult get(const char* url, char* result, size_t maxResultLen, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
 
   /** Execute a POST request on the url
   Blocks until completion
@@ -98,9 +98,9 @@
   @param dataOut : a IHTTPDataOut instance that contains the data that will be posted
   @param pDataIn : pointer to an IHTTPDataIn instance that will collect the data returned by the request, can be NULL
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
-  @return 0 on success, NET error on failure
+  @return 0 on success, HTTP error (<0) on failure
   */
-  HTTPResult post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
+  HTTPResult post(const char* url, const IHTTPDataOut& dataOut, IHTTPDataIn* pDataIn, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
   
   /** Get last request's HTTP response code
   @return The HTTP response code of the last request
@@ -115,7 +115,7 @@
     HTTP_HEAD
   };
 
-  HTTPResult connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, uint32_t timeout); //Execute request
+  HTTPResult connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, int timeout); //Execute request
   HTTPResult recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen); //0 on success, err code on failure
   HTTPResult send(char* buf, size_t len = 0); //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
@@ -123,7 +123,7 @@
   //Parameters
   TCPSocketConnection m_sock;
   
-  uint32_t m_timeout;
+  int m_timeout;
 
   const char* m_basicAuthUser;
   const char* m_basicAuthPassword;