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:
WiredHome
Date:
Tue Jan 26 11:44:35 2016 +0000
Parent:
35:d9e2d1c96b75
Child:
37:74c1c4527f70
Commit message:
Fixed a memory leak that occurred during a redirection. Whether the redirection was 1 step, or many, there was a single leak. Fix was to free memory in the destructor.
; Reflowed the source to improve consistency.

Changed in this revision

HTTPClient.cpp Show annotated file Show diff for this revision Revisions of this file
data/HTTPText.cpp Show annotated file Show diff for this revision Revisions of this file
data/HTTPText.h Show annotated file Show diff for this revision Revisions of this file
--- a/HTTPClient.cpp	Thu Aug 06 11:11:31 2015 +0000
+++ b/HTTPClient.cpp	Tue Jan 26 11:44:35 2016 +0000
@@ -17,6 +17,12 @@
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
+//#include "Utility.h"            // private memory manager
+#ifndef UTILITY_H
+#define swMalloc malloc         // use the standard
+#define swFree free
+#endif
+
 //Debug is disabled by default
 //#define DEBUG "HTCL"
 #include <cstdio>
@@ -56,19 +62,21 @@
 
 HTTPClient::~HTTPClient()
 {
-
+    if (m_location) // if any redirection was involved, clean up after it.
+        swFree(m_location);
+    m_location = NULL;      // this step isn't necessary...
 }
 
 void HTTPClient::basicAuth(const char* user, const char* password) //Basic Authentification
 {
 #if 1
     if (m_basicAuthUser)
-        free(m_basicAuthUser);
-    m_basicAuthUser = (char *)malloc(strlen(user)+1);
+        swFree(m_basicAuthUser);
+    m_basicAuthUser = (char *)swMalloc(strlen(user)+1);
     strcpy(m_basicAuthUser, user);
     if (m_basicAuthPassword)
-        free(m_basicAuthPassword);
-    m_basicAuthPassword = (char *)malloc(strlen(password)+1);
+        swFree(m_basicAuthPassword);
+    m_basicAuthPassword = (char *)swMalloc(strlen(password)+1);
     strcpy(m_basicAuthPassword, password);
 #else
     m_basicAuthUser = user;
@@ -193,10 +201,10 @@
             return HTTP_CONN;
         }
 
-        //Send request
+        // Send request
         DBG("Sending request");
         const char* meth = (method==HTTP_GET)?"GET":(method==HTTP_POST)?"POST":(method==HTTP_PUT)?"PUT":(method==HTTP_DELETE)?"DELETE":"";
-        snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s:%d\r\nConnection: keep-alive\r\n", meth, path, host, port); //Write request
+        snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\nHost: %s:%d\r\n", meth, path, host, port); //Write request
         INFO(" buf{%s}", buf);
         ret = send(buf);
         if (ret) {
@@ -221,11 +229,10 @@
             }
         }
 
-        //Send all headers
+        // Send all headers
         INFO("Send custom header(s) %d (if any)", m_nCustomHeaders);
         for (size_t nh = 0; nh < m_nCustomHeaders * 2; nh+=2) {
-            INFO("hdr[%d] %s:", nh, m_customHeaders[nh]);
-            INFO("        %s", m_customHeaders[nh+1]);
+            INFO("hdr[%2d] %s: %s", nh, m_customHeaders[nh], m_customHeaders[nh+1]);
             snprintf(buf, sizeof(buf), "%s: %s\r\n", m_customHeaders[nh], m_customHeaders[nh+1]);
             ret = send(buf);
             if (ret) {
@@ -235,7 +242,7 @@
                 ERR("Could not write request");
                 return HTTP_CONN;
             }
-            INFO(" hdr %d", ret);
+            INFO("   send() returned %d", ret);
         }
 
         //Send default headers
@@ -383,9 +390,10 @@
                 } else if( !strcmp(key, "Content-Type") ) {
                     pDataIn->setDataType(value);
                 } else if ( !strcmp(key, "Location") ) {
-                    if (m_location)
-                        free(m_location);
-                    m_location = (char *)malloc(strlen(value)+1);
+                    if (m_location) {
+                        swFree(m_location);
+                    }
+                    m_location = (char *)swMalloc(strlen(value)+1);
                     if (m_location) {
                         strcpy(m_location,value);
                         url = m_location;
@@ -393,6 +401,8 @@
                         m_sock.close();
                         takeRedirect = true;
                         break;   // exit the while(true) header to follow the redirect
+                    } else {
+                        ERR("Could not allocate memory for %s", key);
                     }
                 }
 
--- a/data/HTTPText.cpp	Thu Aug 06 11:11:31 2015 +0000
+++ b/data/HTTPText.cpp	Tue Jan 26 11:44:35 2016 +0000
@@ -31,7 +31,7 @@
 
 HTTPText::HTTPText(char* str) : m_str(str), m_pos(0)
 {
-  m_size = strlen(str) + 1;
+    m_size = strlen(str) + 1;
 }
 
 HTTPText::HTTPText(char* str, size_t size) : m_str(str), m_size(size), m_pos(0)
