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:
17:080f2bed8b36
Parent:
16:0248bbfdb6c1
Child:
18:5de680c4cfcb
--- a/RdWebServer.cpp	Tue May 05 22:14:16 2015 +0000
+++ b/RdWebServer.cpp	Mon May 11 11:17:15 2015 +0000
@@ -4,14 +4,13 @@
    More details at http://robdobson.com/2013/10/moving-my-window-shades-control-to-mbed/
 */
 
-#define RDWEB_DEBUG 5
+//#define RDWEB_DEBUG 5
 
 #include "RdWebServer.h"
 
 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()
 {
@@ -33,6 +32,23 @@
     _pStatusLed = pStatusLed;
     _pBaseWebFolder = pBaseWebFolder;
 
+    // The sample web server on MBED site turns off blocking after the accept has happened
+    // I've tried this but it doesn't seem to yield a reliable server
+    _blockingOnAccept = true;
+    _blockingOnReceive = true;
+    
+    // This is the same as the default in the socket.cpp file
+    _timeoutOnBlocking = 1500;
+    
+    // Currently tested using close connection after send with a single file which works fine
+    // If closeConnAfterSend is set false then the socket connection remains open and only
+    // one client can access the server at a time
+    // Need to test with the closeConnAfterSend seetting true when trying to download multiple files
+    // for a website as previous experience would indicate that requests might be missed in this scenario
+    // although all other settings may not have been the same
+    _closeConnAfterSend = true;
+    _closeConnOnReceiveFail = true;
+
     // Setup tcp socket
     _serverSocket.set_blocking(true);
     if(_serverSocket.bind(port)< 0) 
@@ -56,31 +72,13 @@
     if (!_initOk)
         return;
     
-    // The sample web server on MBED site turns off blocking after the accept has happened
-    // I've tried this but it doesn't seem to yield a reliable server
-    bool blockingOnAccept = true;
-    bool blockingOnReceive = true;
-    
-    // This is the same as the default in the socket.cpp file
-    int timeoutOnBlocking = 1500;
-    
-    // Currently tested using close connection after send with a single file which works fine
-    // If closeConnAfterSend is set false then the socket connection remains open and only
-    // one client can access the server at a time
-    // Need to test with the closeConnAfterSend seetting true when trying to download multiple files
-    // for a website as previous experience would indicate that requests might be missed in this scenario
-    // although all other settings may not have been the same
-    bool closeConnAfterSend = true;
-    bool closeConnOnReceiveFail = true;
-    const char* closeConnStr = "Connection: Close\r\n";
-    
     // Start accepting connections
     while (true)
     {
         TCPSocketConnection clientSocketConn;
         // Accept connection if available
         RD_INFO("Waiting for TCP connection\r\n");
-        clientSocketConn.set_blocking(blockingOnAccept, timeoutOnBlocking);
+        clientSocketConn.set_blocking(_blockingOnAccept, _timeoutOnBlocking);
         if(_serverSocket.accept(clientSocketConn)<0) 
         {
             RD_WARN("TCP Socket failed to accept connection\n\r");
@@ -97,12 +95,12 @@
         while(clientSocketConn.is_connected() && !forcedClosed)
         {
             // Receive data
-            clientSocketConn.set_blocking(blockingOnReceive, timeoutOnBlocking);
+            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)
+                if (_closeConnOnReceiveFail)
                 {
                     int closeRet = clientSocketConn.close();
                     RD_DBG("Failed receive connection close() ret %d is connected %d\r\n", closeRet, clientSocketConn.is_connected());
@@ -118,6 +116,9 @@
             if (rxLen > HTTPD_MAX_REQ_LENGTH)
             {
                 RD_DBG("clientSocketConn.receive() returned %d - too long\r\n", rxLen);
+                formHTTPHeader("413 Request Entity Too Large", "text/plain", 0);
+//                sprintf(_httpHeader,"HTTP/1.1 413 Request Entity Too Large \r\nContent-Type: text\r\nContent-Length: 0\r\n%s\r\n", closeConnAfterSend ? closeConnStr : "");
+                int sentRet = clientSocketConn.send(_httpHeader,strlen(_httpHeader));
                 continue;
             }
         
@@ -126,15 +127,25 @@
             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));
+//            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());
+
+                // Handle received message
+                if (handleReceivedHttp(clientSocketConn))
+                {
+                    // OK
+                }
+                else
+                {
+                    // FAIL
+                }
             
-            RD_DBG("Sent %s header ret %d content ret %d now connected %d\r\n", content, sentRet, sentRet2, clientSocketConn.is_connected());
-            
-            if (closeConnAfterSend)
+            // Close connection if required
+            if (_closeConnAfterSend)
             {
                 int closeRet = clientSocketConn.close();
                 RD_DBG("After send connection close() ret %d is connected %d\r\n", closeRet, clientSocketConn.is_connected());
@@ -169,8 +180,8 @@
 //                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);
+//                    clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+//                    clientSocketConn.send(_buffer, rxLen);
 //                    break;
 //                }
 //                _buffer[rxLen] = '\0';
@@ -199,7 +210,7 @@
 //
 bool RdWebServer::handleReceivedHttp(TCPSocketConnection &clientSocketConn)
 {
-    bool closeConn = true;
+    bool handledOk = false;
     RD_DBG("Received Data: %d\n\r\n\r%.*s\n\r",strlen(_buffer),strlen(_buffer),_buffer);
     int method = METHOD_OTHER;
     if (strncmp(_buffer, "GET ", 4) == 0)
@@ -224,50 +235,37 @@
                 if ((*it)->_cmdType == RdWebServerCmdDef::CMD_CALLBACK)
                 {
                     char* respStr = ((*it)->_callback)(method, cmdStr, argStr);
-                    clientSocketConn.send_all(respStr, strlen(respStr));
+                    clientSocketConn.send(respStr, strlen(respStr));
                 }
-                else if ((*it)->_cmdType == RdWebServerCmdDef::CMD_LOCALFILE)
+                else if ( ((*it)->_cmdType == RdWebServerCmdDef::CMD_LOCALFILE) ||
+                          ((*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);
-                        handleLocalFileRequest(combinedFileName, argStr, clientSocketConn, _httpHeader, (*it)->_bCacheIfPossible);
-                    }
+                    char combinedFileName[MAX_FILENAME_LEN];
+                    strcpy(combinedFileName, (*it)->_substFileName);
+                    if (strlen(combinedFileName) == 0)
+                        strcpy(combinedFileName, cmdStr);
+                    else if (combinedFileName[strlen(combinedFileName)-1] == '*')
+                        strcpy(combinedFileName+strlen(combinedFileName)-1, argStr);
+                    if ((*it)->_cmdType == RdWebServerCmdDef::CMD_LOCALFILE)
+                        handledOk = handleLocalFileRequest(combinedFileName, argStr, clientSocketConn, (*it)->_bCacheIfPossible);
                     else
-#endif
-                    {
-                        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, clientSocketConn, _httpHeader);
-                    }
-                    else
-#endif
-                    {
-                        closeConn = handleSDFileRequest(cmdStr, argStr, clientSocketConn, _httpHeader);
-                    }
+                        handledOk = handleSDFileRequest(combinedFileName, argStr, clientSocketConn);
+
                 }
                 break;
             }
         }
         // If command not found see if it is a local file
         if (!cmdFound)
-            closeConn = handleSDFileRequest(cmdStr, argStr, clientSocketConn, _httpHeader);
+        {
+            char combinedFileName[MAX_FILENAME_LEN];
+            strcpy(combinedFileName, cmdStr);
+            strcat(combinedFileName, "/");
+            strcat(combinedFileName, argStr);
+            handledOk = handleSDFileRequest(cmdStr, argStr, clientSocketConn);
+        }
     }
