Example of HTTPServer with additional features: * SNTPClient, DST rules * Link status indication * Local or SDCard-based WebServer * RPC-able class * Static and Dynamic HTML page
HTTPDynamicPage.h
- Committer:
- iva2k
- Date:
- 2010-01-12
- Revision:
- 2:360fda42fefd
- Parent:
- 0:886e4b3119ad
File content as of revision 2:360fda42fefd:
#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