HTTPDynamicPage
.
What was missing in HTTPServer is a way to make dynamic pages... until now. Here's an example program that uses new HTTPDynamicPage class and shows how to create fully dynamic pages in the code.
Dynamic pages are useful for interactive websites. One can build web application on MBED with help of dynamic pages.
once compiled and copied to MBED, open
http://mbeddeviceip/dynamic.htm?anyurlparamsyoulike&more
You will see the example page echo back to you the query string "?anyurlparamsyoulike&more". You can further modify the code to parse the query and perform some dynamic response generation. Simplest example could be to ask for a temperature in F or in C.
The complete code of HTTPDynamicPage.h (This code is only for quick overview. To reliably get the code without corruption use the published program):
#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 Dynamic 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
5 comments
You need to log in to post a comment
Ilya,
When compiling the code above, I received errors on Line 77.
HTTPDynamicPageData *data = static_cast(con->data);
So I looked up my older code (with the SNTP client) and found this on Line 77. It compliles without error.
HTTPDynamicPageData *data = static_cast<HTTPDynamicPageData *>(con->data);
Is there anything else that changed what allows for the new Line 77 in the above code to compile w/o error? Or have things totally changed?
...kevin