A simple web server mainly based on ideas from Jasper Schuurmans Netduino web server
Dependents: RdBlindsServer SpideyWallWeb RdGasUseMonitor
A fast and reliable web server for MBED! http://robdobson.com/2015/08/a-reliable-mbed-webserver/
It has a very neat way to implement REST commands and can serve files from local storage (on LPC1768 for instance) and from SD cards. It also has a caching facility which is particularly useful for serving files from local storage.
The server can be run in the main() thread (and has a sub-2ms response time if this is done) or in a mbed-rtos thread which increases the response time to (a still respectable) 30ms or so.
The latest project that uses this is here - https://developer.mbed.org/users/Bobty/code/SpideyWallWeb/
int main (void)
{
// Ethernet interface
EthernetInterface::init();
// Connect ethernet
EthernetInterface::connect();
// Init the web server
pc.printf("Starting web server\r\n");
char* baseWebFolder = "/sd/"; // should be /sd/ for SDcard files - not used for local file system
RdWebServer webServer;
// Add commands to handle the home page and favicon
webServer.addCommand("", RdWebServerCmdDef::CMD_LOCALFILE, NULL, "index.htm", true);
webServer.addCommand("favicon.ico", RdWebServerCmdDef::CMD_LOCALFILE, NULL, NULL, true);
// Add the lightwall control commands
webServer.addCommand("name", RdWebServerCmdDef::CMD_CALLBACK, &lightwallGetSystemName);
webServer.addCommand("clear", RdWebServerCmdDef::CMD_CALLBACK, &lightwallClear);
webServer.addCommand("rawfill", RdWebServerCmdDef::CMD_CALLBACK, &lightwallRawFill);
webServer.addCommand("fill", RdWebServerCmdDef::CMD_CALLBACK, &lightwallFill);
webServer.addCommand("showleds", RdWebServerCmdDef::CMD_CALLBACK, &lightwallShowLeds);
// Start the server
webServer.init(WEBPORT, &led4, baseWebFolder);
webServer.run();
}
// Get system name - No arguments required
char* lightwallGetSystemName(int method, char*cmdStr, char* argStr, char* msgBuffer, int msgLen,
int contentLen, unsigned char* pPayload, int payloadLen, int splitPayloadPos)
{
// Perform any required actions here ....
// ...
// Return the system name
return systemName;
}
This server was originally based on a Netduino web server from Jasper Schuurmans but has been optimised for speed.
Revision 15:0865fa4b046a, committed 2015-05-05
- Comitter:
- Bobty
- Date:
- Tue May 05 20:27:33 2015 +0000
- Parent:
- 14:4b83670854f0
- Child:
- 16:0248bbfdb6c1
- Commit message:
- Pared back for work on stability - ok on LPC1768
Changed in this revision
| RdWebServer.cpp | Show annotated file Show diff for this revision Revisions of this file |
| RdWebServer.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/RdWebServer.cpp Tue May 05 15:05:44 2015 +0000
+++ b/RdWebServer.cpp Tue May 05 20:27:33 2015 +0000
@@ -1,5 +1,5 @@
/* RdWebServer.cpp
- Rob Dobson 2013
+ Rob Dobson 2013-2015
Inspired by Jasper Schuurmans multi-threaded web server for Netduino http://www.schuurmans.cc/multi-threaded-web-server-for-netduino-plus
More details at http://robdobson.com/2013/10/moving-my-window-shades-control-to-mbed/
*/
@@ -8,14 +8,14 @@
#include "RdWebServer.h"
-#define MAX_CMDSTR_LEN 100
-#define MAX_ARGSTR_LEN 100
-#define MAX_FILENAME_LEN (MAX_ARGSTR_LEN + 20)
-#define MAX_MIMETYPE_LEN 50
+const int MAX_CMDSTR_LEN = 100;
+const int MAX_ARGSTR_LEN = 100;
+const int MAX_FILENAME_LEN = (MAX_ARGSTR_LEN + 20);
+const int MAX_MIMETYPE_LEN = 50;
RdWebServer::RdWebServer()
{
- _serverIsListening = false;
+ _initOk = false;
_pStatusLed = NULL;
}
@@ -28,38 +28,164 @@
bool RdWebServer::init(int port, DigitalOut* pStatusLed, char* pBaseWebFolder)
{
+ // Settings
_port = port;
_pStatusLed = pStatusLed;
_pBaseWebFolder = pBaseWebFolder;
-
- _socketSrv.set_blocking(true);
- //setup tcp socket
- if(_socketSrv.bind(port)< 0)
+ // Setup tcp socket
+ _serverSocket.set_blocking(true);
+ if(_serverSocket.bind(port)< 0)
{
RD_WARN("TCP server bind fail\n\r");
return false;
}
- else
- {
- RD_DBG("TCP server bind success\n\r");
- _serverIsListening = true;
- }
-
- if(_socketSrv.listen(1) < 0)
+ if(_serverSocket.listen(1) < 0)
{
RD_WARN("TCP server listen fail\n\r");
return false;
}
- else
- {
- RD_INFO("TCP server is listening...\r\n");
- }
-
+ RD_INFO("TCP server is listening...\r\n");
+ _initOk = true;
return true;
}
-bool RdWebServer::handleReceivedHttp(TCPSocketConnection &client)
+void RdWebServer::run()
+{
+ // Check initialised ok
+ if (!_initOk)
+ return;
+
+ bool blockingOnAccept = true;
+ bool blockingOnReceive = true;
+ int timeoutOnBlocking = 2000;
+ const char* closeConnStr = "Connection: Close\r\n";
+ bool closeConnAfterSend = false;
+ bool closeConnOnReceiveFail = true;
+
+ // Start accepting connections
+ while (true)
+ {
+ TCPSocketConnection clientSocketConn;
+ // Accept connection if available
+ RD_INFO("Waiting for TCP connection\r\n");
+ clientSocketConn.set_blocking(blockingOnAccept, timeoutOnBlocking);
+ if(_serverSocket.accept(clientSocketConn)<0)
+ {
+ RD_WARN("TCP Socket failed to accept connection\n\r");
+ continue;
+ }
+
+ // Connection
+ RD_INFO("Connection from IP: %s\n\r", clientSocketConn.get_address());
+ if (_pStatusLed != NULL)
+ *_pStatusLed = true;
+
+ // While connected
+ bool forcedClosed = false;
+ while(clientSocketConn.is_connected() && !forcedClosed)
+ {
+ // Receive data
+ clientSocketConn.set_blocking(blockingOnReceive, timeoutOnBlocking);
+ int rxLen = clientSocketConn.receive(_buffer, HTTPD_MAX_REQ_LENGTH);
+ if (rxLen == -1)
+ {
+ RD_DBG("clientSocketConn.receive() returned %d\r\n", rxLen);
+ if (closeConnOnReceiveFail)
+ {
+ int closeRet = clientSocketConn.close();
+ RD_DBG("Failed receive connection close() ret %d is connected %d\r\n", closeRet, clientSocketConn.is_connected());
+ forcedClosed = true;
+ }
+ continue;
+ }
+ if (rxLen == 0)
+ {
+ RD_DBG("clientSocketConn.receive() returned %d - ignoring\r\n", rxLen);
+ continue;
+ }
+ if (rxLen > HTTPD_MAX_REQ_LENGTH)
+ {
+ RD_DBG("clientSocketConn.receive() returned %d - too long\r\n", rxLen);
+ continue;
+ }
+
+ RD_DBG("Received len %d\r\n", rxLen);
+ _buffer[rxLen] = '\0';
+ RD_DBG("%s\r\n", _buffer);
+
+ // Send a response
+ char* content = "HELLO\r\n";
+ int sz = strlen(content);
+ sprintf(_httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n%s\r\n", sz, closeConnAfterSend ? closeConnStr : "");
+ int sentRet = clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+ int sentRet2 = clientSocketConn.send(content, strlen(content));
+
+ RD_DBG("Sent %s header ret %d content ret %d now connected %d\r\n", content, sentRet, sentRet2, clientSocketConn.is_connected());
+
+ if (closeConnAfterSend)
+ {
+ int closeRet = clientSocketConn.close();
+ RD_DBG("After send connection close() ret %d\r\n", closeRet);
+ }
+ }
+ }
+}
+
+// connectLimitTimer.reset();
+// connectLimitTimer.start();
+// while(true)
+// {
+// // Check connection timer - 10 seconds timeout on HTTP operation
+// if (connectLimitTimer.read() >= 10)
+// {
+// RD_WARN("Connection timed out\n\r");
+// break;
+// }
+// // Get received data
+// int rxLen = clientSocketConn.receive(_buffer, HTTPD_MAX_REQ_LENGTH);
+// if (rxLen == -1)
+// {
+// RD_WARN("Nothing received\n\r");
+// continue;
+// }
+// else if (rxLen == 0)
+// {
+// RD_WARN("received buffer is empty.\n\r");
+// break;
+// }
+// else if (rxLen > HTTPD_MAX_REQ_LENGTH)
+// {
+// sprintf(_httpHeader,"HTTP/1.1 413 Request Entity Too Large \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
+// clientSocketConn.send_all(_httpHeader,strlen(_httpHeader));
+// clientSocketConn.send_all(_buffer, rxLen);
+// break;
+// }
+// _buffer[rxLen] = '\0';
+//
+// // Handle buffer
+// if (handleReceivedHttp(clientSocketConn))
+// {
+// break;
+// }
+// else
+// {
+// connectLimitTimer.reset();
+// connectLimitTimer.start();
+// }
+// }
+//
+// // Connection now closed
+// RD_INFO("Connection closed ...\r\n");
+// clientSocketConn.close();
+// if (_pStatusLed != NULL)
+// *_pStatusLed = false;
+// }
+//
+// }
+//}
+//
+bool RdWebServer::handleReceivedHttp(TCPSocketConnection &clientSocketConn)
{
bool closeConn = true;
RD_DBG("Received Data: %d\n\r\n\r%.*s\n\r",strlen(_buffer),strlen(_buffer),_buffer);
@@ -86,36 +212,40 @@
if ((*it)->_cmdType == RdWebServerCmdDef::CMD_CALLBACK)
{
char* respStr = ((*it)->_callback)(method, cmdStr, argStr);
- client.send_all(respStr, strlen(respStr));
+ clientSocketConn.send_all(respStr, strlen(respStr));
}
else if ((*it)->_cmdType == RdWebServerCmdDef::CMD_LOCALFILE)
{
+#ifdef SUPPORT_LOCAL_FILE_CACHE
if ((*it)->_substFileName[0] != '\0')
{
char combinedFileName[MAX_FILENAME_LEN];
strcpy(combinedFileName, (*it)->_substFileName);
if (combinedFileName[strlen(combinedFileName)-1] == '*')
strcpy(combinedFileName+strlen(combinedFileName)-1, argStr);
- handleLocalFileRequest(combinedFileName, argStr, client, _httpHeader, (*it)->_bCacheIfPossible);
+ handleLocalFileRequest(combinedFileName, argStr, clientSocketConn, _httpHeader, (*it)->_bCacheIfPossible);
}
else
+#endif
{
- handleLocalFileRequest(cmdStr, argStr, client, _httpHeader, (*it)->_bCacheIfPossible);
+ handleLocalFileRequest(cmdStr, argStr, clientSocketConn, _httpHeader, (*it)->_bCacheIfPossible);
}
}
else if ((*it)->_cmdType == RdWebServerCmdDef::CMD_SDORUSBFILE)
{
+#ifdef SUPPORT_LOCAL_FILE_CACHE
if ((*it)->_substFileName[0] != '\0')
{
char combinedFileName[MAX_FILENAME_LEN];
strcpy(combinedFileName, (*it)->_substFileName);
if (combinedFileName[strlen(combinedFileName)-1] == '*')
strcpy(combinedFileName+strlen(combinedFileName)-1, argStr);
- closeConn = handleSDFileRequest(combinedFileName, argStr, client, _httpHeader);
+ closeConn = handleSDFileRequest(combinedFileName, argStr, clientSocketConn, _httpHeader);
}
else
+#endif
{
- closeConn = handleSDFileRequest(cmdStr, argStr, client, _httpHeader);
+ closeConn = handleSDFileRequest(cmdStr, argStr, clientSocketConn, _httpHeader);
}
}
break;
@@ -123,89 +253,17 @@
}
// If command not found see if it is a local file
if (!cmdFound)
- closeConn = handleSDFileRequest(cmdStr, argStr, client, _httpHeader);
+ closeConn = handleSDFileRequest(cmdStr, argStr, clientSocketConn, _httpHeader);
}
return closeConn;
}
-void RdWebServer::run()
-{
- TCPSocketConnection client;
- Timer connectLimitTimer;
-
- while (isListening())
- {
- RD_INFO("Waiting for TCP connection\r\n");
- if(_socketSrv.accept(client)<0)
- {
- RD_WARN("TCP Socket failed to accept connection\n\r");
- }
- else
- {
- client.set_blocking(false, 2000);
- RD_INFO("Connection from IP: %s\n\r",client.get_address());
- if (_pStatusLed != NULL)
- *_pStatusLed = true;
-
- connectLimitTimer.reset();
- connectLimitTimer.start();
- while(true)
- {
- // Check connection timer - 10 seconds timeout on HTTP operation
- if (connectLimitTimer.read() >= 10)
- {
- RD_WARN("Connection timed out\n\r");
- break;
- }
- // Get received data
- int rxLen = client.receive(_buffer, HTTPD_MAX_REQ_LENGTH);
- if (rxLen == -1)
- {
- RD_WARN("Nothing received\n\r");
- continue;
- }
- else if (rxLen == 0)
- {
- RD_WARN("received buffer is empty.\n\r");
- break;
- }
- else if (rxLen > HTTPD_MAX_REQ_LENGTH)
- {
- sprintf(_httpHeader,"HTTP/1.1 413 Request Entity Too Large \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
- client.send_all(_httpHeader,strlen(_httpHeader));
- client.send_all(_buffer, rxLen);
- break;
- }
- _buffer[rxLen] = '\0';
-
- // Handle buffer
- if (handleReceivedHttp(client))
- {
- break;
- }
- else
- {
- connectLimitTimer.reset();
- connectLimitTimer.start();
- }
- }
-
- // Connection now closed
- RD_INFO("Connection closed ...\r\n");
- client.close();
- if (_pStatusLed != NULL)
- *_pStatusLed = false;
- }
-
- }
-}
-
void RdWebServer::addCommand(char* pCmdStr, int cmdType, CmdCallbackType callback, char* substFileName, bool cacheIfPossible)
{
_commands.push_back(new RdWebServerCmdDef(pCmdStr, cmdType, callback, substFileName, cacheIfPossible));
}
-bool RdWebServer::handleSDFileRequest(char* inFileName, char* argStr, TCPSocketConnection &client, char* httpHeader)
+bool RdWebServer::handleSDFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn, char* httpHeader)
{
bool closeConn = true;
const int HTTPD_MAX_FNAME_LENGTH = 127;
@@ -222,21 +280,21 @@
if (d != NULL)
{
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
sprintf(httpHeader,"<html><head><title>Directory Listing</title></head><body><h1>%s</h1><ul>", inFileName);
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
struct dirent *p;
while((p = readdir(d)) != NULL)
{
RD_INFO("%s\r\n", p->d_name);
sprintf(httpHeader,"<li>%s</li>", p->d_name);
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
}
}
closedir(d);
RD_DBG("Directory closed\n");
sprintf(httpHeader,"</ul></body></html>");
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
}
else
#endif
@@ -249,7 +307,7 @@
{
RD_WARN("Filename %s not found\r\n", filename);
sprintf(httpHeader,"HTTP/1.1 404 Not Found \r\nContent-Type: text\r\nContent-Length: 0\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
closeConn = false;
}
else
@@ -259,7 +317,7 @@
int sz = ftell(fp);
fseek(fp, 0L, SEEK_SET);
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n", sz);
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
// MIME type
char *pDot = strrchr(filename, '.');
char mimeType[MAX_MIMETYPE_LEN+1];
@@ -269,16 +327,16 @@
strcpy(mimeType, "Content-Type: text/css\r\n");
if (pDot && !strcmp(pDot, ".js"))
strcpy(mimeType, "Content-Type: application/javascript\r\n");
-// client.send_all(mimeType,strlen(mimeType));
+// clientSocketConn.send_all(mimeType,strlen(mimeType));
RD_INFO("MIME TYPE %s", mimeType);
// Read file in blocks and send
int rdCnt = 0;
char fileBuf[1024];
while ((rdCnt = fread(fileBuf, sizeof( char ), 1024, fp)) == 1024)
{
- client.send_all(fileBuf, rdCnt);
+ clientSocketConn.send_all(fileBuf, rdCnt);
}
- client.send_all(fileBuf, rdCnt);
+ clientSocketConn.send_all(fileBuf, rdCnt);
fclose(fp);
closeConn = false;
}
@@ -286,11 +344,13 @@
return closeConn;
}
-void RdWebServer::sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &client, char* httpHeader)
+#ifdef SUPPORT_LOCAL_FILE_CACHE
+
+void RdWebServer::sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &clientSocketConn, char* httpHeader)
{
RD_INFO("Sending file %s from cache %d bytes\r\n", pCacheEntry->_fileName, pCacheEntry->_nFileLen);
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
char* pMem = pCacheEntry->_pFileContent;
int nLenLeft = pCacheEntry->_nFileLen;
int blkSize = 2048;
@@ -298,13 +358,14 @@
{
if (blkSize > nLenLeft)
blkSize = nLenLeft;
- client.send_all(pMem, blkSize);
+ clientSocketConn.send_all(pMem, blkSize);
pMem += blkSize;
nLenLeft -= blkSize;
}
}
+#endif
-void RdWebServer::handleLocalFileRequest(char* inFileName, char* argStr, TCPSocketConnection &client, char* httpHeader, bool bCacheIfPossible)
+void RdWebServer::handleLocalFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn, char* httpHeader, bool bCacheIfPossible)
{
#ifdef SUPPORT_LOCAL_FILESYSTEM
@@ -327,7 +388,7 @@
{
if ((*it)->_bCacheValid)
{
- sendFromCache(*it, client, httpHeader);
+ sendFromCache(*it, clientSocketConn, httpHeader);
return;
}
bTryToCache = false; // don't try to cache as cacheing must have already failed
@@ -345,7 +406,7 @@
_cachedFiles.push_back(pCacheEntry);
if (bCacheSuccess)
{
- sendFromCache(pCacheEntry, client, httpHeader);
+ sendFromCache(pCacheEntry, clientSocketConn, httpHeader);
return;
}
}
@@ -359,21 +420,21 @@
{
RD_WARN("Local file %s not found\r\n", localFilename);
sprintf(httpHeader,"HTTP/1.1 404 Not Found \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
- client.send_all(reqFileNameStr,strlen(reqFileNameStr));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(reqFileNameStr,strlen(reqFileNameStr));
}
else
{
RD_INFO("Sending file %s from disk\r\n", localFilename);
sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
int rdCnt = 0;
char fileBuf[2000];
while ((rdCnt = fread(fileBuf, sizeof( char ), 2000, fp)) == 2000)
{
- client.send_all(fileBuf, rdCnt);
+ clientSocketConn.send_all(fileBuf, rdCnt);
}
- client.send_all(fileBuf, rdCnt);
+ clientSocketConn.send_all(fileBuf, rdCnt);
fclose(fp);
}
@@ -381,12 +442,14 @@
RD_WARN("Local file system not supported\r\n");
sprintf(httpHeader,"HTTP/1.1 404 Not Found \r\nContent-Type: text\r\nConnection: Close\r\n\r\n");
- client.send_all(httpHeader,strlen(httpHeader));
- client.send_all(inFileName,strlen(inFileName));
+ clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+ clientSocketConn.send_all(inFileName,strlen(inFileName));
#endif
}
+#ifdef SUPPORT_LOCAL_FILE_CACHE
+
bool RdFileCacheEntry::readLocalFileIntoCache(char* fileName)
{
#ifdef SUPPORT_LOCAL_FILESYSTEM
@@ -443,6 +506,8 @@
#endif
}
+#endif
+
bool RdWebServer::extractCmdArgs(char* buf, char* pCmdStr, int maxCmdStrLen, char* pArgStr, int maxArgStrLen)
{
*pCmdStr = '\0';
--- a/RdWebServer.h Tue May 05 15:05:44 2015 +0000
+++ b/RdWebServer.h Tue May 05 20:27:33 2015 +0000
@@ -1,5 +1,5 @@
/* RdWebServer.h
- Rob Dobson 2013
+ Rob Dobson 2013-2015
Inspired by Jasper Schuurmans multi-threaded web server for Netduino http://www.schuurmans.cc/multi-threaded-web-server-for-netduino-plus
*/
#ifndef RD_WEB_SERVER
@@ -52,9 +52,12 @@
//#define SUPPORT_LOCAL_FILESYSTEM 1
//#define SUPPORT_FOLDER_VIEW 1
+//#define SUPPORT_LOCAL_FILE_CACHE 1
extern RawSerial pc;
+#ifdef SUPPORT_LOCAL_FILE_CACHE
+
class RdFileCacheEntry
{
public:
@@ -78,6 +81,8 @@
int _nFileLen;
};
+#endif
+
typedef char* (*CmdCallbackType)(int method, char*cmdStr, char* argStr);
class RdWebServerCmdDef
@@ -86,23 +91,27 @@
static const int CMD_LOCALFILE = 1;
static const int CMD_CALLBACK = 2;
static const int CMD_SDORUSBFILE = 3;
- RdWebServerCmdDef(char* pStr, int cmdType, CmdCallbackType callback, char* substFileName, bool bCacheIfPossible)
+ RdWebServerCmdDef(char* pStr, int cmdType, CmdCallbackType callback, char* subst8dot3FileName = NULL, bool bCacheIfPossible = false)
{
_pCmdStr = pStr;
_cmdType = cmdType;
_callback = callback;
- _substFileName[0] = '\0';
- if (substFileName != NULL)
+#ifdef SUPPORT_LOCAL_FILE_CACHE
+ _subst8dot3FileName[0] = '\0';
+ if (subst8dot3FileName != NULL)
{
- strncpy(_substFileName, substFileName, RdFileCacheEntry::CACHE_MAX_FNAME_LEN);
- _substFileName[RdFileCacheEntry::CACHE_MAX_FNAME_LEN-1] = '\0';
+ strncpy(_subst8dot3FileName, subst8dot3FileName, RdFileCacheEntry::CACHE_MAX_FNAME_LEN);
+ _subst8dot3FileName[RdFileCacheEntry::CACHE_MAX_FNAME_LEN-1] = '\0';
}
+#endif
_bCacheIfPossible = bCacheIfPossible;
};
char* _pCmdStr;
int _cmdType;
CmdCallbackType _callback;
- char _substFileName[RdFileCacheEntry::CACHE_MAX_FNAME_LEN];
+#ifdef SUPPORT_LOCAL_FILE_CACHE
+ char _subst8dot3FileName[RdFileCacheEntry::CACHE_MAX_FNAME_LEN];
+#endif
bool _bCacheIfPossible;
};
@@ -120,20 +129,17 @@
bool init(int port, DigitalOut* pStatusLed, char* pBaseWebFolder);
void run();
- bool isListening()
- {
- return _serverIsListening;
- };
-
void addCommand(char* pCmdStr, int cmdType, CmdCallbackType callback = NULL, char* substFileName = NULL, bool cacheIfPossible = false);
private :
int _port;
DigitalOut* _pStatusLed;
- TCPSocketServer _socketSrv;
- bool _serverIsListening;
+ TCPSocketServer _serverSocket;
+ bool _initOk;
std::vector<RdWebServerCmdDef*> _commands;
+#ifdef SUPPORT_LOCAL_FILE_CACHE
std::vector<RdFileCacheEntry*> _cachedFiles;
+#endif
bool extractCmdArgs(char* buf, char* pCmdStr, int maxCmdStrLen, char* pArgStr, int maxArgStrLen);
char* _pBaseWebFolder;
char _httpHeader[HTTPD_MAX_HDR_LENGTH+1];
@@ -142,7 +148,9 @@
void handleLocalFileRequest(char* cmdStr, char* argStr, TCPSocketConnection &client, char* httpHeader, bool bCacheIfPossible);
bool handleSDFileRequest(char* cmdStr, char* argStr, TCPSocketConnection &client, char* httpHeader);
void handleCGIRequest(char* pUriStr, char* pQueryStr);
+#ifdef SUPPORT_LOCAL_FILE_CACHE
void sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &client, char* httpHeader);
+#endif
bool handleReceivedHttp(TCPSocketConnection &client);
};