-    return closeConn;
+    return handledOk;
 }
 
 void RdWebServer::addCommand(char* pCmdStr, int cmdType, CmdCallbackType callback, char* substFileName, bool cacheIfPossible)
@@ -275,9 +273,35 @@
     _commands.push_back(new RdWebServerCmdDef(pCmdStr, cmdType, callback, substFileName, cacheIfPossible));
 }
 
-bool RdWebServer::handleSDFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn, char* httpHeader)
+void RdWebServer::formHTTPHeader(const char* rsltCode, const char* contentType, int contentLen)
+{
+    const char* closeConnStr = "\r\nConnection: Close";
+    if(contentLen != -1)
+        sprintf(_httpHeader, "HTTP/1.1 %s\r\nContent-Type: %s\r\nContent-Length: %d%s\r\n\r\n", rsltCode, contentType, contentLen, _closeConnAfterSend ? closeConnStr : "");
+    else
+        sprintf(_httpHeader, "HTTP/1.1 %s\r\nContent-Type: %s%s\r\n\r\n", rsltCode, contentType, _closeConnAfterSend ? closeConnStr : "");
+}
+    
+char* getMimeTypeStr(char* filename)
 {
-    bool closeConn = true;
+    char* mimeType = "text/plain";
+    char *pDot = strrchr(filename, '.');
+    if (pDot && (!strcmp(pDot, ".html") || !strcmp(pDot, ".htm")))
+        mimeType = "text/html";
+    else if (pDot && !strcmp(pDot, ".css"))
+        mimeType = "text/css";
+    else if (pDot && !strcmp(pDot, ".js"))
+        mimeType = "application/javascript";
+    else if (pDot && !strcmp(pDot, ".png"))
+        mimeType = "image/png";
+    else if (pDot && (!strcmp(pDot, ".jpeg") || !strcmp(pDot, ".jpeg")))
+        mimeType = "image/jpeg";
+    return mimeType;
+}
+    
+bool RdWebServer::handleSDFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn)
+{
+    bool handledOk = false;
     const int HTTPD_MAX_FNAME_LENGTH = 127;
     char filename[HTTPD_MAX_FNAME_LENGTH+1];
     
@@ -291,22 +315,23 @@
         DIR *d = opendir(filename);
         if (d != NULL) 
         {
-            sprintf(httpHeader,"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nConnection: Close\r\n\r\n");
-            clientSocketConn.send_all(httpHeader,strlen(httpHeader));
-            sprintf(httpHeader,"<html><head><title>Directory Listing</title></head><body><h1>%s</h1><ul>", inFileName);
-            clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+            formHTTPHeader("200 OK", "text/html", -1);
+            clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+            sprintf(_httpHeader,"<html><head><title>Directory Listing</title></head><body><h1>%s</h1><ul>", inFileName);
+            clientSocketConn.send(_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);
-                clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+                sprintf(_httpHeader,"<li>%s</li>", p->d_name);
+                clientSocketConn.send(_httpHeader,strlen(_httpHeader));
             }
         }
         closedir(d);
         RD_DBG("Directory closed\n");
