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>
Committer:
aktk
Date:
Fri Mar 16 21:55:50 2018 +0000
Revision:
13:b6dd6ed0060b
Parent:
10:4a48594c2f44
merged

Who changed what in which revision?

UserRevisionLine numberNew contents of line
aktk 0:cc483bea4fe3 1 #include "HTTP_SERVER.h"
aktk 1:3a1fe94c6e42 2 #include "string"
aktk 8:b013075de2e4 3 #ifndef DEBUG
aktk 10:4a48594c2f44 4 //#define DEBUG
aktk 8:b013075de2e4 5 #endif
aktk 1:3a1fe94c6e42 6
aktk 10:4a48594c2f44 7 namespace HTTP_SERVER
aktk 10:4a48594c2f44 8 {
aktk 1:3a1fe94c6e42 9 void DEBUG_PRINT_LINE(const char* arg_line)
aktk 1:3a1fe94c6e42 10 {
aktk 1:3a1fe94c6e42 11 #ifdef DEBUG
aktk 10:4a48594c2f44 12 printf("(HTTP_SERVER) ")
aktk 10:4a48594c2f44 13 printf(arg_line);
aktk 10:4a48594c2f44 14 printf("\r\n");
aktk 1:3a1fe94c6e42 15 #endif
aktk 1:3a1fe94c6e42 16 }
aktk 10:4a48594c2f44 17 template<typename T>
aktk 10:4a48594c2f44 18 void DEBUG_PRINT_LINE(const char* arg_line, T arg_t)
aktk 10:4a48594c2f44 19 {
aktk 10:4a48594c2f44 20 #ifdef DEBUG
aktk 10:4a48594c2f44 21 printf("(HTTP_SERVER) ");
aktk 10:4a48594c2f44 22 printf(arg_line, arg_t);
aktk 10:4a48594c2f44 23 printf("\r\n");
aktk 10:4a48594c2f44 24 #endif
aktk 10:4a48594c2f44 25 }
aktk 10:4a48594c2f44 26 template<typename T1, typename T2>
aktk 10:4a48594c2f44 27 void DEBUG_PRINT_LINE(const char* arg_line, T1 arg_t1, T2 arg_t2)
aktk 10:4a48594c2f44 28 {
aktk 10:4a48594c2f44 29 #ifdef DEBUG
aktk 10:4a48594c2f44 30 printf("(HTTP_SERVER) ");
aktk 10:4a48594c2f44 31 printf(arg_line, arg_t1, arg_t2);
aktk 10:4a48594c2f44 32 printf("\r\n");
aktk 10:4a48594c2f44 33 #endif
aktk 10:4a48594c2f44 34 }
aktk 10:4a48594c2f44 35 }
aktk 10:4a48594c2f44 36 using namespace HTTP_SERVER;
aktk 1:3a1fe94c6e42 37
aktk 0:cc483bea4fe3 38 HttpServer::HttpServer()
aktk 0:cc483bea4fe3 39 {
aktk 0:cc483bea4fe3 40 keep_alive = (false);
aktk 0:cc483bea4fe3 41 listening_flag = (false);
aktk 0:cc483bea4fe3 42 req_buf[0] = '\0';
aktk 0:cc483bea4fe3 43 }
aktk 0:cc483bea4fe3 44
aktk 0:cc483bea4fe3 45 HttpServer::~HttpServer()
aktk 0:cc483bea4fe3 46 {
aktk 0:cc483bea4fe3 47 }
aktk 0:cc483bea4fe3 48
aktk 0:cc483bea4fe3 49 bool HttpServer::init()
aktk 0:cc483bea4fe3 50 {
aktk 0:cc483bea4fe3 51
aktk 0:cc483bea4fe3 52 // Ethernet Initialization
aktk 0:cc483bea4fe3 53 if(eth.init()) {
aktk 1:3a1fe94c6e42 54 printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n");
aktk 0:cc483bea4fe3 55 return false;
aktk 0:cc483bea4fe3 56 }
aktk 0:cc483bea4fe3 57 // Ethernet Connecting setup
aktk 0:cc483bea4fe3 58 if(eth.connect()) {
aktk 1:3a1fe94c6e42 59 printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n");
aktk 0:cc483bea4fe3 60 return false;
aktk 0:cc483bea4fe3 61 } else {
aktk 1:3a1fe94c6e42 62 printf("(HTTP_SERVER) IP Address is %s\r\n", eth.getIPAddress());
aktk 0:cc483bea4fe3 63 }
aktk 0:cc483bea4fe3 64 // TCP Socket setup
aktk 0:cc483bea4fe3 65 // To open Server-side PORT
aktk 0:cc483bea4fe3 66 if(tcpsvr.bind(TCP_PORT)< 0) {
aktk 1:3a1fe94c6e42 67 printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n");
aktk 0:cc483bea4fe3 68 return false;
aktk 0:cc483bea4fe3 69 } else {
aktk 1:3a1fe94c6e42 70 printf("(HTTP_SERVER) TCP Server has bounden!\r\n");
aktk 0:cc483bea4fe3 71 }
aktk 0:cc483bea4fe3 72 // Server start listening Request from a web browser.
aktk 0:cc483bea4fe3 73 if(tcpsvr.listen(1) < 0) {
aktk 1:3a1fe94c6e42 74 printf("(HTTP_SERVER) tcp server listen failed.\r\n");
aktk 0:cc483bea4fe3 75 return false;
aktk 0:cc483bea4fe3 76 } else {
aktk 0:cc483bea4fe3 77 listening_flag = true;
aktk 1:3a1fe94c6e42 78 printf("(HTTP_SERVER) tcp server is listening...\r\n");
aktk 0:cc483bea4fe3 79 }
aktk 0:cc483bea4fe3 80
aktk 0:cc483bea4fe3 81 return true;
aktk 0:cc483bea4fe3 82 }
aktk 0:cc483bea4fe3 83
aktk 0:cc483bea4fe3 84 bool HttpServer::run()
aktk 0:cc483bea4fe3 85 {
aktk 0:cc483bea4fe3 86 DigitalOut led1(LED1);
aktk 0:cc483bea4fe3 87 DigitalOut led2(LED1);
aktk 0:cc483bea4fe3 88
aktk 0:cc483bea4fe3 89 while (listening_flag) {
aktk 0:cc483bea4fe3 90 led1 = true;
aktk 0:cc483bea4fe3 91 // blocking mode (never timeout)
aktk 0:cc483bea4fe3 92 // waiting client connection
aktk 1:3a1fe94c6e42 93 printf("(HTTP_SERVER) waiting connection\r\n");
aktk 0:cc483bea4fe3 94 if(tcpsvr.accept(tcpcon) < 0) {
aktk 1:3a1fe94c6e42 95 printf("(HTTP_SERVER) failed to accept connection.\r\n");
aktk 0:cc483bea4fe3 96 return -1;
aktk 0:cc483bea4fe3 97 } else {
aktk 1:3a1fe94c6e42 98 printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",tcpcon.get_address());
aktk 0:cc483bea4fe3 99 led2 = true;
aktk 0:cc483bea4fe3 100 }
aktk 1:3a1fe94c6e42 101 // When conected
aktk 0:cc483bea4fe3 102 while(tcpcon.is_connected()) {
aktk 10:4a48594c2f44 103 printf("(HTTP_SERVER) connected\r\n");
aktk 1:3a1fe94c6e42 104
aktk 0:cc483bea4fe3 105 char buffer[1024] = {0};
aktk 0:cc483bea4fe3 106 char* httpmethod = NULL;
aktk 0:cc483bea4fe3 107 char* filepath = NULL;
aktk 0:cc483bea4fe3 108 char* http_ver = NULL;
aktk 0:cc483bea4fe3 109 char* header_field_name = NULL;
aktk 0:cc483bea4fe3 110 char* header_field_val = NULL;
aktk 1:3a1fe94c6e42 111
aktk 0:cc483bea4fe3 112 //
aktk 0:cc483bea4fe3 113 // Request Analysis
aktk 0:cc483bea4fe3 114 //
aktk 10:4a48594c2f44 115 DEBUG_PRINT_LINE("DEBUG MODE");
aktk 0:cc483bea4fe3 116 switch(tcpcon.receive(buffer, 1023)) {
aktk 0:cc483bea4fe3 117 case 0:
aktk 10:4a48594c2f44 118 DEBUG_PRINT_LINE("recieved buffer is empty.");
aktk 0:cc483bea4fe3 119 msger.setStatusLine(400, "No Request");
aktk 10:4a48594c2f44 120 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 121 httpmethod = NULL;
aktk 0:cc483bea4fe3 122 filepath = NULL;
aktk 0:cc483bea4fe3 123 http_ver = NULL;
aktk 0:cc483bea4fe3 124 break;
aktk 0:cc483bea4fe3 125 case -1:
aktk 10:4a48594c2f44 126 DEBUG_PRINT_LINE("failed to read data from client.");
aktk 0:cc483bea4fe3 127 msger.setStatusLine(500, "Internal Server Error");
aktk 10:4a48594c2f44 128 if(msger.setHeaderField("Connection", "Close"))DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 129 httpmethod = NULL;
aktk 0:cc483bea4fe3 130 filepath = NULL;
aktk 0:cc483bea4fe3 131 http_ver = NULL;
aktk 0:cc483bea4fe3 132 break;
aktk 0:cc483bea4fe3 133 default:
aktk 10:4a48594c2f44 134 DEBUG_PRINT_LINE("Recieved Data: %d",strlen(buffer));
aktk 10:4a48594c2f44 135 DEBUG_PRINT_LINE("-->\r\n");
aktk 10:4a48594c2f44 136 DEBUG_PRINT_LINE("%.*s[End of Request]",strlen(buffer),buffer);
aktk 10:4a48594c2f44 137 // get HTTP method, File path, HTTP version
aktk 0:cc483bea4fe3 138 httpmethod = strtok(buffer," ");
aktk 0:cc483bea4fe3 139 filepath = strtok(NULL, " ");
aktk 0:cc483bea4fe3 140 http_ver = strtok(NULL, "\r\n");
aktk 10:4a48594c2f44 141 DEBUG_PRINT_LINE("httpmethod: %s", httpmethod);
aktk 10:4a48594c2f44 142 DEBUG_PRINT_LINE("file path: %s", filepath);
aktk 10:4a48594c2f44 143 DEBUG_PRINT_LINE("http ver : %s", http_ver);
aktk 0:cc483bea4fe3 144 break;
aktk 0:cc483bea4fe3 145 }
aktk 1:3a1fe94c6e42 146
aktk 0:cc483bea4fe3 147 //
aktk 0:cc483bea4fe3 148 // Response
aktk 0:cc483bea4fe3 149 //
aktk 0:cc483bea4fe3 150 if (strcmp(httpmethod,"GET") == 0 ) {
aktk 10:4a48594c2f44 151 DEBUG_PRINT_LINE("GET request incomming.");
aktk 0:cc483bea4fe3 152
aktk 0:cc483bea4fe3 153 // file calibration
aktk 10:4a48594c2f44 154 DEBUG_PRINT_LINE("file opening");
aktk 0:cc483bea4fe3 155 fhandl.open(filepath,"rb");
aktk 0:cc483bea4fe3 156 if(fhandl.arrival()) {
aktk 0:cc483bea4fe3 157 msger.setStatusLine(200, "OK");
aktk 10:4a48594c2f44 158 if(msger.setHeaderField("Content-Length", fhandl.getFileSize())) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 159 if(msger.setHeaderField("Connection", "keep-alive")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 160 } else {
aktk 10:4a48594c2f44 161 if(msger.setStatusLine(404, "NOT FOUND")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 162 if(msger.setHeaderField("Connection", "Close")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 163 DEBUG_PRINT_LINE("NOT FOUND");
aktk 0:cc483bea4fe3 164 }
aktk 10:4a48594c2f44 165 if( !strcmp(fhandl.getSuffix(), "htm" ) ||
aktk 10:4a48594c2f44 166 !strcmp(fhandl.getSuffix(), "HTM" ) ||
aktk 10:4a48594c2f44 167 !strcmp(fhandl.getSuffix(), "html") ||
aktk 10:4a48594c2f44 168 !strcmp(fhandl.getSuffix(), "HTML")){
aktk 10:4a48594c2f44 169 if(msger.setHeaderField("Content-Type", "text/html")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 170 } else if( !strcmp(fhandl.getSuffix(), "js" )){
aktk 10:4a48594c2f44 171 if(msger.setHeaderField("Content-Type", "text/javascript")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 172 } else if ( !strcmp(fhandl.getSuffix(), "ico" )){
aktk 10:4a48594c2f44 173 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 174 } else if ( !strcmp(fhandl.getSuffix(), "png" ) ||
aktk 10:4a48594c2f44 175 !strcmp(fhandl.getSuffix(), "PNG" )){
aktk 10:4a48594c2f44 176 if(msger.setHeaderField("Content-Type", "image/png")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 10:4a48594c2f44 177 } else if ( !strcmp(fhandl.getSuffix(), "jpg" ) ||
aktk 10:4a48594c2f44 178 !strcmp(fhandl.getSuffix(), "JPG" )){
aktk 10:4a48594c2f44 179 if(msger.setHeaderField("Content-Type", "image/jpg")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 180 } else {
aktk 0:cc483bea4fe3 181 msger.setStatusLine(406, "not acceptable");
aktk 0:cc483bea4fe3 182 }
aktk 0:cc483bea4fe3 183
aktk 0:cc483bea4fe3 184 // Connection timeout field
aktk 10:4a48594c2f44 185 if(msger.setHeaderField("Keep-Alive", "timeouit=15")) DEBUG_PRINT_LINE("buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 186
aktk 0:cc483bea4fe3 187 // send response
aktk 0:cc483bea4fe3 188 msger.sendHTTPResponse(tcpcon, fhandl);
aktk 0:cc483bea4fe3 189
aktk 0:cc483bea4fe3 190 //file close
aktk 7:184c6f1ace94 191 if( fhandl.close()== 0)
aktk 10:4a48594c2f44 192 DEBUG_PRINT_LINE("file has closed");
aktk 0:cc483bea4fe3 193 else if(EOF)
aktk 10:4a48594c2f44 194 DEBUG_PRINT_LINE("failed to close the file");
aktk 7:184c6f1ace94 195
aktk 7:184c6f1ace94 196 msger.resetHeader();
aktk 10:4a48594c2f44 197 DEBUG_PRINT_LINE("echo back done.");
aktk 7:184c6f1ace94 198 }
aktk 7:184c6f1ace94 199 if (httpmethod == NULL) {
aktk 7:184c6f1ace94 200 msger.sendHTTPResponse(tcpcon);
aktk 0:cc483bea4fe3 201 msger.resetHeader();
aktk 10:4a48594c2f44 202 DEBUG_PRINT_LINE("echo back done.");
aktk 0:cc483bea4fe3 203 }
aktk 1:3a1fe94c6e42 204 printf("(HTTP_SERVER) Response to Request has done\r\n");
aktk 7:184c6f1ace94 205 //
aktk 7:184c6f1ace94 206 //
aktk 7:184c6f1ace94 207 //
aktk 0:cc483bea4fe3 208 }
aktk 1:3a1fe94c6e42 209 printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
aktk 0:cc483bea4fe3 210 tcpcon.close();
aktk 0:cc483bea4fe3 211 led2 = false;
aktk 0:cc483bea4fe3 212 }
aktk 7:184c6f1ace94 213 tcpsvr.close();
aktk 7:184c6f1ace94 214 listening_flag = false;
aktk 0:cc483bea4fe3 215 led1 = false;
aktk 0:cc483bea4fe3 216 return 0;
aktk 0:cc483bea4fe3 217 }