Webserver example for Nuvoton NuMaker boards and mbed OS 5.15 - HTTP 1.1 and multi-threaded.
For Mbed OS 6, please use the NuMaker-simple-httpd example.
This application demonstrates how to run an HTTP server on an mbed OS 5 device. It is derived from http-webserver-example Request parsing is done through nodejs/http-parser.
Fixed for Mbed OS 5.15 or later
Tested on
NuMaker IoT-M487 with Ethernet NuMaker PFM-M487 with Ethernet
source/main.cpp@2:ff1a293c4df3, 2020-06-29 (annotated)
- Committer:
- morgandu
- Date:
- Mon Jun 29 08:17:16 2020 +0000
- Revision:
- 2:ff1a293c4df3
- Parent:
- 0:41f820ea137a
Webserver example for mbed OS 5 - HTTP 1.1 and multi-threaded; Fix for mbed OS 5.15 and clean unnecessary libraries; Add fixed IP address option; Test on Nuvoton NuMaker boards.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jan Jongboom |
0:41f820ea137a | 1 | #include "mbed.h" |
Jan Jongboom |
0:41f820ea137a | 2 | #include "http_server.h" |
Jan Jongboom |
0:41f820ea137a | 3 | #include "http_response_builder.h" |
Jan Jongboom |
0:41f820ea137a | 4 | |
morgandu | 2:ff1a293c4df3 | 5 | #define USE_FIXED_IP 1 // 1 for fixed IP, 0 for DHCP |
morgandu | 2:ff1a293c4df3 | 6 | |
Jan Jongboom |
0:41f820ea137a | 7 | DigitalOut led(LED1); |
Jan Jongboom |
0:41f820ea137a | 8 | |
Jan Jongboom |
0:41f820ea137a | 9 | // Requests come in here |
Jan Jongboom |
0:41f820ea137a | 10 | void request_handler(ParsedHttpRequest* request, TCPSocket* socket) { |
Jan Jongboom |
0:41f820ea137a | 11 | |
Jan Jongboom |
0:41f820ea137a | 12 | printf("Request came in: %s %s\n", http_method_str(request->get_method()), request->get_url().c_str()); |
Jan Jongboom |
0:41f820ea137a | 13 | |
Jan Jongboom |
0:41f820ea137a | 14 | if (request->get_method() == HTTP_GET && request->get_url() == "/") { |
Jan Jongboom |
0:41f820ea137a | 15 | HttpResponseBuilder builder(200); |
Jan Jongboom |
0:41f820ea137a | 16 | builder.set_header("Content-Type", "text/html; charset=utf-8"); |
Jan Jongboom |
0:41f820ea137a | 17 | |
Jan Jongboom |
0:41f820ea137a | 18 | char response[] = "<html><head><title>Hello from mbed</title></head>" |
Jan Jongboom |
0:41f820ea137a | 19 | "<body>" |
Jan Jongboom |
0:41f820ea137a | 20 | "<h1>mbed webserver</h1>" |
Jan Jongboom |
0:41f820ea137a | 21 | "<button id=\"toggle\">Toggle LED</button>" |
Jan Jongboom |
0:41f820ea137a | 22 | "<script>document.querySelector('#toggle').onclick = function() {" |
Jan Jongboom |
0:41f820ea137a | 23 | "var x = new XMLHttpRequest(); x.open('POST', '/toggle'); x.send();" |
Jan Jongboom |
0:41f820ea137a | 24 | "}</script>" |
Jan Jongboom |
0:41f820ea137a | 25 | "</body></html>"; |
Jan Jongboom |
0:41f820ea137a | 26 | |
Jan Jongboom |
0:41f820ea137a | 27 | builder.send(socket, response, sizeof(response) - 1); |
Jan Jongboom |
0:41f820ea137a | 28 | } |
Jan Jongboom |
0:41f820ea137a | 29 | else if (request->get_method() == HTTP_POST && request->get_url() == "/toggle") { |
Jan Jongboom |
0:41f820ea137a | 30 | printf("toggle LED called\n"); |
Jan Jongboom |
0:41f820ea137a | 31 | led = !led; |
Jan Jongboom |
0:41f820ea137a | 32 | |
Jan Jongboom |
0:41f820ea137a | 33 | HttpResponseBuilder builder(200); |
Jan Jongboom |
0:41f820ea137a | 34 | builder.send(socket, NULL, 0); |
Jan Jongboom |
0:41f820ea137a | 35 | } |
Jan Jongboom |
0:41f820ea137a | 36 | else { |
Jan Jongboom |
0:41f820ea137a | 37 | HttpResponseBuilder builder(404); |
Jan Jongboom |
0:41f820ea137a | 38 | builder.send(socket, NULL, 0); |
Jan Jongboom |
0:41f820ea137a | 39 | } |
Jan Jongboom |
0:41f820ea137a | 40 | } |
Jan Jongboom |
0:41f820ea137a | 41 | |
Jan Jongboom |
0:41f820ea137a | 42 | int main() { |
Jan Jongboom |
0:41f820ea137a | 43 | |
Jan Jongboom |
0:41f820ea137a | 44 | // Connect to the network (see mbed_app.json for the connectivity method used) |
morgandu | 2:ff1a293c4df3 | 45 | NetworkInterface *network = NetworkInterface::get_default_instance(); |
Jan Jongboom |
0:41f820ea137a | 46 | if (!network) { |
Jan Jongboom |
0:41f820ea137a | 47 | printf("Cannot connect to the network, see serial output\n"); |
Jan Jongboom |
0:41f820ea137a | 48 | return 1; |
Jan Jongboom |
0:41f820ea137a | 49 | } |
Jan Jongboom |
0:41f820ea137a | 50 | |
morgandu | 2:ff1a293c4df3 | 51 | #if USE_FIXED_IP |
morgandu | 2:ff1a293c4df3 | 52 | // This fixed IP address is convenient to test with Windows PC |
morgandu | 2:ff1a293c4df3 | 53 | SocketAddress ip_addr("169.254.108.2"); |
morgandu | 2:ff1a293c4df3 | 54 | SocketAddress ip_mask("255.255.0.0"); |
morgandu | 2:ff1a293c4df3 | 55 | SocketAddress ip_gwaddr("169.254.108.1"); |
morgandu | 2:ff1a293c4df3 | 56 | network->set_network(ip_addr, ip_mask, ip_gwaddr); |
morgandu | 2:ff1a293c4df3 | 57 | #endif |
morgandu | 2:ff1a293c4df3 | 58 | |
morgandu | 2:ff1a293c4df3 | 59 | network->connect(); |
morgandu | 2:ff1a293c4df3 | 60 | |
Jan Jongboom |
0:41f820ea137a | 61 | HttpServer server(network); |
morgandu | 2:ff1a293c4df3 | 62 | nsapi_error_t res = server.start(80, &request_handler); |
Jan Jongboom |
0:41f820ea137a | 63 | |
Jan Jongboom |
0:41f820ea137a | 64 | if (res == NSAPI_ERROR_OK) { |
morgandu | 2:ff1a293c4df3 | 65 | SocketAddress ip_addr; |
morgandu | 2:ff1a293c4df3 | 66 | network->get_ip_address(&ip_addr); |
morgandu | 2:ff1a293c4df3 | 67 | printf("Server is listening at http://%s\n", ip_addr.get_ip_address()); |
Jan Jongboom |
0:41f820ea137a | 68 | } |
Jan Jongboom |
0:41f820ea137a | 69 | else { |
Jan Jongboom |
0:41f820ea137a | 70 | printf("Server could not be started... %d\n", res); |
Jan Jongboom |
0:41f820ea137a | 71 | } |
Jan Jongboom |
0:41f820ea137a | 72 | |
morgandu | 2:ff1a293c4df3 | 73 | while(1) ThisThread::sleep_for(1000000); |
Jan Jongboom |
0:41f820ea137a | 74 | } |