-        sprintf(httpHeader,"</ul></body></html>");
-        clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+        sprintf(_httpHeader,"</ul></body></html>");
+        clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+        handledOk = true;
     }
     else
 #endif
@@ -318,51 +343,49 @@
         if (fp == NULL)
         {
             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");
-            clientSocketConn.send_all(httpHeader,strlen(httpHeader));
-            closeConn = false;
+            formHTTPHeader("404 Not Found", "text/plain", 0);
+            clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+            handledOk = true;
         }
         else
         {
             RD_INFO("Sending file %s\r\n", filename);
+            // Find file length
             fseek(fp, 0L, SEEK_END);
             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);
-            clientSocketConn.send_all(httpHeader,strlen(httpHeader));
-            // MIME type
-            char *pDot = strrchr(filename, '.');
-            char mimeType[MAX_MIMETYPE_LEN+1];
-            if (pDot && (!strcmp(pDot, ".html") || !strcmp(pDot, ".htm")))
-                strcpy(mimeType, "Content-Type: text/html\r\n");
-            else if (pDot && !strcmp(pDot, ".css"))
-                strcpy(mimeType, "Content-Type: text/css\r\n");
-            if (pDot && !strcmp(pDot, ".js"))
-                strcpy(mimeType, "Content-Type: application/javascript\r\n");
-//            clientSocketConn.send_all(mimeType,strlen(mimeType));
+            // Get mime type
+            char* mimeType = getMimeTypeStr(filename);
             RD_INFO("MIME TYPE %s", mimeType);
+            // Form header   
+            formHTTPHeader("200 OK", mimeType, sz);
+            clientSocketConn.send(_httpHeader,strlen(_httpHeader));
             // Read file in blocks and send
             int rdCnt = 0;
             char fileBuf[1024];
             while ((rdCnt = fread(fileBuf, sizeof( char ), 1024, fp)) == 1024) 
             {
-                clientSocketConn.send_all(fileBuf, rdCnt);
+                clientSocketConn.send(fileBuf, rdCnt);
             }
