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:
Mon Jul 30 15:16:51 2012 +0000
Parent:
10:e1351de84c16
Child:
12:89d09a6db00a
Commit message:
Update for compat with 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	Wed Jul 18 15:40:04 2012 +0000
+++ b/HTTPClient.cpp	Mon Jul 30 15:16:51 2012 +0000
@@ -19,25 +19,30 @@
 
 //Debug is disabled by default
 #if 0
-#define __DEBUG__ 4 //Maximum verbosity
-#ifndef __MODULE__
-#define __MODULE__ "HTTPClient.cpp"
-#endif
+#define DBG(x, ...) 
+#define WARN(x, ...)
+#define ERR(x, ...) 
 #else
-#define __DEBUG__ 0 //Disabled
+#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__); 
 #endif
 
-#include "core/fwk.h"
-
-#include "HTTPClient.h"
-
 #define HTTP_REQUEST_TIMEOUT 30000
 #define HTTP_PORT 80
 
+#define OK 0
+
+#define MIN(x,y) (((x)<(y))?(x):(y))
+#define MAX(x,y) (((x)>(y))?(x):(y))
+
 #define CHUNK_SIZE 256
 
 #include <cstring>
 
+#include "HTTPClient.h"
+
 HTTPClient::HTTPClient() :
 m_sock(), m_basicAuthUser(NULL), m_basicAuthPassword(NULL), m_httpResponseCode(0)
 {
@@ -57,18 +62,18 @@
 }
 #endif
 
-int HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
+HTTPResult HTTPClient::get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   return connect(url, HTTP_GET, NULL, pDataIn, timeout);
 }
 
-int 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, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   HTTPText str(result, maxResultLen);
   return get(url, &str, timeout);
 }
 
-int 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, uint32_t timeout /*= HTTP_CLIENT_DEFAULT_TIMEOUT*/) //Blocking
 {
   return connect(url, HTTP_POST, (IHTTPDataOut*)&dataOut, pDataIn, timeout);
 }
@@ -83,7 +88,7 @@
     if(ret) { \
       m_sock.close(); \
       ERR("Connection error (%d)", ret); \
-      return NET_CONN; \
+      return HTTP_CONN; \
     } \
   } while(0)
 
@@ -91,10 +96,10 @@
   do{ \
     m_sock.close(); \
     ERR("Protocol error"); \
-    return NET_PROTOCOL; \
+    return HTTP_PRTCL; \
   } while(0)
 
-int 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, uint32_t timeout) //Execute request
 {
   m_httpResponseCode = 0; //Invalidate code
   m_timeout = timeout;
@@ -104,11 +109,11 @@
   char host[32];
   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)
+  HTTPResult res = parseURL(url, scheme, sizeof(scheme), host, sizeof(host), &port, path, sizeof(path));
+  if(res != HTTP_OK)
   {
-    ERR("parseURL returned %d", ret);
-    return ret;
+    ERR("parseURL returned %d", res);
+    return res;
   }
 
   if(port == 0) //TODO do handle HTTPS->443
@@ -123,12 +128,12 @@
 
   //Connect
   DBG("Connecting socket to server");
-  ret = m_sock.connect(host, port);
+  int ret = m_sock.connect(host, port);
   if (ret < 0)
   {
     m_sock.close();
     ERR("Could not connect");
-    return NET_CONN;
+    return HTTP_CONN;
   }
 
   //Send request
@@ -141,7 +146,7 @@
   {
     m_sock.close();
     ERR("Could not write request");
-    return NET_CONN;
+    return HTTP_CONN;
   }
 
   //Send all headers
@@ -162,7 +167,7 @@
       CHECK_CONN_ERR(ret);
     }
     char type[48];
-    if( pDataOut->getDataType(type, 48) == OK )
+    if( pDataOut->getDataType(type, 48) == HTTP_OK )
     {
       snprintf(buf, sizeof(buf), "Content-Type: %s\r\n", type);
       ret = send(buf);
@@ -442,10 +447,10 @@
   m_sock.close();
   DBG("Completed HTTP transaction");
 
-  return OK;
+  return HTTP_OK;
 }
 
