mbed_controller / HTTPD

Dependents:   mbed_controller_demo

Fork of HTTPD by Suga koubou

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPD.h Source File

HTTPD.h

00001 /* Copyright (C) 2013 Hiroshi Suga, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #ifndef HTTPD_H
00020 #define HTTPD_H
00021 
00022 #include "mbed.h"
00023 #include "rtos.h"
00024 #include "EthernetInterface.h"
00025 #include "CBuffer.h"
00026 
00027 //#define DEBUG
00028 
00029 #define HTTPD_PORT 80
00030 #define HTTPD_MAX_CLIENTS 2
00031 #define HTTPD_KEEPALIVE 10
00032 #define HTTPD_TIMEOUT 15000
00033 #define HTTPD_MAX_HANDLES 10
00034  
00035 #define HTTPD_CMD_SIZE 100
00036 #define HTTPD_BUF_SIZE 256
00037 //#define HTTPD_STACK_SIZE (1024 * 6)
00038 // The HTTPD_STACK_SIZE is too much for clild thread, so it is reduced.
00039 // See following Callgraph report of Keil MDK.
00040 #define HTTPD_STACK_SIZE (1024 * 2)
00041 /* 
00042 HTTPD::child(const void*) (Thumb, 244 bytes, Stack size 272 bytes, httpd.o(.text)) 
00043 
00044 [Stack]
00045 
00046 Max Depth = 1288 + Unknown Stack Size
00047 Call Chain = HTTPD::child(const void*) <-> HTTPD::recvData(int, char) <->
00048 HTTPD::httpdFile(int, char*) <-> fopen <-> _freopen_locked <-> _sys_open <-> 
00049 */
00050 //#define HTTPD_ENABLE_CLOSER
00051 
00052 //Debug is disabled by default
00053 #if defined(DEBUG) and (!defined(TARGET_LPC11U24))
00054 #define DBG(x, ...) std::printf("[DBG]" x "\r\n", ##__VA_ARGS__);
00055 #define WARN(x, ...) std::printf("[WARN]" x "\r\n", ##__VA_ARGS__);
00056 #define ERR(x, ...) std::printf("[ERR]" x "\r\n", ##__VA_ARGS__);
00057 #define INFO(x, ...) std::printf("[INFO]" x "\r\n", ##__VA_ARGS__);
00058 #else
00059 #define DBG(x, ...)
00060 #define WARN(x, ...)
00061 #define ERR(x, ...)
00062 #define INFO(x, ...)
00063 #endif
00064 
00065 
00066 class HTTPD {
00067 public:
00068 
00069     enum Request {
00070         REQ_HTTPGET,
00071         REQ_HTTPPOST,
00072         REQ_PUT,
00073     };
00074 
00075     enum Mode {
00076         MODE_REQUEST,
00077         MODE_REQSTR,
00078         MODE_HEADER,
00079         MODE_BODY,
00080         MODE_ENTER,
00081         MODE_ERROR,
00082         MODE_WEBSOCKET,
00083         MODE_WEBSOCKET_MASK,
00084         MODE_WEBSOCKET_BODY,
00085         MODE_WEBSOCKET_ENTER,
00086     };
00087 
00088     struct STATE {
00089         Thread *thread;
00090         TCPSocketConnection *client;
00091         volatile Request req;
00092         volatile Mode mode;
00093         CircBuffer <char>*buf;
00094         char uri[HTTPD_CMD_SIZE];
00095         char *filename;
00096         char *querystring;
00097         int enter;
00098         int length;
00099         int n;
00100         int keepalive;
00101         int websocket;
00102         char *websocket_key;
00103         int websocket_opcode;
00104         int websocket_flg;
00105         char websocket_mask[4];
00106         int websocket_payload;
00107         int (*sendws)(int id, const char *buf, int len, const char *mask);
00108     };
00109 
00110     HTTPD ();
00111     
00112     int start (int port = HTTPD_PORT);
00113 
00114     // --- HTTPD_req.cpp ---
00115     void httpdError (int id, int err);
00116 
00117     // --- HTTPD_ws.cpp ---
00118     static int sendWebsocket (int id, const char *buf, int len, const char *mask = NULL);
00119 
00120     // --- HTTPD_util.cpp ---
00121     char *getUri (int id);
00122     char *getFilename (int id);
00123     char *getQueryString (int id);
00124     int send (int id, const char *body, int len, const char *header = NULL);
00125     int receive (int id, char *buf, int len);
00126     int attach (const char *uri, const char *dir);
00127     int attach (const char *uri, void (*funcCgi)(int id));
00128     int base64encode (const char *input, int length, char *output, int len);
00129     int urlencode (const char *str, char *buf, int len);
00130     int urldecode (const char *str, char *buf, int len);
00131 
00132     static HTTPD * getInstance() {
00133         return _inst;
00134     };
00135 
00136 private :
00137     static HTTPD *_inst;
00138     Thread *_daemon;
00139     TCPSocketServer _server;
00140 
00141 #ifdef HTTPD_ENABLE_CLOSER
00142     struct STATE _state[HTTPD_MAX_CLIENTS + 1];
00143 #else
00144     struct STATE _state[HTTPD_MAX_CLIENTS];
00145 #endif
00146 
00147     struct HANDLER {
00148         char *uri;
00149         char *dir;
00150         void (*funcCgi)(int id);
00151     } _handler[HTTPD_MAX_HANDLES];
00152 
00153     int _handler_count;
00154 
00155     static void daemon (void const *arg);
00156     static void child (void const *arg);
00157     static void closer (void const *arg);
00158 
00159     // --- HTTPD_req.cpp ---
00160     int httpdFile (int id, char *dir);
00161     void recvData (int id, char c);
00162     int parseRequest (int id);
00163     int parseHeader (int id);
00164     void reqContentLength (int id, const char *buf);
00165     void reqConnection (int id, const char *buf);
00166     void reqUpgrade (int id, const char *buf);
00167     void reqWebSocketVersion (int id, const char *buf);
00168     void reqWebSocketKey (int id, const char *buf);
00169 
00170     // --- HTTPD_ws.cpp ---
00171     void recvWS (int id, char c);
00172     int parseWebsocket (int id);
00173     int acceptWebsocket (int id);
00174 
00175     // --- HTTPD_util.cpp ---
00176     int getHandler (const char *uri);
00177     char *mimetype (char *file);
00178     int strnicmp (const char *p1, const char *p2, int n);
00179     int from_hex (int ch);
00180     int to_hex (int code);
00181 };
00182 
00183 #endif
00184