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:
Sat Nov 26 18:54:10 2016 +0000
Revision:
5:dedbaa9c633b
Parent:
4:b551799053c6
Child:
6:4eb469f51570
bug fix: the bug communication was conducted when it shouldn't have been was fixed.

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 0:cc483bea4fe3 3 #define DEBUG
aktk 1:3a1fe94c6e42 4
aktk 1:3a1fe94c6e42 5 void DEBUG_PRINT_LINE(const char* arg_line)
aktk 1:3a1fe94c6e42 6 {
aktk 1:3a1fe94c6e42 7 #ifdef DEBUG
aktk 1:3a1fe94c6e42 8 printf("%s",arg_line);
aktk 1:3a1fe94c6e42 9 #endif
aktk 1:3a1fe94c6e42 10 }
aktk 1:3a1fe94c6e42 11
aktk 0:cc483bea4fe3 12 HttpServer::HttpServer()
aktk 0:cc483bea4fe3 13 {
aktk 0:cc483bea4fe3 14 keep_alive = (false);
aktk 0:cc483bea4fe3 15 listening_flag = (false);
aktk 0:cc483bea4fe3 16 req_buf[0] = '\0';
aktk 0:cc483bea4fe3 17 }
aktk 0:cc483bea4fe3 18
aktk 0:cc483bea4fe3 19 HttpServer::~HttpServer()
aktk 0:cc483bea4fe3 20 {
aktk 0:cc483bea4fe3 21 }
aktk 0:cc483bea4fe3 22
aktk 0:cc483bea4fe3 23 bool HttpServer::init()
aktk 0:cc483bea4fe3 24 {
aktk 0:cc483bea4fe3 25
aktk 0:cc483bea4fe3 26 // Ethernet Initialization
aktk 0:cc483bea4fe3 27 if(eth.init()) {
aktk 1:3a1fe94c6e42 28 printf("(HTTP_SERVER) Error!@EthernetInterface::init()\r\n");
aktk 0:cc483bea4fe3 29 return false;
aktk 0:cc483bea4fe3 30 }
aktk 0:cc483bea4fe3 31 // Ethernet Connecting setup
aktk 0:cc483bea4fe3 32 if(eth.connect()) {
aktk 1:3a1fe94c6e42 33 printf("(HTTP_SERVER) Error!@EthernetInterface::connect()\r\n");
aktk 0:cc483bea4fe3 34 return false;
aktk 0:cc483bea4fe3 35 } else {
aktk 1:3a1fe94c6e42 36 printf("(HTTP_SERVER) IP Address is %s\r\n", eth.getIPAddress());
aktk 0:cc483bea4fe3 37 }
aktk 0:cc483bea4fe3 38 // TCP Socket setup
aktk 0:cc483bea4fe3 39 // To open Server-side PORT
aktk 0:cc483bea4fe3 40 if(tcpsvr.bind(TCP_PORT)< 0) {
aktk 1:3a1fe94c6e42 41 printf("(HTTP_SERVER) Error!@TCPSocketServer::bind()\r\n");
aktk 0:cc483bea4fe3 42 return false;
aktk 0:cc483bea4fe3 43 } else {
aktk 1:3a1fe94c6e42 44 printf("(HTTP_SERVER) TCP Server has bounden!\r\n");
aktk 0:cc483bea4fe3 45 }
aktk 0:cc483bea4fe3 46 // Server start listening Request from a web browser.
aktk 0:cc483bea4fe3 47 if(tcpsvr.listen(1) < 0) {
aktk 1:3a1fe94c6e42 48 printf("(HTTP_SERVER) tcp server listen failed.\r\n");
aktk 0:cc483bea4fe3 49 return false;
aktk 0:cc483bea4fe3 50 } else {
aktk 0:cc483bea4fe3 51 listening_flag = true;
aktk 1:3a1fe94c6e42 52 printf("(HTTP_SERVER) tcp server is listening...\r\n");
aktk 0:cc483bea4fe3 53 }
aktk 0:cc483bea4fe3 54
aktk 0:cc483bea4fe3 55 return true;
aktk 0:cc483bea4fe3 56 }
aktk 0:cc483bea4fe3 57
aktk 0:cc483bea4fe3 58 bool HttpServer::run()
aktk 0:cc483bea4fe3 59 {
aktk 0:cc483bea4fe3 60 DigitalOut led1(LED1);
aktk 0:cc483bea4fe3 61 DigitalOut led2(LED1);
aktk 0:cc483bea4fe3 62
aktk 0:cc483bea4fe3 63 while (listening_flag) {
aktk 0:cc483bea4fe3 64 led1 = true;
aktk 0:cc483bea4fe3 65 // blocking mode (never timeout)
aktk 0:cc483bea4fe3 66 // waiting client connection
aktk 1:3a1fe94c6e42 67 printf("(HTTP_SERVER) waiting connection\r\n");
aktk 0:cc483bea4fe3 68 if(tcpsvr.accept(tcpcon) < 0) {
aktk 1:3a1fe94c6e42 69 printf("(HTTP_SERVER) failed to accept connection.\r\n");
aktk 0:cc483bea4fe3 70 return -1;
aktk 0:cc483bea4fe3 71 } else {
aktk 1:3a1fe94c6e42 72 printf("(HTTP_SERVER) connection success!\r\nIP: %s\r\n",tcpcon.get_address());
aktk 0:cc483bea4fe3 73 led2 = true;
aktk 0:cc483bea4fe3 74 }
aktk 1:3a1fe94c6e42 75 // When conected
aktk 0:cc483bea4fe3 76 while(tcpcon.is_connected()) {
aktk 1:3a1fe94c6e42 77 DEBUG_PRINT_LINE("(HTTP_SERVER) connected\r\n");
aktk 1:3a1fe94c6e42 78
aktk 0:cc483bea4fe3 79 char buffer[1024] = {0};
aktk 0:cc483bea4fe3 80 char* httpmethod = NULL;
aktk 0:cc483bea4fe3 81 char* filepath = NULL;
aktk 0:cc483bea4fe3 82 char* http_ver = NULL;
aktk 0:cc483bea4fe3 83 char* header_field_name = NULL;
aktk 0:cc483bea4fe3 84 char* header_field_val = NULL;
aktk 1:3a1fe94c6e42 85
aktk 0:cc483bea4fe3 86 //
aktk 0:cc483bea4fe3 87 // Request Analysis
aktk 0:cc483bea4fe3 88 //
aktk 1:3a1fe94c6e42 89 DEBUG_PRINT_LINE("(HTTP_SERVER) DEBUG MODE\r\n");
aktk 0:cc483bea4fe3 90 switch(tcpcon.receive(buffer, 1023)) {
aktk 0:cc483bea4fe3 91 case 0:
aktk 1:3a1fe94c6e42 92 printf("(HTTP_SERVER) recieved buffer is empty.\r\n");
aktk 0:cc483bea4fe3 93 msger.setStatusLine(400, "No Request");
aktk 5:dedbaa9c633b 94 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 95 httpmethod = NULL;
aktk 0:cc483bea4fe3 96 filepath = NULL;
aktk 0:cc483bea4fe3 97 http_ver = NULL;
aktk 0:cc483bea4fe3 98 break;
aktk 0:cc483bea4fe3 99 case -1:
aktk 1:3a1fe94c6e42 100 printf("(HTTP_SERVER) failed to read data from client.\r\n");
aktk 0:cc483bea4fe3 101 msger.setStatusLine(500, "Internal Server Error");
aktk 5:dedbaa9c633b 102 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 103 httpmethod = NULL;
aktk 0:cc483bea4fe3 104 filepath = NULL;
aktk 0:cc483bea4fe3 105 http_ver = NULL;
aktk 0:cc483bea4fe3 106 break;
aktk 0:cc483bea4fe3 107 default:
aktk 1:3a1fe94c6e42 108 printf("(HTTP_SERVER) Recieved Data: %d\r\n-->\r\n%.*s[End of Request]\r\n",strlen(buffer),strlen(buffer),buffer);
aktk 0:cc483bea4fe3 109 // get HTTP method
aktk 0:cc483bea4fe3 110 httpmethod = strtok(buffer," ");
aktk 0:cc483bea4fe3 111 // get File path
aktk 0:cc483bea4fe3 112 filepath = strtok(NULL, " ");
aktk 0:cc483bea4fe3 113 // get HTTP version
aktk 0:cc483bea4fe3 114 http_ver = strtok(NULL, "\r\n");
aktk 0:cc483bea4fe3 115 #ifdef DEBUG
aktk 1:3a1fe94c6e42 116 printf("(HTTP_SERVER) httpmethod: %s\r\n", httpmethod);
aktk 1:3a1fe94c6e42 117 printf("(HTTP_SERVER) file path: %s\r\n", filepath);
aktk 1:3a1fe94c6e42 118 printf("(HTTP_SERVER) http ver : %s\r\n", http_ver);
aktk 0:cc483bea4fe3 119 #endif
aktk 0:cc483bea4fe3 120 break;
aktk 0:cc483bea4fe3 121 }
aktk 1:3a1fe94c6e42 122 DEBUG_PRINT_LINE("\r\n"
aktk 1:3a1fe94c6e42 123 "(HTTP_SERVER) debug before response\r\n");
aktk 1:3a1fe94c6e42 124
aktk 0:cc483bea4fe3 125 //
aktk 0:cc483bea4fe3 126 // Response
aktk 0:cc483bea4fe3 127 //
aktk 0:cc483bea4fe3 128 if (strcmp(httpmethod,"GET") == 0 ) {
aktk 1:3a1fe94c6e42 129 printf("(HTTP_SERVER) GET request incomming.\r\n");
aktk 0:cc483bea4fe3 130
aktk 0:cc483bea4fe3 131 // file calibration
aktk 1:3a1fe94c6e42 132 DEBUG_PRINT_LINE("(HTTP_SERVER) file opening\r\n");
aktk 0:cc483bea4fe3 133 fhandl.open(filepath,"rb");
aktk 0:cc483bea4fe3 134 if(fhandl.arrival()) {
aktk 0:cc483bea4fe3 135 msger.setStatusLine(200, "OK");
aktk 5:dedbaa9c633b 136 if(msger.setHeaderField("Content-Length", fhandl.getFileSize()))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 5:dedbaa9c633b 137 if(msger.setHeaderField("Connection", "keep-alive"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 138 } else {
aktk 5:dedbaa9c633b 139 if(msger.setStatusLine(404, "NOT FOUND"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 5:dedbaa9c633b 140 if(msger.setHeaderField("Connection", "close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 141 DEBUG_PRINT_LINE("(HTTP_SERVER) NOT FOUND\r\n");
aktk 0:cc483bea4fe3 142 }
aktk 1:3a1fe94c6e42 143 if( strcmp(fhandl.getSuffix(), "htm" ) ||
aktk 1:3a1fe94c6e42 144 strcmp(fhandl.getSuffix(), "HTM" ) ||
aktk 1:3a1fe94c6e42 145 strcmp(fhandl.getSuffix(), "html") ||
aktk 1:3a1fe94c6e42 146 strcmp(fhandl.getSuffix(), "HTML")) {
aktk 5:dedbaa9c633b 147 if(msger.setHeaderField("Content-Type", "text/html"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 148 } else if (strcmp(fhandl.getSuffix(), "ico" ) ) {
aktk 5:dedbaa9c633b 149 if(msger.setHeaderField("Content-Type", "image/png"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 150 } else {
aktk 0:cc483bea4fe3 151 msger.setStatusLine(406, "not acceptable");
aktk 0:cc483bea4fe3 152 }
aktk 0:cc483bea4fe3 153
aktk 0:cc483bea4fe3 154 // Connection timeout field
aktk 5:dedbaa9c633b 155 if(msger.setHeaderField("Keep-Alive", "timeouit=15"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 1:3a1fe94c6e42 156
aktk 1:3a1fe94c6e42 157 // Define behaviour of server according to Request Header lines
aktk 2:33714d7c0f45 158 // Apply request header field to response header field
aktk 3:59884bc0a238 159 char* field_Connection = NULL;
aktk 3:59884bc0a238 160 char* field_Upgrade = NULL;
aktk 3:59884bc0a238 161 char* field_Sec_WebSocket_Key = NULL;
aktk 3:59884bc0a238 162 char* field_Sec_WebSocket_Version = NULL;
aktk 3:59884bc0a238 163 char* field_Origin = NULL;
aktk 0:cc483bea4fe3 164 do {
aktk 2:33714d7c0f45 165 //Analyze the header feilds
aktk 0:cc483bea4fe3 166 header_field_name = strtok(NULL, ":");
aktk 0:cc483bea4fe3 167 header_field_name++;
aktk 0:cc483bea4fe3 168 header_field_val = strtok(NULL, "\r\n");
aktk 0:cc483bea4fe3 169 header_field_val++;
aktk 2:33714d7c0f45 170
aktk 4:b551799053c6 171 if(header_field_name - 1 != NULL) {
aktk 3:59884bc0a238 172 if(!strcmp(header_field_name, "Connection")) {
aktk 3:59884bc0a238 173 field_Connection = header_field_val;
aktk 3:59884bc0a238 174 } else if(!strcmp(header_field_name, "Upgrade")) {
aktk 3:59884bc0a238 175 field_Upgrade = header_field_val;
aktk 3:59884bc0a238 176 } else if(!strcmp(header_field_name, "Sec-WebSocket-Key") ) {
aktk 3:59884bc0a238 177 field_Sec_WebSocket_Key = header_field_val;
aktk 3:59884bc0a238 178 } else if(!strcmp(header_field_name, "Sec-WebSocket-Version") ) {
aktk 3:59884bc0a238 179 field_Sec_WebSocket_Version = header_field_val;
aktk 3:59884bc0a238 180 } else if(!strcmp(header_field_name, "Origin") ) {
aktk 3:59884bc0a238 181 field_Origin = header_field_val;
aktk 2:33714d7c0f45 182 }
aktk 4:b551799053c6 183 } else {
aktk 4:b551799053c6 184 break;
aktk 4:b551799053c6 185 }
aktk 0:cc483bea4fe3 186 #ifdef DEBUG
aktk 1:3a1fe94c6e42 187 printf("(HTTP_SERVER) *header_field_name adr: %d %s\r\n", header_field_name - 1, header_field_name);
aktk 1:3a1fe94c6e42 188 printf("(HTTP_SERVER) header_field_val adr: %d %s\r\n", header_field_val - 1, header_field_val);
aktk 0:cc483bea4fe3 189 #endif
aktk 2:33714d7c0f45 190 } while(1);
aktk 2:33714d7c0f45 191
aktk 2:33714d7c0f45 192 // if the request is to switching to the WebSocket Server
aktk 5:dedbaa9c633b 193 if(!strcmp(field_Connection, "Upgrade")) {
aktk 5:dedbaa9c633b 194 if( !strcmp(field_Upgrade, "websocket") &&
aktk 5:dedbaa9c633b 195 field_Sec_WebSocket_Key != NULL &&
aktk 5:dedbaa9c633b 196 !strcmp(field_Sec_WebSocket_Version, "13") &&
aktk 5:dedbaa9c633b 197 field_Origin != NULL) {
aktk 5:dedbaa9c633b 198 DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol will be Upgraded to Websocket! \r\n");
aktk 5:dedbaa9c633b 199 /*
aktk 5:dedbaa9c633b 200 if(ws.isValid()){
aktk 5:dedbaa9c633b 201 ...//calcurate the key
aktk 5:dedbaa9c633b 202 msger.resetHeader();
aktk 5:dedbaa9c633b 203 msger.setStatusLine(101, "Switching Protocols");
aktk 5:dedbaa9c633b 204 if(msger.msger.setHeaderField("Connection", "Upgrade")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 205 if(msger.msger.setHeaderField("Upgrade", "websocket")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 206 if(msger.msger.setHeaderField("Sec-WebSocket-Accept", ...)) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 207 if(msger.msger.setHeaderField("Access-Control-Allow-Origin", "*")) printf("(HTTP_SERVER)buffer over flow@ResposeMessenger");
aktk 5:dedbaa9c633b 208 }
aktk 5:dedbaa9c633b 209 else goto AAA;
aktk 5:dedbaa9c633b 210 */
aktk 5:dedbaa9c633b 211 } else {
aktk 5:dedbaa9c633b 212 //AAA:
aktk 5:dedbaa9c633b 213 DEBUG_PRINT_LINE("(HTTP_SERVER) Communication Protocol won't be Upgraded.\r\n");
aktk 5:dedbaa9c633b 214 msger.setStatusLine(426, "Upgrade Required");
aktk 5:dedbaa9c633b 215 if(msger.setHeaderField("Connection", "Close"))printf("(HTTP_SERVER)buffer over flow @ ResponseMessenger");
aktk 0:cc483bea4fe3 216 }
aktk 2:33714d7c0f45 217 }
aktk 2:33714d7c0f45 218
aktk 1:3a1fe94c6e42 219
aktk 0:cc483bea4fe3 220 #ifdef DEBUG
aktk 0:cc483bea4fe3 221 //printf("status code : %d\r\n", status_code);
aktk 0:cc483bea4fe3 222 //printf("content type: %s\r\n", content_type);
aktk 0:cc483bea4fe3 223 #endif
aktk 0:cc483bea4fe3 224
aktk 0:cc483bea4fe3 225 // send response
aktk 0:cc483bea4fe3 226 msger.sendHTTPResponse(tcpcon, fhandl);
aktk 0:cc483bea4fe3 227
aktk 0:cc483bea4fe3 228 //file close
aktk 0:cc483bea4fe3 229 #ifdef DEBUG
aktk 0:cc483bea4fe3 230 if(
aktk 0:cc483bea4fe3 231 #endif
aktk 0:cc483bea4fe3 232 fhandl.close()
aktk 0:cc483bea4fe3 233 #ifndef DEBUG
aktk 0:cc483bea4fe3 234 ;
aktk 0:cc483bea4fe3 235 #endif
aktk 0:cc483bea4fe3 236 #ifdef DEBUG
aktk 0:cc483bea4fe3 237 == 0)
aktk 1:3a1fe94c6e42 238 printf("(HTTP_SERVER) file has closed\r\n");
aktk 0:cc483bea4fe3 239 else if(EOF)
aktk 1:3a1fe94c6e42 240 printf("(HTTP_SERVER) failed to close the file\r\n");
aktk 0:cc483bea4fe3 241 #endif
aktk 0:cc483bea4fe3 242 msger.resetHeader();
aktk 1:3a1fe94c6e42 243 printf("(HTTP_SERVER) echo back done.\r\n");
aktk 0:cc483bea4fe3 244 }
aktk 1:3a1fe94c6e42 245 printf("(HTTP_SERVER) Response to Request has done\r\n");
aktk 0:cc483bea4fe3 246 }
aktk 1:3a1fe94c6e42 247 printf("(HTTP_SERVER) close connection.\r\ntcp server is listening...\r\n");
aktk 0:cc483bea4fe3 248 tcpcon.close();
aktk 1:3a1fe94c6e42 249 //tcpsvr.close();
aktk 0:cc483bea4fe3 250 led2 = false;
aktk 0:cc483bea4fe3 251 }
aktk 0:cc483bea4fe3 252 led1 = false;
aktk 0:cc483bea4fe3 253 return 0;
aktk 0:cc483bea4fe3 254 }