Dependencies:   mbed lwip

Revision:
0:b0aa20381646
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/HTTPDynamicPage.h	Thu Dec 10 08:59:18 2009 +0000
@@ -0,0 +1,96 @@
+#ifndef HTTPDYNAMICPAGE_H
+#define HTTPDYNAMICPAGE_H
+
+#include "HTTPServer.h"
+
+/**
+ * A datastorage helper for the HTTPDynamicPage class.
+ * Stores dynamically created page data and the size left to upload.
+ */
+class HTTPDynamicPageData : public HTTPData {
+  public:
+    HTTPDynamicPageData()
+     : page_free(NULL), page(NULL), size(0), _left(0) {}
+    virtual ~HTTPDynamicPageData() {
+      if (page_free && page) {
+          page_free(page);
+      }
+    }
+
+    /** Pointer to garbage collection function (for freeing page data)
+     * Should be set by callback function to a suitable free() if page is dynamically allocated
+     */
+    void (*page_free)(void *page);
+    
+    /** Pointer to the page data */
+    char *page;
+    
+    /** Page data size
+     * As long as the page is NULL terminated you don't have to tell the data length.
+     * But if you want to send binary data you should tell us the size.
+     */
+    int size;
+
+    /** Page data size left for the upload */
+    int _left;
+};
+
+/**
+ * This class Provide a Handler to send Static HTTP Pages from the bin file.
+ */
+class HTTPDynamicPage : public HTTPHandler {
+  public:
+    /**
+     * Constructor takes the page path and the page callback function.
+     */
+    HTTPDynamicPage(const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
+     : HTTPHandler(path), _page_fnc(page_fnc) {
+    }
+
+    HTTPDynamicPage(HTTPServer *server, const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
+     : HTTPHandler(path), _page_fnc(page_fnc) {
+      server->addHandler(this);
+    }
+
+  private:
+    /**
+     * This Dynamic Page is requested!
+     * Prepare a datastorage helper "HTTPDynamicPageData", create the page and store in helper, then initialize remaining data size.
+     * And return HTTP_OK if all ok.
+     */
+    virtual HTTPStatus init(HTTPConnection *con) const {
+      HTTPDynamicPageData *data = new HTTPDynamicPageData();
+      con->data = data;
+      HTTPStatus status = _page_fnc(con, data);    // assigns data->page, data->size and optionally data->page_free
+      if (!data->size && data->page)
+          data->size = strlen(data->page);
+      data->_left = data->size;
+      con->setLength(data->size);
+      return status;
+    }
+
+    /**
+     * Send the maximum data out to the client. 
+     * If the file is complete transmitted close connection by returning HTTP_SuccessEnded
+     */
+    virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
+      HTTPDynamicPageData *data = static_cast<HTTPDynamicPageData *>(con->data);
+      int len = min(maximum, data->_left);
+      err_t err;
+
+      do {
+        err = con->write((void*)&data->page[data->size - data->_left], len, 1);
+        if (err == ERR_MEM) {
+          len >>= 1;
+        }
+      } while(err == ERR_MEM && len > 1);
+      if (err == ERR_OK) {
+        data->_left -= len;
+      }
+      return (data->_left) ? HTTP_Success : HTTP_SuccessEnded;
+    }
+
+    HTTPStatus (*_page_fnc)(HTTPConnection *con, HTTPDynamicPageData *pd);
+};
+
+#endif