-int HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure
+HTTPResult HTTPClient::recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen) //0 on success, err code on failure
 {
   DBG("Trying to read between %d and %d bytes", minLen, maxLen);
   size_t readLen = 0;
@@ -455,7 +460,7 @@
   {
     if(readLen < minLen)
     {
-      ret = m_sock.receive(buf + readLen, minLen - readLen, m_timeout);
+      ret = m_sock.receive_all(buf + readLen, minLen - readLen, m_timeout);
     }
     else
     {
@@ -475,15 +480,15 @@
     {
       ERR("Connection error (recv returned %d)", ret);
       *pReadLen = readLen;
-      return NET_CONN;
+      return HTTP_CONN;
     }
   }
   DBG("Read %d bytes", readLen);
   *pReadLen = readLen;
-  return OK;
+  return HTTP_OK;
 }
 
-int HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure
+HTTPResult HTTPClient::send(char* buf, size_t len) //0 on success, err code on failure
 {
   if(len == 0)
   {
@@ -495,7 +500,7 @@
   int ret;
   do
   {
-    ret = m_sock.send(buf + writtenLen, len - writtenLen, m_timeout);
+    ret = m_sock.send_all(buf + writtenLen, len - writtenLen, m_timeout);
     if(ret > 0)
     {
       writtenLen += ret;
@@ -503,33 +508,33 @@
     else if( ret == 0 )
     {
       WARN("Connection was closed by server");
-      return NET_CLOSED; //Connection was closed by server
+      return HTTP_CLOSED; //Connection was closed by server
     }
     else
     {
       ERR("Connection error (recv returned %d)", ret);
-      return NET_CONN;
+      return HTTP_CONN;
     }
   } while(writtenLen < len);
   
   DBG("Written %d bytes", writtenLen);
-  return OK;
+  return HTTP_OK;
 }
 
-int HTTPClient::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
+HTTPResult HTTPClient::parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen) //Parse URL
 {
   char* schemePtr = (char*) url;
   char* hostPtr = (char*) strstr(url, "://");
   if(hostPtr == NULL)
   {
     WARN("Could not find host");
-    return NET_INVALID; //URL is invalid
+    return HTTP_PARSE; //URL is invalid
   }
 
   if( maxSchemeLen < hostPtr - schemePtr + 1 ) //including NULL-terminating char
   {
     WARN("Scheme str is too small (%d >= %d)", maxSchemeLen, hostPtr - schemePtr + 1);
-    return NET_TOOSMALL;
+    return HTTP_PARSE;
   }
   memcpy(scheme, schemePtr, hostPtr - schemePtr);
   scheme[hostPtr - schemePtr] = '\0';
@@ -546,7 +551,7 @@
     if( sscanf(portPtr, "%hu", port) != 1)
     {
       WARN("Could not find port");
-      return NET_INVALID;
+      return HTTP_PARSE;
     }
   }
   else
@@ -562,7 +567,7 @@
   if( maxHostLen < hostLen + 1 ) //including NULL-terminating char
   {
     WARN("Host str is too small (%d >= %d)", maxHostLen, hostLen + 1);
-    return NET_TOOSMALL;
+    return HTTP_PARSE;
   }
   memcpy(host, hostPtr, hostLen);
   host[hostLen] = '\0';
@@ -581,10 +586,10 @@
   if( maxPathLen < pathLen + 1 ) //including NULL-terminating char
   {
     WARN("Path str is too small (%d >= %d)", maxPathLen, pathLen + 1);
-    return NET_TOOSMALL;
+    return HTTP_PARSE;
   }
   memcpy(path, pathPtr, pathLen);
   path[pathLen] = '\0';
 
-  return OK;
+  return HTTP_OK;
 }
--- a/HTTPClient.h	Wed Jul 18 15:40:04 2012 +0000
+++ b/HTTPClient.h	Mon Jul 30 15:16:51 2012 +0000
@@ -24,7 +24,7 @@
 #ifndef HTTP_CLIENT_H
 #define HTTP_CLIENT_H
 
-#include "TCPSocket.h"
+#include "TCPSocketConnection.h"
 
 #define HTTP_CLIENT_DEFAULT_TIMEOUT 4000
 
@@ -36,7 +36,6 @@
 ///HTTP client results
 enum HTTPResult
 {
-  HTTP_OK, ///<Success
   HTTP_PROCESSING, ///<Processing
   HTTP_PARSE, ///<url Parse error
   HTTP_DNS, ///<Could not resolve name
@@ -45,7 +44,9 @@
   HTTP_REFUSED, ///<HTTP 403 Error
   HTTP_ERROR, ///<HTTP xxx error
   HTTP_TIMEOUT, ///<Connection timeout
-  HTTP_CONN ///<Connection error
+  HTTP_CONN, ///<Connection error
+  HTTP_CLOSED, ///<Connection was closed by remote host
+  HTTP_OK = 0, ///<Success
 };
 
 /**A simple HTTP Client
@@ -78,7 +79,7 @@
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
   @return 0 on success, NET error (<0) on failure
   */
-  int get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
+  HTTPResult get(const char* url, IHTTPDataIn* pDataIn, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
   
   /** Execute a GET request on the url
   Blocks until completion
@@ -89,7 +90,7 @@
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
   @return 0 on success, NET error on failure
   */
-  int 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, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
 
   /** Execute a POST request on the url
   Blocks until completion
@@ -99,7 +100,7 @@
   @param timeout waiting timeout in ms (osWaitForever for blocking function, not recommended)
   @return 0 on success, NET error on failure
   */
-  int 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, uint32_t timeout = HTTP_CLIENT_DEFAULT_TIMEOUT); //Blocking
   
   /** Get last request's HTTP response code
   @return The HTTP response code of the last request
@@ -114,13 +115,13 @@
     HTTP_HEAD
   };
 
-  int connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, uint32_t timeout); //Execute request
-  int recv(char* buf, size_t minLen, size_t maxLen, size_t* pReadLen); //0 on success, err code on failure
-  int send(char* buf, size_t len = 0); //0 on success, err code on failure
-  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
+  HTTPResult connect(const char* url, HTTP_METH method, IHTTPDataOut* pDataOut, IHTTPDataIn* pDataIn, uint32_t 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
 
   //Parameters
-  TCPSocket m_sock;
+  TCPSocketConnection m_sock;
   
   uint32_t m_timeout;