@@ -42,47 +42,47 @@
 //IHTTPDataIn
 /*virtual*/ void HTTPText::readReset()
 {
-  m_pos = 0;
+    m_pos = 0;
 }
 
 /*virtual*/ int HTTPText::read(char* buf, size_t len, size_t* pReadLen)
 {
-  *pReadLen = MIN(len, m_size - 1 - m_pos);
-  memcpy(buf, m_str + m_pos, *pReadLen);
-  m_pos += *pReadLen;
-  return OK;
+    *pReadLen = MIN(len, m_size - 1 - m_pos);
+    memcpy(buf, m_str + m_pos, *pReadLen);
+    m_pos += *pReadLen;
+    return OK;
 }
 
 /*virtual*/ int HTTPText::getDataType(char* type, size_t maxTypeLen) //Internet media type for Content-Type header
 {
-  strncpy(type, "text/plain", maxTypeLen-1);
-  type[maxTypeLen-1] = '\0';
-  return OK;
+    strncpy(type, "text/plain", maxTypeLen-1);
+    type[maxTypeLen-1] = '\0';
+    return OK;
 }
 
 /*virtual*/ bool HTTPText::getIsChunked() //For Transfer-Encoding header
 {
-  return false;
+    return false;
 }
 
 /*virtual*/ size_t HTTPText::getDataLen() //For Content-Length header
 {
-  return m_size - 1;
+    return m_size - 1;
 }
 
 //IHTTPDataOut
 /*virtual*/ void HTTPText::writeReset()
 {
-  m_pos = 0;
+    m_pos = 0;
 }
 
 /*virtual*/ int HTTPText::write(const char* buf, size_t len)
 {
-  size_t writeLen = MIN(len, m_size - 1 - m_pos);
-  memcpy(m_str + m_pos, buf, writeLen);
-  m_pos += writeLen;
-  m_str[m_pos] = '\0';
-  return OK;
+    size_t writeLen = MIN(len, m_size - 1 - m_pos);
+    memcpy(m_str + m_pos, buf, writeLen);
+    m_pos += writeLen;
+    m_str[m_pos] = '\0';
+    return OK;
 }
 
 /*virtual*/ void HTTPText::setDataType(const char* type) //Internet media type from Content-Type header
--- a/data/HTTPText.h	Thu Aug 06 11:11:31 2015 +0000
+++ b/data/HTTPText.h	Tue Jan 26 11:44:35 2016 +0000
@@ -28,45 +28,45 @@
 class HTTPText : public IHTTPDataIn, public IHTTPDataOut
 {
 public:
-  /** Create an HTTPText instance for output
-   * @param[in] str String to be transmitted
-   */
-  HTTPText(char* str);
+    /** Create an HTTPText instance for output
+     * @param[in] str String to be transmitted
+     */
+    HTTPText(char* str);
 
-  /** Create an HTTPText instance for input
-   * @param[in] str Buffer to store the incoming string
-   * @param[in] size Size of the buffer
-   */
-  HTTPText(char* str, size_t size);
+    /** Create an HTTPText instance for input
+     * @param[in] str Buffer to store the incoming string
+     * @param[in] size Size of the buffer
+     */
+    HTTPText(char* str, size_t size);
 
 protected:
-  //IHTTPDataIn
-  virtual void readReset();
-  
-  virtual int read(char* buf, size_t len, size_t* pReadLen);
+    //IHTTPDataIn
+    virtual void readReset();
+
+    virtual int read(char* buf, size_t len, size_t* pReadLen);
 
-  virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header
+    virtual int getDataType(char* type, size_t maxTypeLen); //Internet media type for Content-Type header
 
-  virtual bool getIsChunked(); //For Transfer-Encoding header
+    virtual bool getIsChunked(); //For Transfer-Encoding header
 
-  virtual size_t getDataLen(); //For Content-Length header
+    virtual size_t getDataLen(); //For Content-Length header
 
-  //IHTTPDataOut
-  virtual void writeReset();
-  
-  virtual int write(const char* buf, size_t len);
+    //IHTTPDataOut
+    virtual void writeReset();
+
+    virtual int write(const char* buf, size_t len);
 
-  virtual void setDataType(const char* type); //Internet media type from Content-Type header
+    virtual void setDataType(const char* type); //Internet media type from Content-Type header
 
-  virtual void setIsChunked(bool chunked); //From Transfer-Encoding header
+    virtual void setIsChunked(bool chunked); //From Transfer-Encoding header
 
-  virtual void setDataLen(size_t len); //From Content-Length header, or if the transfer is chunked, next chunk length
+    virtual void setDataLen(size_t len); //From Content-Length header, or if the transfer is chunked, next chunk length
 
 private:
-  char* m_str;
-  size_t m_size;
+    char* m_str;
+    size_t m_size;
 
-  size_t m_pos;
+    size_t m_pos;
 };
 
 #endif /* HTTPTEXT_H_ */