The library with which to make your mbed a HTTP Server which just reads HTML files in the mbed and sends it to the clients.

Dependents:   httpserversample SIMPLE_WSS

Quote:

This library depends on EthernetInterface class, TCPSocketServer class and TCPSocketConnection class. These classes can be imported at EthernetInterface library. Moreover, the EthernetInterface library depends on the mbed-rtos library, so import it here.

Abstract

This is the library to make a mbed a simple HTTP server. With this library, a mbed can understand only GET requests, and can send clients htm or jpg files as a response.

Handleable Requests:

  • GET

Handleable files:

  • html
  • jpg

Note the length of the Filename

A mbed can handle only 8.3 filename (also called as "short filename" or SFN), such as index.htm (in this case, length of the filename is 5.3).

Sample Code

Running the code below, if your mbed is connected to a network, you can see an IP address of the mbed on your console. (When connecting the mbed to a PC with USB, the baud rate should be 9600)

Hello World

#include "mbed.h"
#include "HTTP_SERVER.h"
int main()
{
    HttpServer httpsvr;
    if(httpsvr.init()){
        if(httpsvr.run() == 0)
            printf("end\r\n");
        else
            printf("error end\r\n");
    }
    return 0;
}

As an example, make a index.htm like below (NOT .html; the reason is referred above) in the mbed, and access to <the IP address>/index.htm with a web browser on your PC or any terminals on the network the mbed is connected to, then you would be able to see the page.

index.htm in mbed

<!DOCTYPE html>
<html>
<head>
<title>mbed http server demo</title>
</head>
<body>
	<h1>Mbed Simple HTTP Server</h1> 
	hello world<br />
	<a href="./index.htm" terget="self">Hyper Link Test</a><br />
</body>
</html>

Files at this revision

API Documentation at this revision

Comitter:
aktk
Date:
Fri Mar 16 21:55:50 2018 +0000
Parent:
12:cbf97b865d76
Parent:
11:0ee7d100db24
Commit message:
merged

Changed in this revision

diff -r cbf97b865d76 -r b6dd6ed0060b HTTP_SERVER.cpp
--- a/HTTP_SERVER.cpp	Fri Mar 16 21:50:43 2018 +0000
+++ b/HTTP_SERVER.cpp	Fri Mar 16 21:55:50 2018 +0000
@@ -1,15 +1,39 @@
 #include "HTTP_SERVER.h"
 #include "string"
 #ifndef DEBUG
-#define DEBUG
+//#define DEBUG
 #endif
 
