A simple web server mainly based on ideas from Jasper Schuurmans Netduino web server
Dependents: RdBlindsServer SpideyWallWeb RdGasUseMonitor
RdWebServer.h
00001 // RdWebServer - Simple Web Server for MBED 00002 // Copyright (C) Rob Dobson 2013-2015, MIT License 00003 // Inspired by Jasper Schuurmans multi-threaded web server for Netduino which now seems to have gone from ... 00004 // http://www.schuurmans.cc/multi-threaded-web-server-for-netduino-plus 00005 // More details at http://robdobson.com/2013/10/moving-my-window-shades-control-to-mbed/ 00006 00007 #ifndef RD_WEB_SERVER 00008 #define RD_WEB_SERVER 00009 00010 #include "mbed.h" 00011 00012 // Debug level 00013 #ifdef RDWEB_DEBUG 00014 #if (RDWEB_DEBUG > 3) 00015 #define RD_DBG(x, ...) std::printf("[RD_DBG: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); 00016 #else 00017 #define RD_DBG(x, ...) 00018 #endif 00019 #else 00020 #define RD_DBG(x, ...) 00021 #endif 00022 00023 #ifdef RDWEB_DEBUG 00024 #if (RDWEB_DEBUG > 2) 00025 #define RD_INFO(x, ...) std::printf("[RD_INFO: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); 00026 #else 00027 #define RD_INFO(x, ...) 00028 #endif 00029 #else 00030 #define RD_INFO(x, ...) 00031 #endif 00032 00033 #ifdef RDWEB_DEBUG 00034 #if (RDWEB_DEBUG > 1) 00035 #define RD_WARN(x, ...) std::printf("[RD_WARNING: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); 00036 #else 00037 #define RD_WARN(x, ...) 00038 #endif 00039 #else 00040 #define RD_WARN(x, ...) 00041 #endif 00042 00043 #ifdef RDWEB_DEBUG 00044 #if (RDWEB_DEBUG > 0) 00045 #define RD_ERR(x, ...) std::printf("[RD_ERR: %s:%d]" x "\r\n", __FILE__, __LINE__, ##__VA_ARGS__); 00046 #else 00047 #define RD_ERR(x, ...) 00048 #endif 00049 #else 00050 #define RD_ERR(x, ...) 00051 #endif 00052 00053 // Length of strings 00054 const int MAX_CMDSTR_LEN = 100; 00055 const int MAX_ARGSTR_LEN = 100; 00056 const int MAX_WEB_SERVER_CMDS = 30; 00057 const int MAX_WEB_SERVER_CACHED_FILES = 5; 00058 const int SUBST_MAX_FNAME_LEN = 40; // note local files on MBED are 8.3 but this might include other files 00059 00060 extern RawSerial pc; 00061 00062 class RdFileCacheEntry 00063 { 00064 public: 00065 RdFileCacheEntry(char* pFileName) 00066 { 00067 _bCacheValid = false; 00068 strncpy(_fileName, pFileName, SUBST_MAX_FNAME_LEN-1); 00069 _fileName[SUBST_MAX_FNAME_LEN-1] = '\0'; 00070 _pFileContent = NULL; 00071 } 00072 ~RdFileCacheEntry() 00073 { 00074 delete _pFileContent; 00075 } 00076 bool readLocalFileIntoCache(char* fileName); 00077 public: 00078 bool _bCacheValid; 00079 char _fileName[SUBST_MAX_FNAME_LEN]; 00080 char* _pFileContent; 00081 int _nFileLen; 00082 }; 00083 00084 typedef char* (*CmdCallbackType)(int method, char*cmdStr, char* argStr, char* msgBuffer, int msgLen, 00085 int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos); 00086 00087 class RdWebServerCmdDef 00088 { 00089 public: 00090 static const int CMD_LOCALFILE = 1; 00091 static const int CMD_CALLBACK = 2; 00092 static const int CMD_SDORUSBFILE = 3; 00093 RdWebServerCmdDef(char* pStr, int cmdType, CmdCallbackType callback, char* substFileName = NULL, bool bCacheIfPossible = false) 00094 { 00095 _pCmdStr = pStr; 00096 _cmdType = cmdType; 00097 _callback = callback; 00098 _substFileName[0] = '\0'; 00099 if (substFileName != NULL) 00100 { 00101 strncpy(_substFileName, substFileName, SUBST_MAX_FNAME_LEN); 00102 _substFileName[SUBST_MAX_FNAME_LEN-1] = '\0'; 00103 } 00104 _bCacheIfPossible = bCacheIfPossible; 00105 }; 00106 char* _pCmdStr; 00107 int _cmdType; 00108 CmdCallbackType _callback; 00109 char _substFileName[SUBST_MAX_FNAME_LEN]; 00110 bool _bCacheIfPossible; 00111 }; 00112 00113 const int HTTPD_MAX_HDR_LENGTH = 255; 00114 // The FRDM-K64F has more memory than the LPC1768 so allow a larger buffer 00115 #if defined(MCU_MK64F12) 00116 const int HTTPD_MAX_REQ_LENGTH = 2048; 00117 #warning("TCP Request Length 2048") 00118 #elif defined(TARGET_ARCH_BLE) 00119 const int HTTPD_MAX_REQ_LENGTH = 1024; 00120 #warning("TCP Request Length 1024") 00121 #else 00122 const int HTTPD_MAX_REQ_LENGTH = 1024; 00123 #warning("TCP Request Length 1024") 00124 #endif 00125 00126 class TCPSocketServer; 00127 class TCPSocketConnection; 00128 class rtos::Mutex; 00129 00130 class RdWebServer 00131 { 00132 public : 00133 static const int METHOD_OTHER = 0; 00134 static const int METHOD_GET = 1; 00135 static const int METHOD_POST = 2; 00136 static const int METHOD_OPTIONS = 3; 00137 RdWebServer(TCPSocketServer& tcpServerSocket, rtos::Mutex* pSdCardMutex = NULL); 00138 virtual ~RdWebServer(); 00139 00140 bool init(int port, DigitalOut* pStatusLed, char* pBaseWebFolder); 00141 void run(); 00142 void addCommand(char* pCmdStr, int cmdType, CmdCallbackType callback = NULL, char* substFileName = NULL, bool cacheIfPossible = false); 00143 00144 static unsigned char* getPayloadDataFromMsg(char* msgBuf, int msgLen, int& payloadLen); 00145 static int getContentLengthFromMsg(char* msgBuf); 00146 00147 private : 00148 int _port; 00149 DigitalOut* _pStatusLed; 00150 TCPSocketServer& _serverSocket; 00151 bool _initOk; 00152 RdWebServerCmdDef* _pWebServerCmds[MAX_WEB_SERVER_CMDS]; 00153 int _numWebServerCmds; 00154 RdFileCacheEntry* _pWebServerCachedFiles[MAX_WEB_SERVER_CACHED_FILES]; 00155 int _numWebServerCachedFiles; 00156 bool extractCmdArgs(char* buf, char* pCmdStr, int maxCmdStrLen, char* pArgStr, int maxArgStrLen, int& contentLen); 00157 char* _pBaseWebFolder; 00158 char _httpHeader[HTTPD_MAX_HDR_LENGTH+1]; 00159 char _buffer[HTTPD_MAX_REQ_LENGTH+1]; 00160 int _bufferReceivedLen; 00161 00162 bool handleLocalFileRequest(char* cmdStr, char* argStr, TCPSocketConnection &client, bool bCacheIfPossible); 00163 bool handleSDFileRequest(char* cmdStr, char* argStr, TCPSocketConnection &client); 00164 void handleCGIRequest(char* pUriStr, char* pQueryStr); 00165 void sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &client); 00166 bool handleReceivedHttp(TCPSocketConnection &client); 00167 void formHTTPHeader(const char* rsltCode, const char* contentType, int contentLen); 00168 00169 // Settings - see the constructor 00170 bool _blockingOnAccept; 00171 bool _blockingOnReceive; 00172 int _timeoutOnBlocking; 00173 bool _closeConnAfterSend; 00174 bool _closeConnOnReceiveFail; 00175 00176 // Handling of split payloads on receipt (e.g. POST) 00177 int _curSplitPayloadPos; 00178 char _curCmdStr[MAX_CMDSTR_LEN]; 00179 char _curArgStr[MAX_ARGSTR_LEN]; 00180 int _curContentLen; 00181 int _curHttpMethod; 00182 RdWebServerCmdDef* _curWebServerCmdDef; 00183 00184 // Mutex for SD card access (if supplied in constructor) 00185 Mutex* _pSdCardMutex; 00186 }; 00187 00188 #endif
Generated on Fri Jul 15 2022 15:39:19 by
