User | Revision | Line number | New contents of line |
iva2k |
0:b0aa20381646
|
1
|
#ifndef HTTPDYNAMICPAGE_H
|
iva2k |
0:b0aa20381646
|
2
|
#define HTTPDYNAMICPAGE_H
|
iva2k |
0:b0aa20381646
|
3
|
|
iva2k |
0:b0aa20381646
|
4
|
#include "HTTPServer.h"
|
iva2k |
0:b0aa20381646
|
5
|
|
iva2k |
0:b0aa20381646
|
6
|
/**
|
iva2k |
0:b0aa20381646
|
7
|
* A datastorage helper for the HTTPDynamicPage class.
|
iva2k |
0:b0aa20381646
|
8
|
* Stores dynamically created page data and the size left to upload.
|
iva2k |
0:b0aa20381646
|
9
|
*/
|
iva2k |
0:b0aa20381646
|
10
|
class HTTPDynamicPageData : public HTTPData {
|
iva2k |
0:b0aa20381646
|
11
|
public:
|
iva2k |
0:b0aa20381646
|
12
|
HTTPDynamicPageData()
|
iva2k |
0:b0aa20381646
|
13
|
: page_free(NULL), page(NULL), size(0), _left(0) {}
|
iva2k |
0:b0aa20381646
|
14
|
virtual ~HTTPDynamicPageData() {
|
iva2k |
0:b0aa20381646
|
15
|
if (page_free && page) {
|
iva2k |
0:b0aa20381646
|
16
|
page_free(page);
|
iva2k |
0:b0aa20381646
|
17
|
}
|
iva2k |
0:b0aa20381646
|
18
|
}
|
iva2k |
0:b0aa20381646
|
19
|
|
iva2k |
0:b0aa20381646
|
20
|
/** Pointer to garbage collection function (for freeing page data)
|
iva2k |
0:b0aa20381646
|
21
|
* Should be set by callback function to a suitable free() if page is dynamically allocated
|
iva2k |
0:b0aa20381646
|
22
|
*/
|
iva2k |
0:b0aa20381646
|
23
|
void (*page_free)(void *page);
|
iva2k |
0:b0aa20381646
|
24
|
|
iva2k |
0:b0aa20381646
|
25
|
/** Pointer to the page data */
|
iva2k |
0:b0aa20381646
|
26
|
char *page;
|
iva2k |
0:b0aa20381646
|
27
|
|
iva2k |
0:b0aa20381646
|
28
|
/** Page data size
|
iva2k |
0:b0aa20381646
|
29
|
* As long as the page is NULL terminated you don't have to tell the data length.
|
iva2k |
0:b0aa20381646
|
30
|
* But if you want to send binary data you should tell us the size.
|
iva2k |
0:b0aa20381646
|
31
|
*/
|
iva2k |
0:b0aa20381646
|
32
|
int size;
|
iva2k |
0:b0aa20381646
|
33
|
|
iva2k |
0:b0aa20381646
|
34
|
/** Page data size left for the upload */
|
iva2k |
0:b0aa20381646
|
35
|
int _left;
|
iva2k |
0:b0aa20381646
|
36
|
};
|
iva2k |
0:b0aa20381646
|
37
|
|
iva2k |
0:b0aa20381646
|
38
|
/**
|
iva2k |
0:b0aa20381646
|
39
|
* This class Provide a Handler to send Static HTTP Pages from the bin file.
|
iva2k |
0:b0aa20381646
|
40
|
*/
|
iva2k |
0:b0aa20381646
|
41
|
class HTTPDynamicPage : public HTTPHandler {
|
iva2k |
0:b0aa20381646
|
42
|
public:
|
iva2k |
0:b0aa20381646
|
43
|
/**
|
iva2k |
0:b0aa20381646
|
44
|
* Constructor takes the page path and the page callback function.
|
iva2k |
0:b0aa20381646
|
45
|
*/
|
iva2k |
0:b0aa20381646
|
46
|
HTTPDynamicPage(const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
|
iva2k |
0:b0aa20381646
|
47
|
: HTTPHandler(path), _page_fnc(page_fnc) {
|
iva2k |
0:b0aa20381646
|
48
|
}
|
iva2k |
0:b0aa20381646
|
49
|
|
iva2k |
0:b0aa20381646
|
50
|
HTTPDynamicPage(HTTPServer *server, const char *path, HTTPStatus page_fnc(HTTPConnection *con, HTTPDynamicPageData *pd))
|
iva2k |
0:b0aa20381646
|
51
|
: HTTPHandler(path), _page_fnc(page_fnc) {
|
iva2k |
0:b0aa20381646
|
52
|
server->addHandler(this);
|
iva2k |
0:b0aa20381646
|
53
|
}
|
iva2k |
0:b0aa20381646
|
54
|
|
iva2k |
0:b0aa20381646
|
55
|
private:
|
iva2k |
0:b0aa20381646
|
56
|
/**
|
iva2k |
0:b0aa20381646
|
57
|
* This Dynamic Page is requested!
|
iva2k |
0:b0aa20381646
|
58
|
* Prepare a datastorage helper "HTTPDynamicPageData", create the page and store in helper, then initialize remaining data size.
|
iva2k |
0:b0aa20381646
|
59
|
* And return HTTP_OK if all ok.
|
iva2k |
0:b0aa20381646
|
60
|
*/
|
iva2k |
0:b0aa20381646
|
61
|
virtual HTTPStatus init(HTTPConnection *con) const {
|
iva2k |
0:b0aa20381646
|
62
|
HTTPDynamicPageData *data = new HTTPDynamicPageData();
|
iva2k |
0:b0aa20381646
|
63
|
con->data = data;
|
iva2k |
0:b0aa20381646
|
64
|
HTTPStatus status = _page_fnc(con, data); // assigns data->page, data->size and optionally data->page_free
|
iva2k |
0:b0aa20381646
|
65
|
if (!data->size && data->page)
|
iva2k |
0:b0aa20381646
|
66
|
data->size = strlen(data->page);
|
iva2k |
0:b0aa20381646
|
67
|
data->_left = data->size;
|
iva2k |
0:b0aa20381646
|
68
|
con->setLength(data->size);
|
iva2k |
0:b0aa20381646
|
69
|
return status;
|
iva2k |
0:b0aa20381646
|
70
|
}
|
iva2k |
0:b0aa20381646
|
71
|
|
iva2k |
0:b0aa20381646
|
72
|
/**
|
iva2k |
0:b0aa20381646
|
73
|
* Send the maximum data out to the client.
|
iva2k |
0:b0aa20381646
|
74
|
* If the file is complete transmitted close connection by returning HTTP_SuccessEnded
|
iva2k |
0:b0aa20381646
|
75
|
*/
|
iva2k |
0:b0aa20381646
|
76
|
virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
|
iva2k |
0:b0aa20381646
|
77
|
HTTPDynamicPageData *data = static_cast<HTTPDynamicPageData *>(con->data);
|
iva2k |
0:b0aa20381646
|
78
|
int len = min(maximum, data->_left);
|
iva2k |
0:b0aa20381646
|
79
|
err_t err;
|
iva2k |
0:b0aa20381646
|
80
|
|
iva2k |
0:b0aa20381646
|
81
|
do {
|
iva2k |
0:b0aa20381646
|
82
|
err = con->write((void*)&data->page[data->size - data->_left], len, 1);
|
iva2k |
0:b0aa20381646
|
83
|
if (err == ERR_MEM) {
|
iva2k |
0:b0aa20381646
|
84
|
len >>= 1;
|
iva2k |
0:b0aa20381646
|
85
|
}
|
iva2k |
0:b0aa20381646
|
86
|
} while(err == ERR_MEM && len > 1);
|
iva2k |
0:b0aa20381646
|
87
|
if (err == ERR_OK) {
|
iva2k |
0:b0aa20381646
|
88
|
data->_left -= len;
|
iva2k |
0:b0aa20381646
|
89
|
}
|
iva2k |
0:b0aa20381646
|
90
|
return (data->_left) ? HTTP_Success : HTTP_SuccessEnded;
|
iva2k |
0:b0aa20381646
|
91
|
}
|
iva2k |
0:b0aa20381646
|
92
|
|
iva2k |
0:b0aa20381646
|
93
|
HTTPStatus (*_page_fnc)(HTTPConnection *con, HTTPDynamicPageData *pd);
|
iva2k |
0:b0aa20381646
|
94
|
};
|
iva2k |
0:b0aa20381646
|
95
|
|
iva2k |
0:b0aa20381646
|
96
|
#endif
|