+namespace HTTP_SERVER
+{
 void DEBUG_PRINT_LINE(const char* arg_line)
 {
 #ifdef DEBUG
-    printf("%s",arg_line);
+    printf("(HTTP_SERVER) ")
+    printf(arg_line);
+    printf("\r\n");
 #endif
 }
+template<typename T>
+void DEBUG_PRINT_LINE(const char* arg_line, T arg_t)
+{
+#ifdef DEBUG
+    printf("(HTTP_SERVER) ");
+    printf(arg_line, arg_t);
+    printf("\r\n");
+#endif
+}
+template<typename T1, typename T2>
+void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2)
+{
+#ifdef DEBUG
+    printf("(HTTP_SERVER) ");
+    printf(arg_line, arg_t1, arg_t2);
+    printf("\r\n");
+#endif
+}
+}
+using namespace HTTP_SERVER;
 
 HttpServer::HttpServer()
 {
@@ -76,7 +100,7 @@
         }
         //  When conected
         while(tcpcon.is_connected()) {
-            DEBUG_PRINT_LINE("(HTTP_SERVER) connected\r\n");
+            printf("(HTTP_SERVER) connected\r\n");
 
             char buffer[1024]   = {0};
             char* httpmethod    = NULL;
@@ -88,92 +112,94 @@
             //
             //  Request Analysis
             //
-            DEBUG_PRINT_LINE("(HTTP_SERVER) DEBUG MODE\r\n");
+            DEBUG_PRINT_LINE("DEBUG MODE");
             switch(tcpcon.receive(buffer, 1023)) {
                 case 0:
-                    printf("(HTTP_SERVER) recieved buffer is empty.\r\n");
+                    DEBUG_PRINT_LINE("recieved buffer is empty.");
                     msger.setStatusLine(400, "No Request");
-                    if(msger.setHeaderField("Connection", "Close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
+                    if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                     httpmethod    = NULL;
                     filepath      = NULL;
                     http_ver      = NULL;
                     break;
                 case -1:
-                    printf("(HTTP_SERVER) failed to read data from client.\r\n");
+                    DEBUG_PRINT_LINE("failed to read data from client.");
                     msger.setStatusLine(500, "Internal Server Error");
-                    if(msger.setHeaderField("Connection", "Close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
+                    if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                     httpmethod    = NULL;
                     filepath      = NULL;
                     http_ver      = NULL;
                     break;
                 default:
-                    printf("(HTTP_SERVER) Recieved Data: %d\r\n-->\r\n%.*s[End of Request]\r\n",strlen(buffer),strlen(buffer),buffer);
-                    //  get HTTP method
+                    DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer));
+                    DEBUG_PRINT_LINE("-->\r\n");
+                    DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer);
+                    //  get HTTP method, File path, HTTP version
                     httpmethod = strtok(buffer," ");
-                    //  get File path
                     filepath = strtok(NULL, " ");
-                    //  get HTTP version
                     http_ver = strtok(NULL, "\r\n");
-#ifdef DEBUG
-                    printf("(HTTP_SERVER) httpmethod: %s\r\n", httpmethod);
-                    printf("(HTTP_SERVER) file path:  %s\r\n", filepath);
-                    printf("(HTTP_SERVER) http ver :  %s\r\n", http_ver);
-#endif
+                    DEBUG_PRINT_LINE("httpmethod: %s", httpmethod);
+                    DEBUG_PRINT_LINE("file path:  %s", filepath);
+                    DEBUG_PRINT_LINE("http ver :  %s", http_ver);
                     break;
             }
-            DEBUG_PRINT_LINE("\r\n"
-                             "(HTTP_SERVER) debug before response\r\n");
 
             //
             //  Response
             //
             if (strcmp(httpmethod,"GET") == 0 ) {
-                printf("(HTTP_SERVER) GET request incomming.\r\n");
+                DEBUG_PRINT_LINE("GET request incomming.");
 
                 //  file calibration
-                DEBUG_PRINT_LINE("(HTTP_SERVER) file opening\r\n");
+                DEBUG_PRINT_LINE("file opening");
                 fhandl.open(filepath,"rb");
                 if(fhandl.arrival()) {
                     msger.setStatusLine(200, "OK");
-                    if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
-                    if(msger.setHeaderField("Connection", "keep-alive"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
+                    if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))    DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                    if(msger.setHeaderField("Connection", "keep-alive"))                DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                 } else {
-                    if(msger.setStatusLine(404, "NOT FOUND"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
-                    if(msger.setHeaderField("Connection", "Close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
-                    DEBUG_PRINT_LINE("(HTTP_SERVER) NOT FOUND\r\n");
+                    if(msger.setStatusLine(404, "NOT FOUND"))                           DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                    if(msger.setHeaderField("Connection", "Close"))                     DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                    DEBUG_PRINT_LINE("NOT FOUND");
                 }
-                if(     !strcmp(fhandl.getSuffix(), "htm" )  ||
-                        !strcmp(fhandl.getSuffix(), "HTM" )  ||
-                        !strcmp(fhandl.getSuffix(), "html")  ||
-                        !strcmp(fhandl.getSuffix(), "HTML")) {
-                    if(msger.setHeaderField("Content-Type", "text/html"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
-                } else if(!strcmp(fhandl.getSuffix(), "js" )){
-                    if(msger.setHeaderField("Content-Type", "text/javascript"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
-                } else if (!strcmp(fhandl.getSuffix(), "ico" )  ) {
-                    if(msger.setHeaderField("Content-Type", "image/png"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
+                if(         !strcmp(fhandl.getSuffix(), "htm" ) ||
+                            !strcmp(fhandl.getSuffix(), "HTM" ) ||
+                            !strcmp(fhandl.getSuffix(), "html") ||
+                            !strcmp(fhandl.getSuffix(), "HTML")){
+                    if(msger.setHeaderField("Content-Type", "text/html"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                } else if(  !strcmp(fhandl.getSuffix(), "js"  )){
+                    if(msger.setHeaderField("Content-Type", "text/javascript"))         DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                } else if ( !strcmp(fhandl.getSuffix(), "ico" )){
+                    if(msger.setHeaderField("Content-Type", "image/png"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                } else if ( !strcmp(fhandl.getSuffix(), "png" ) ||
+                            !strcmp(fhandl.getSuffix(), "PNG" )){
+                    if(msger.setHeaderField("Content-Type", "image/png"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
+                } else if ( !strcmp(fhandl.getSuffix(), "jpg" ) ||
+                            !strcmp(fhandl.getSuffix(), "JPG" )){
+                    if(msger.setHeaderField("Content-Type", "image/jpg"))               DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
                 } else {
                     msger.setStatusLine(406, "not acceptable");
                 }
 
                 //  Connection timeout field
-                if(msger.setHeaderField("Keep-Alive", "timeouit=15"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
+                if(msger.setHeaderField("Keep-Alive", "timeouit=15"))                   DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
 
                 //  send response
                 msger.sendHTTPResponse(tcpcon, fhandl);
 
                 //file close
                 if( fhandl.close()== 0)
-                    DEBUG_PRINT_LINE("(HTTP_SERVER) file has closed\r\n");
+                    DEBUG_PRINT_LINE("file has closed");
                 else if(EOF)
-                    DEBUG_PRINT_LINE("(HTTP_SERVER) failed to close the file\r\n");
+                    DEBUG_PRINT_LINE("failed to close the file");
                     
                 msger.resetHeader();
-                printf("(HTTP_SERVER) echo back done.\r\n");
+                DEBUG_PRINT_LINE("echo back done.");
             }
             if (httpmethod == NULL) {
                 msger.sendHTTPResponse(tcpcon);
                 msger.resetHeader();
-                printf("(HTTP_SERVER) echo back done.\r\n");
+                DEBUG_PRINT_LINE("echo back done.");
             }
             printf("(HTTP_SERVER) Response to Request has done\r\n");
             //
diff -r cbf97b865d76 -r b6dd6ed0060b handlers/Filehandler.cpp
--- a/handlers/Filehandler.cpp	Fri Mar 16 21:50:43 2018 +0000
+++ b/handlers/Filehandler.cpp	Fri Mar 16 21:55:50 2018 +0000
@@ -1,6 +1,6 @@
 #include "FileHandler.h"
 #ifndef DEBUG
-#define DEBUG
+//#define DEBUG
 #endif
 LocalFileSystem local("local");
 
@@ -25,11 +25,11 @@
 {
     FILE *tmp;
 
-    printf("\r\n"
-           "fp: %d@FileHandler::open\r\n", fp);
+    //////printf("\r\n"
+    //       "fp: %d@FileHandler::open\r\n", fp);
     if (fullpath != NULL) free(fullpath);
     fullpath = (char*)malloc(sizeof(char) * (strlen("/local/") + strlen(arg_filepath) + strlen("index.htm") + 1));
-    printf("fp: %d@FileHandler::open\r\n", fp);
+    //////printf("fp: %d@FileHandler::open\r\n", fp);
 
     //  Path formatting
     if (arg_filepath[0] == '/') {
@@ -47,31 +47,31 @@
     suffix = strchr(filename, '.');
     if(suffix   != NULL)    suffix++;   //  remove '.' and just get only the suffix.
 #ifdef DEBUG
-    printf("full path: %s\r\nfilename: %s\r\nsuffix: %s\r\n", getFullpath(), getFilename(), getSuffix());
+    //////printf("full path: %s\r\nfilename: %s\r\nsuffix: %s\r\n", getFullpath(), getFilename(), getSuffix());
 #endif
     fp = fopen(fullpath, arg_mode);
 #ifdef DEBUG
-    printf("file opened@FileHandler::open\r\n");
+    //////////printf("file opened@FileHandler::open\r\n");
 #endif
     //  mesure file size
     file_size = 0;
     tmp = fp;
     if(tmp != NULL ) {
-        printf("\r\nfile content\r\n");
+        ////printf("\r\nfile content\r\n");
         int ctmp;
         while(1) {
             ctmp = fgetc(tmp);
             if(ctmp != EOF) {
-                printf("%c", ctmp);
+                //////printf("%c", ctmp);
                 file_size++;
             } else {
-                printf("[EOF]\r\n");
+                //////printf("[EOF]\r\n");
                 break;
             }
         }
-        printf("file size: %d\r\n", file_size);
+        ////printf("file size: %d\r\n", file_size);
         if(fseek(tmp, 0L, SEEK_SET) != 0) {
-            printf("fseek failed\r\n");
+            //////printf("fseek failed\r\n");
         }
     } else {
         file_size = 0;
@@ -95,7 +95,7 @@
 int FileHandler::getc()
 {
     int tmp = fgetc(fp);
-
+#ifdef DEBUG
     if(0x20 < tmp && tmp < 0x7e)
         printf("%c", tmp);
     else if (tmp == '\r')
@@ -104,8 +104,8 @@
         printf("\n");
     else
         printf("@");
-
-    return tmp;//fgetc(fp);
+#endif
+    return tmp;
 }
 bool FileHandler::arrival()
 {
diff -r cbf97b865d76 -r b6dd6ed0060b handlers/ResponseMessenger.cpp
--- a/handlers/ResponseMessenger.cpp	Fri Mar 16 21:50:43 2018 +0000
+++ b/handlers/ResponseMessenger.cpp	Fri Mar 16 21:55:50 2018 +0000
@@ -41,12 +41,15 @@
 int ResponseMessenger::setHeaderField(
     const char* arg_field_name, const char* arg_field_val)
 {
-    const int nField = 4;
+    const int nField = 7;
     char registered_field_name[nField][32]= {
         "Connection",
         "Location",
         "Keep-Alive",
-        "Content-Type"
+        "Content-Type",
+        "Upgrade",
+        "Sec-WebSocket-Accept",
+        "Access-Control-Allow-Origin"
     };
     bool flag = false;
     char header_field_line_buffer[128];
@@ -59,7 +62,7 @@
     if(flag) {
         sprintf(header_field_line_buffer, "%s: %s\r\n", arg_field_name, arg_field_val);
         strcat(header_field_buffer, header_field_line_buffer);
-        printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
+        //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
     }
     //  To be safe on the sage side
     header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
@@ -88,7 +91,7 @@
     if(flag) {
         sprintf(header_field_line_buffer, "%s: %d\r\n", arg_field_name, arg_field_val);
         strcat(header_field_buffer, header_field_line_buffer);
-        printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
+        //printf("(RM) header field: \r\n%s\r\n", header_field_buffer);
     }
     //  To be safe on the sage side
     header_field_buffer[HEADER_FIELDS_SIZE - 1] = '\0';
@@ -187,8 +190,8 @@
                 err_log = arg_connection.send_all((char*)buffer, i);
                 //printf("(RM) buffer log: %s",  buffer);
             }
-            if (arg_file.hasError()) printf("(RM) \r\n[ERR][ERR][ERR]\r\n");
-            if (arg_file.atEOF())    printf("(RM) \r\n[EOF][EOF][EOF]\r\n");
+            if (arg_file.hasError()) printf("(RM)---[ERR]---\r\n");
+            if (arg_file.atEOF())    printf("(RM)---[EOF]---\r\n");
         } while (!arg_file.atEOF() && !arg_file.hasError());
         printf("(RM) [Body has sent]\r\n");