-            clientSocketConn.send_all(fileBuf, rdCnt);
+            clientSocketConn.send(fileBuf, rdCnt);
             fclose(fp);
-            closeConn = false;
+            handledOk = true;
         }
     }
-    return closeConn;
+    return handledOk;
 }
 
 #ifdef SUPPORT_LOCAL_FILE_CACHE
 
-void RdWebServer::sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &clientSocketConn, char* httpHeader)
+void RdWebServer::sendFromCache(RdFileCacheEntry* pCacheEntry, TCPSocketConnection &clientSocketConn)
 {
     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");
-    clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+    // Get mime type
+    char* mimeType = getMimeTypeStr(pCacheEntry->_fileName);
+    RD_INFO("MIME TYPE %s", mimeType);
+    // Form header
+    formHTTPHeader("200 OK", mimeType, pCacheEntry->_nFileLen);
+    clientSocketConn.send(_httpHeader,strlen(_httpHeader));
     char* pMem = pCacheEntry->_pFileContent;
     int nLenLeft = pCacheEntry->_nFileLen;
     int blkSize = 2048;
@@ -370,14 +393,14 @@
     {
         if (blkSize > nLenLeft)
             blkSize = nLenLeft;
-        clientSocketConn.send_all(pMem, blkSize);
+        clientSocketConn.send(pMem, blkSize);
         pMem += blkSize;
         nLenLeft -= blkSize;
     }
 }
 #endif
 
-void RdWebServer::handleLocalFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn, char* httpHeader, bool bCacheIfPossible)
+bool RdWebServer::handleLocalFileRequest(char* inFileName, char* argStr, TCPSocketConnection &clientSocketConn, bool bCacheIfPossible)
 {
 
 #ifdef SUPPORT_LOCAL_FILESYSTEM
@@ -401,7 +424,7 @@
                 if ((*it)->_bCacheValid)
                 {
                     sendFromCache(*it, clientSocketConn, httpHeader);
-                    return;
+                    return true;
                 }
                 bTryToCache = false; // don't try to cache as cacheing must have already failed
             }
@@ -419,7 +442,7 @@
                 if (bCacheSuccess)
                 {
                     sendFromCache(pCacheEntry, clientSocketConn, httpHeader);
-                    return;
+                    return true;
                 }
             }
         }        
@@ -431,31 +454,40 @@
     if (fp == NULL)
     {
         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");
-        clientSocketConn.send_all(httpHeader,strlen(httpHeader));
-        clientSocketConn.send_all(reqFileNameStr,strlen(reqFileNameStr));
+        formHTTPHeader("404 Not Found", "text/plain", 0);
+        clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+        return true;
     }
     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");
-        clientSocketConn.send_all(httpHeader,strlen(httpHeader));
+        // Find file length
+        fseek(fp, 0L, SEEK_END);
+        int sz = ftell(fp);
+        fseek(fp, 0L, SEEK_SET);
+        // Get mime type
+        char* mimeType = getMimeTypeStr(localFilename);
+        RD_INFO("MIME TYPE %s", mimeType);
+        // Form header   
+        formHTTPHeader("200 OK", mimeType, sz);
+        clientSocketConn.send(_httpHeader,strlen(_httpHeader));
         int rdCnt = 0;
-        char fileBuf[2000];
-        while ((rdCnt = fread(fileBuf, sizeof( char ), 2000, fp)) == 2000) 
+        while ((rdCnt = fread(_httpHeader, sizeof( char ), sizeof(_httpHeader), fp)) == sizeof(_httpHeader)) 
         {
-            clientSocketConn.send_all(fileBuf, rdCnt);
+            clientSocketConn.send(_httpHeader, rdCnt);
         }
-        clientSocketConn.send_all(fileBuf, rdCnt);
+        if (rdCnt != 0)
+            clientSocketConn.send(_httpHeader, rdCnt);
         fclose(fp);
+        return true;
     }
     
 #else
 
     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");
-    clientSocketConn.send_all(httpHeader,strlen(httpHeader));
-    clientSocketConn.send_all(inFileName,strlen(inFileName));
+    formHTTPHeader("404 Not Found", "text/plain", 0);
+    clientSocketConn.send(_httpHeader,strlen(_httpHeader));
+    return true;
 
 #endif
 }