Fork of HttpServer_snapshot_mbed-os library
Fork of HttpServer_snapshot_mbed-os by
HTTPServer.h@13:d3571c244759, 2017-06-07 (annotated)
- Committer:
- dkato
- Date:
- Wed Jun 07 05:53:36 2017 +0000
- Revision:
- 13:d3571c244759
- Parent:
- 11:0700755d64ae
- Child:
- 15:371fbad587ed
SnapshotHandler can register multiple paths.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
yueee_yt | 4:1b6b021ee21d | 1 | //#define _DEBUG_ALL |
yueee_yt | 4:1b6b021ee21d | 2 | |
yueee_yt | 0:fdf9c2c5200f | 3 | #ifndef HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 4 | #define HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 5 | |
yueee_yt | 4:1b6b021ee21d | 6 | #ifdef _DEBUG_ALL |
yueee_yt | 4:1b6b021ee21d | 7 | #define _DEBUG_HTTP_SERVER_H |
yueee_yt | 4:1b6b021ee21d | 8 | #endif |
yueee_yt | 4:1b6b021ee21d | 9 | |
yueee_yt | 0:fdf9c2c5200f | 10 | #include <string> |
yueee_yt | 0:fdf9c2c5200f | 11 | using std::string; |
yueee_yt | 0:fdf9c2c5200f | 12 | |
yueee_yt | 0:fdf9c2c5200f | 13 | #include <map> |
yueee_yt | 0:fdf9c2c5200f | 14 | using std::map; |
yueee_yt | 0:fdf9c2c5200f | 15 | |
yueee_yt | 0:fdf9c2c5200f | 16 | #include "HTTPRequestHandler.h" |
yueee_yt | 0:fdf9c2c5200f | 17 | #include "rtos.h" |
yueee_yt | 0:fdf9c2c5200f | 18 | #include "mbed.h" |
yueee_yt | 0:fdf9c2c5200f | 19 | |
yueee_yt | 0:fdf9c2c5200f | 20 | #define THREAD_MAX 5 |
yueee_yt | 0:fdf9c2c5200f | 21 | Thread *threads[THREAD_MAX]; |
yueee_yt | 0:fdf9c2c5200f | 22 | Thread *xthread; |
yueee_yt | 0:fdf9c2c5200f | 23 | |
yueee_yt | 0:fdf9c2c5200f | 24 | struct handlersComp { //Used to order handlers in the right way |
yueee_yt | 0:fdf9c2c5200f | 25 | bool operator() (const string& handler1, const string& handler2) const { |
yueee_yt | 0:fdf9c2c5200f | 26 | //The first handler is longer than the second one |
yueee_yt | 0:fdf9c2c5200f | 27 | if (handler1.length() > handler2.length()) |
yueee_yt | 0:fdf9c2c5200f | 28 | return true; //Returns true if handler1 is to appear before handler2 |
yueee_yt | 0:fdf9c2c5200f | 29 | else if (handler1.length() < handler2.length()) |
yueee_yt | 0:fdf9c2c5200f | 30 | return false; |
yueee_yt | 0:fdf9c2c5200f | 31 | else //To avoid the == case, sort now by address |
yueee_yt | 0:fdf9c2c5200f | 32 | return ((&handler1)>(&handler2)); |
yueee_yt | 0:fdf9c2c5200f | 33 | } |
yueee_yt | 0:fdf9c2c5200f | 34 | }; |
yueee_yt | 0:fdf9c2c5200f | 35 | |
dkato | 11:0700755d64ae | 36 | map< string, HTTPRequestHandler*(*)(const char*, const char* , TCPSocket* ), handlersComp > m_lpHandlers; |
yueee_yt | 0:fdf9c2c5200f | 37 | template<typename T> |
yueee_yt | 0:fdf9c2c5200f | 38 | void HTTPServerAddHandler(const char* path) //Template decl in header |
yueee_yt | 0:fdf9c2c5200f | 39 | { |
yueee_yt | 0:fdf9c2c5200f | 40 | m_lpHandlers[path] = &T::inst; |
yueee_yt | 0:fdf9c2c5200f | 41 | } |
yueee_yt | 0:fdf9c2c5200f | 42 | |
yueee_yt | 0:fdf9c2c5200f | 43 | void ListenThread(void const *args); |
yueee_yt | 0:fdf9c2c5200f | 44 | enum HTTP_METH { |
yueee_yt | 0:fdf9c2c5200f | 45 | HTTP_GET, |
yueee_yt | 0:fdf9c2c5200f | 46 | HTTP_POST, |
yueee_yt | 0:fdf9c2c5200f | 47 | HTTP_HEAD |
yueee_yt | 0:fdf9c2c5200f | 48 | }; |
yueee_yt | 0:fdf9c2c5200f | 49 | |
dkato | 11:0700755d64ae | 50 | bool getRequest(TCPSocket* client, string* path, string* meth) |
yueee_yt | 0:fdf9c2c5200f | 51 | { |
yueee_yt | 0:fdf9c2c5200f | 52 | char req[128]; |
yueee_yt | 0:fdf9c2c5200f | 53 | char c_path[128]; |
yueee_yt | 0:fdf9c2c5200f | 54 | char c_meth[128]; |
yueee_yt | 0:fdf9c2c5200f | 55 | const int maxLen = 128; |
yueee_yt | 0:fdf9c2c5200f | 56 | char* p = req; |
yueee_yt | 0:fdf9c2c5200f | 57 | //Read Line |
yueee_yt | 0:fdf9c2c5200f | 58 | int ret; |
yueee_yt | 0:fdf9c2c5200f | 59 | int len = 0; |
yueee_yt | 0:fdf9c2c5200f | 60 | for(int i = 0; i < maxLen - 1; i++) { |
dkato | 11:0700755d64ae | 61 | ret = client->recv(p, 1); |
yueee_yt | 0:fdf9c2c5200f | 62 | if(!ret) { |
yueee_yt | 0:fdf9c2c5200f | 63 | break; |
yueee_yt | 0:fdf9c2c5200f | 64 | } |
yueee_yt | 0:fdf9c2c5200f | 65 | if( (len > 1) && *(p-1)=='\r' && *p=='\n' ) { |
yueee_yt | 0:fdf9c2c5200f | 66 | p--; |
yueee_yt | 0:fdf9c2c5200f | 67 | len-=2; |
yueee_yt | 0:fdf9c2c5200f | 68 | break; |
yueee_yt | 0:fdf9c2c5200f | 69 | } else if( *p=='\n' ) { |
yueee_yt | 0:fdf9c2c5200f | 70 | len--; |
yueee_yt | 0:fdf9c2c5200f | 71 | break; |
yueee_yt | 0:fdf9c2c5200f | 72 | } |
yueee_yt | 0:fdf9c2c5200f | 73 | p++; |
yueee_yt | 0:fdf9c2c5200f | 74 | len++; |
yueee_yt | 0:fdf9c2c5200f | 75 | } |
yueee_yt | 0:fdf9c2c5200f | 76 | *p = 0; |
yueee_yt | 4:1b6b021ee21d | 77 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 78 | printf("Parsing request : %s\r\n", req); |
yueee_yt | 4:1b6b021ee21d | 79 | #endif |
yueee_yt | 0:fdf9c2c5200f | 80 | ret = sscanf(req, "%s %s HTTP/%*d.%*d", c_meth, c_path); |
yueee_yt | 0:fdf9c2c5200f | 81 | if(ret !=2) return false; |
yueee_yt | 0:fdf9c2c5200f | 82 | *meth = string(c_meth); |
yueee_yt | 0:fdf9c2c5200f | 83 | *path = string(c_path); |
yueee_yt | 0:fdf9c2c5200f | 84 | return true; |
yueee_yt | 0:fdf9c2c5200f | 85 | } |
yueee_yt | 0:fdf9c2c5200f | 86 | |
dkato | 11:0700755d64ae | 87 | void dispatchRequest(TCPSocket* client) |
yueee_yt | 0:fdf9c2c5200f | 88 | { |
yueee_yt | 0:fdf9c2c5200f | 89 | string path; |
yueee_yt | 0:fdf9c2c5200f | 90 | string meth; |
yueee_yt | 0:fdf9c2c5200f | 91 | HTTP_METH methCode; |
yueee_yt | 4:1b6b021ee21d | 92 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 93 | printf("Dispatching req\r\n"); |
yueee_yt | 4:1b6b021ee21d | 94 | #endif |
yueee_yt | 0:fdf9c2c5200f | 95 | if( !getRequest(client,&path, &meth ) ) { |
yueee_yt | 4:1b6b021ee21d | 96 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 97 | printf("dispatchRequest Invalid request\r\n"); |
yueee_yt | 4:1b6b021ee21d | 98 | #endif |
yueee_yt | 0:fdf9c2c5200f | 99 | return; //Invalid request |
yueee_yt | 0:fdf9c2c5200f | 100 | } |
yueee_yt | 0:fdf9c2c5200f | 101 | if( !meth.compare("GET") ) { |
yueee_yt | 4:1b6b021ee21d | 102 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 103 | printf("dispatchRequest HTTP_GET\r\n"); |
yueee_yt | 4:1b6b021ee21d | 104 | #endif |
yueee_yt | 0:fdf9c2c5200f | 105 | methCode = HTTP_GET; |
yueee_yt | 0:fdf9c2c5200f | 106 | } else if( !meth.compare("POST") ) { |
yueee_yt | 4:1b6b021ee21d | 107 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 108 | printf("dispatchRequest HTTP_POST\r\n"); |
yueee_yt | 4:1b6b021ee21d | 109 | #endif |
yueee_yt | 0:fdf9c2c5200f | 110 | methCode = HTTP_POST; |
yueee_yt | 0:fdf9c2c5200f | 111 | } else if( !meth.compare("HEAD") ) { |
yueee_yt | 4:1b6b021ee21d | 112 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 113 | printf("dispatchRequest HTTP_HEAD\r\n"); |
yueee_yt | 4:1b6b021ee21d | 114 | #endif |
yueee_yt | 0:fdf9c2c5200f | 115 | methCode = HTTP_HEAD; |
yueee_yt | 0:fdf9c2c5200f | 116 | } else { |
yueee_yt | 4:1b6b021ee21d | 117 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 118 | printf("dispatchRequest() Parse error\r\n"); |
yueee_yt | 4:1b6b021ee21d | 119 | #endif |
yueee_yt | 0:fdf9c2c5200f | 120 | return; |
yueee_yt | 0:fdf9c2c5200f | 121 | } |
yueee_yt | 4:1b6b021ee21d | 122 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 123 | printf("Looking for a handler\r\n"); |
yueee_yt | 4:1b6b021ee21d | 124 | #endif |
dkato | 11:0700755d64ae | 125 | map< string, HTTPRequestHandler*(*)(const char*, const char*, TCPSocket*), handlersComp >::iterator it; |
yueee_yt | 0:fdf9c2c5200f | 126 | int root_len = 0; |
yueee_yt | 0:fdf9c2c5200f | 127 | for (it = m_lpHandlers.begin(); it != m_lpHandlers.end(); it++) { |
yueee_yt | 4:1b6b021ee21d | 128 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 129 | printf("Checking %s...\r\n", (*it).first.c_str()); |
yueee_yt | 4:1b6b021ee21d | 130 | #endif |
yueee_yt | 0:fdf9c2c5200f | 131 | root_len = (*it).first.length(); |
yueee_yt | 0:fdf9c2c5200f | 132 | if ( root_len && |
yueee_yt | 0:fdf9c2c5200f | 133 | !path.compare( 0, root_len, (*it).first ) && |
yueee_yt | 0:fdf9c2c5200f | 134 | (path[root_len] == '/' || path[root_len] == '\0')) { |
yueee_yt | 4:1b6b021ee21d | 135 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 136 | printf("Found (%s)\r\n", (*it).first.c_str()); |
yueee_yt | 4:1b6b021ee21d | 137 | #endif |
yueee_yt | 0:fdf9c2c5200f | 138 | // Found! |
yueee_yt | 0:fdf9c2c5200f | 139 | break; // for |
yueee_yt | 0:fdf9c2c5200f | 140 | } |
yueee_yt | 0:fdf9c2c5200f | 141 | } |
yueee_yt | 0:fdf9c2c5200f | 142 | if((it == m_lpHandlers.end()) && !(m_lpHandlers.empty())) { |
yueee_yt | 4:1b6b021ee21d | 143 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 144 | printf("Using default handler\r\n"); |
yueee_yt | 4:1b6b021ee21d | 145 | #endif |
yueee_yt | 0:fdf9c2c5200f | 146 | it = m_lpHandlers.end(); |
yueee_yt | 0:fdf9c2c5200f | 147 | it--; //Get the last element |
yueee_yt | 0:fdf9c2c5200f | 148 | if( ! (((*it).first.length() == 0) || !(*it).first.compare("/")) ) //This is not the default handler |
yueee_yt | 0:fdf9c2c5200f | 149 | it = m_lpHandlers.end(); |
yueee_yt | 0:fdf9c2c5200f | 150 | root_len = 0; |
yueee_yt | 0:fdf9c2c5200f | 151 | } |
yueee_yt | 0:fdf9c2c5200f | 152 | if(it == m_lpHandlers.end()) { |
yueee_yt | 4:1b6b021ee21d | 153 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 154 | printf("No handler found\r\n"); |
yueee_yt | 4:1b6b021ee21d | 155 | #endif |
yueee_yt | 0:fdf9c2c5200f | 156 | return; |
yueee_yt | 0:fdf9c2c5200f | 157 | } |
yueee_yt | 4:1b6b021ee21d | 158 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 159 | printf("Handler found.\r\n"); |
yueee_yt | 4:1b6b021ee21d | 160 | #endif |
yueee_yt | 0:fdf9c2c5200f | 161 | HTTPRequestHandler* pHdlr = (*it).second((*it).first.c_str(), path.c_str() + root_len, client); |
yueee_yt | 0:fdf9c2c5200f | 162 | //**** client = NULL; //We don't own it anymore |
yueee_yt | 0:fdf9c2c5200f | 163 | switch(methCode) { |
yueee_yt | 0:fdf9c2c5200f | 164 | case HTTP_GET: |
yueee_yt | 0:fdf9c2c5200f | 165 | pHdlr->doGet(); |
yueee_yt | 0:fdf9c2c5200f | 166 | break; |
yueee_yt | 0:fdf9c2c5200f | 167 | case HTTP_POST: |
yueee_yt | 0:fdf9c2c5200f | 168 | pHdlr->doPost(); |
yueee_yt | 0:fdf9c2c5200f | 169 | break; |
yueee_yt | 0:fdf9c2c5200f | 170 | case HTTP_HEAD: |
yueee_yt | 0:fdf9c2c5200f | 171 | pHdlr->doHead(); |
yueee_yt | 0:fdf9c2c5200f | 172 | break; |
yueee_yt | 0:fdf9c2c5200f | 173 | } |
yueee_yt | 0:fdf9c2c5200f | 174 | delete pHdlr; |
yueee_yt | 4:1b6b021ee21d | 175 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 4:1b6b021ee21d | 176 | printf("(dispatcherRequest)return\r\n"); |
yueee_yt | 4:1b6b021ee21d | 177 | #endif |
yueee_yt | 4:1b6b021ee21d | 178 | return ; |
yueee_yt | 0:fdf9c2c5200f | 179 | } |
yueee_yt | 0:fdf9c2c5200f | 180 | |
dkato | 13:d3571c244759 | 181 | void HTTPServerChild (TCPSocket* client) |
yueee_yt | 0:fdf9c2c5200f | 182 | { |
yueee_yt | 4:1b6b021ee21d | 183 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 184 | printf("HTTPServerChiled Start......\r\n"); |
yueee_yt | 4:1b6b021ee21d | 185 | #endif |
yueee_yt | 0:fdf9c2c5200f | 186 | |
yueee_yt | 0:fdf9c2c5200f | 187 | for (;;) { |
yueee_yt | 4:1b6b021ee21d | 188 | #ifdef _DEBUG_HTTP_SERVER_H |
dkato | 13:d3571c244759 | 189 | printf("(HTTPServer.h<HTTPServerChild>)Connection\r\n"); |
yueee_yt | 4:1b6b021ee21d | 190 | #endif |
yueee_yt | 0:fdf9c2c5200f | 191 | dispatchRequest(client); |
yueee_yt | 4:1b6b021ee21d | 192 | #ifdef _DEBUG_HTTP_SERVER_H |
dkato | 13:d3571c244759 | 193 | printf("(HTTPServer.h<HTTPServerChild>)Close\r\n"); |
yueee_yt | 4:1b6b021ee21d | 194 | #endif |
yueee_yt | 0:fdf9c2c5200f | 195 | client->close(); |
yueee_yt | 0:fdf9c2c5200f | 196 | Thread::signal_wait(1); |
yueee_yt | 0:fdf9c2c5200f | 197 | } |
yueee_yt | 0:fdf9c2c5200f | 198 | } |
yueee_yt | 0:fdf9c2c5200f | 199 | |
dkato | 13:d3571c244759 | 200 | void HTTPServerCloser (TCPSocket *client) |
yueee_yt | 0:fdf9c2c5200f | 201 | { |
yueee_yt | 0:fdf9c2c5200f | 202 | for (;;) { |
yueee_yt | 0:fdf9c2c5200f | 203 | client->close(); |
yueee_yt | 4:1b6b021ee21d | 204 | #ifdef _DEBUG_HTTP_SERVER_H |
dkato | 13:d3571c244759 | 205 | printf("Close\r\n"); |
yueee_yt | 4:1b6b021ee21d | 206 | #endif |
yueee_yt | 0:fdf9c2c5200f | 207 | Thread::signal_wait(1); |
yueee_yt | 0:fdf9c2c5200f | 208 | } |
yueee_yt | 0:fdf9c2c5200f | 209 | } |
yueee_yt | 0:fdf9c2c5200f | 210 | |
dkato | 11:0700755d64ae | 211 | void HTTPServerStart(NetworkInterface *net, int port = 80) |
yueee_yt | 0:fdf9c2c5200f | 212 | { |
yueee_yt | 0:fdf9c2c5200f | 213 | int i, t = 0; |
dkato | 11:0700755d64ae | 214 | TCPSocket clients[THREAD_MAX]; |
dkato | 11:0700755d64ae | 215 | TCPSocket xclient; |
yueee_yt | 0:fdf9c2c5200f | 216 | |
yueee_yt | 0:fdf9c2c5200f | 217 | for (i = 0; i < THREAD_MAX; i ++) { |
yueee_yt | 0:fdf9c2c5200f | 218 | threads[i] = NULL; |
yueee_yt | 0:fdf9c2c5200f | 219 | } |
yueee_yt | 0:fdf9c2c5200f | 220 | xthread = NULL; |
yueee_yt | 0:fdf9c2c5200f | 221 | |
dkato | 11:0700755d64ae | 222 | TCPServer server(net); |
yueee_yt | 0:fdf9c2c5200f | 223 | server.bind(port); |
yueee_yt | 0:fdf9c2c5200f | 224 | server.listen(); |
yueee_yt | 4:1b6b021ee21d | 225 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 226 | printf("Wait for new connection...\r\n"); |
yueee_yt | 4:1b6b021ee21d | 227 | #endif |
dkato | 13:d3571c244759 | 228 | |
yueee_yt | 0:fdf9c2c5200f | 229 | for (;;) { |
yueee_yt | 4:1b6b021ee21d | 230 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 231 | printf("**Start Loop** \r\n"); |
yueee_yt | 4:1b6b021ee21d | 232 | #endif |
yueee_yt | 0:fdf9c2c5200f | 233 | if (t >= 0) { |
dkato | 11:0700755d64ae | 234 | if(server.accept(&clients[t])==0) { |
yueee_yt | 0:fdf9c2c5200f | 235 | // fork child process |
yueee_yt | 0:fdf9c2c5200f | 236 | if (threads[t]) { |
yueee_yt | 0:fdf9c2c5200f | 237 | threads[t]->signal_set(1); |
yueee_yt | 0:fdf9c2c5200f | 238 | } else { |
dkato | 13:d3571c244759 | 239 | threads[t] = new Thread(osPriorityNormal, 1024 * 3); |
dkato | 13:d3571c244759 | 240 | threads[t]->start(callback(HTTPServerChild, &clients[t])); |
yueee_yt | 0:fdf9c2c5200f | 241 | } |
yueee_yt | 4:1b6b021ee21d | 242 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 243 | printf("Forked %d\r\n", t); |
yueee_yt | 4:1b6b021ee21d | 244 | #endif |
yueee_yt | 0:fdf9c2c5200f | 245 | } |
yueee_yt | 0:fdf9c2c5200f | 246 | } else { |
dkato | 11:0700755d64ae | 247 | if(server.accept(&xclient)==0) { |
yueee_yt | 0:fdf9c2c5200f | 248 | // closer process |
yueee_yt | 0:fdf9c2c5200f | 249 | if (xthread) { |
yueee_yt | 0:fdf9c2c5200f | 250 | xthread->signal_set(1); |
yueee_yt | 0:fdf9c2c5200f | 251 | } else { |
dkato | 13:d3571c244759 | 252 | xthread = new Thread; |
dkato | 13:d3571c244759 | 253 | xthread->start(callback(HTTPServerCloser, &xclient)); |
yueee_yt | 0:fdf9c2c5200f | 254 | } |
yueee_yt | 4:1b6b021ee21d | 255 | #ifdef _DEBUG_HTTP_SERVER_H |
yueee_yt | 0:fdf9c2c5200f | 256 | printf("Connection full\r\n"); |
yueee_yt | 4:1b6b021ee21d | 257 | #endif |
yueee_yt | 0:fdf9c2c5200f | 258 | } |
yueee_yt | 0:fdf9c2c5200f | 259 | } |
yueee_yt | 0:fdf9c2c5200f | 260 | |
yueee_yt | 0:fdf9c2c5200f | 261 | t = -1; |
yueee_yt | 0:fdf9c2c5200f | 262 | for (i = 0; i < THREAD_MAX; i ++) { |
dkato | 6:d9e6379eefac | 263 | if ((threads[i] == NULL) |
dkato | 11:0700755d64ae | 264 | || ((threads[i]->get_state() == Thread::WaitingAnd))) { |
yueee_yt | 0:fdf9c2c5200f | 265 | if (t < 0) t = i; // next empty thread |
yueee_yt | 0:fdf9c2c5200f | 266 | } |
yueee_yt | 0:fdf9c2c5200f | 267 | } |
yueee_yt | 0:fdf9c2c5200f | 268 | } |
yueee_yt | 0:fdf9c2c5200f | 269 | } |
yueee_yt | 0:fdf9c2c5200f | 270 | #include "Handler/RPCHandler.h" |
yueee_yt | 0:fdf9c2c5200f | 271 | #include "Handler/FSHandler.h" |
yueee_yt | 0:fdf9c2c5200f | 272 | #include "Handler/SimpleHandler.h" |
dkato | 6:d9e6379eefac | 273 | #include "SnapshotHandler.h" |
yueee_yt | 0:fdf9c2c5200f | 274 | |
yueee_yt | 0:fdf9c2c5200f | 275 | #endif |