HTTP Server

This page explains how to implement an HTTP Server on your mbed. It uses the Networking stack.

Hello World!

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"

EthernetNetIf eth;  
HTTPServer svr;

DigitalOut led1(LED1);

int main() {
  printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  printf("Setup OK\n");
  
  svr.addHandler<SimpleHandler>("/"); //Default handler
  svr.bind(80);
  
  printf("Listening...\n");
    
  Timer tm;
  tm.start();
  //Listen indefinitely
  while(true)
  {
    Net::poll();
    if(tm.read()>.5)
    {
      led1=!led1; //Show that we are alive
      tm.start();
    }
  }
  
  return 0;
}

This program is available here:

Packages

Precompiled version:

» Import this library into a programHTTPServer

This library is deprecated.

Library

Architecture

The HTTPServer is composed of:

  • The actual server (HTTPServer)
  • A request dispatcher, instanciated on each request (HTTPRequestDispatcher)
  • Request handlers instanciated by the dispatcher(deriving from HTTPRequestHandler)

HTTP Server Requests Handlers

  • Simple "Hello world" handler
  • Filesystem handler
  • RPC handler

You can also Create your custom handler.

Includes

#include "HTTPServer.h"

Reference

» Import this program

Public Member Functions

  HTTPServer ()
  Instantiates the HTTP Server.
template<typename T >
void  addHandler (const char *path)
  Adds a handler.
void  bind (int port=80)
  Starts listening.

Bind the server to port port and start listening. This function returns immediately. You must call Net::poll() regularly after this so that the server serves requests properly.

Examples

This example sets the server up and demonstrates the use of all-three kinds of handlers.

The local file system is available either under the /files/ path. Since FSHandler is the default handler here, the mbed file system (/webfs/) is made available on the root path of the server as well, so mbed.htm is available at the URLs http://a.b.c.d/files/mbed.htm and http://a.b.c.d/mbed.htm, where a.b.c.d is your mbed's IP address.

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"

DigitalOut led1(LED1, "led1");
DigitalOut led2(LED2, "led2");
DigitalOut led3(LED3, "led3");
DigitalOut led4(LED4, "led4");

LocalFileSystem fs("webfs");

EthernetNetIf eth;  
HTTPServer svr;

int main() {
  Base::add_rpc_class<DigitalOut>();

  printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  printf("Setup OK\n");
  
  FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path
  FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path
  
  svr.addHandler<SimpleHandler>("/hello");
  svr.addHandler<RPCHandler>("/rpc");
  svr.addHandler<FSHandler>("/files");
  svr.addHandler<FSHandler>("/"); //Default handler
  //Example : Access to mbed.htm : http://a.b.c.d/mbed.htm or http://a.b.c.d/files/mbed.htm
  
  svr.bind(80);
  
  printf("Listening...\n");
    
  Timer tm;
  tm.start();
  //Listen indefinitely
  while(true)
  {
    Net::poll();
    if(tm.read()>.5)
    {
      led1=!led1; //Show that we are alive
      tm.start();
    }
  }
  
  return 0;

}

You can also directly import this example there:

Robustness

Although this HTTP Server should still be considered in beta phasis, it has been built for robustness. A good test is this web page that you can use with the previous example: put it on your mbed and open it in your browser (at an address like http://a.b.c.d/webfs/stress.htm): http://mbed.org/media/uploads/donatien/stress.htm.

It will start an asynchronous HTTP Request every 100ms, sending RPC commands to set the leds on and off. You will see that all requests are not successfully processed, but the server will not crash and will remain up and running properly after you close the page.

License





43 comments:

05 Jul 2010

Donatiens,

How can I set the server name? How can I get the server IP?

tks

05 Jul 2010

Hi,

I forgot to update the Ethernet page, but there is a getIp() function that you can use to retrieve it. Otherwise you can see it on the serial debug output. What do you mean with the server's name? If it's DNS, you have to register the mbed's IP against a proper DNS server.

Donatien

06 Aug 2010

Does every LPC1768 board have a built in ip address? Or is this assignable? Where is this already explained? I am very new to this product and this forum...

10 Aug 2010

user C Neroth wrote:

Does every LPC1768 board have a built in ip address? Or is this assignable? Where is this already explained? I am very new to this product and this forum...

By default, the server will request an IP address using DHCP. You can see the address it has been allocated on the console output. Of course this only works if your network has a DHCP server.

Alternatively you can specify a static IP address when you instantiate the server.

05 Sep 2010

Hi,

the following sequence: <reset>

http://192.168.1.74/rpc/ webfs led4 led3 led2 led1 DigitalOut Base

http://192.168.1.74/rpc/DigitalOut new

http://192.168.1.74/rpc/DigitalOut/new,5 obj10005718

http://192.168.1.74/rpc/obj10005718 write read delete

http://192.168.1.74/rpc/obj10005718/read

hangs the mbed; led1 stops blinking.

I suspect "/rpc/DigitalOut/new,5" is wrong. maybe a pointer to the "new" syntax? I also would like to be able to give the new object a name.

Anyone can comment please?

Art.

05 Sep 2010

Hi, I think i found the first question after reading http://mbed.org/projects/libraries/svn/mbed/trunk/PinNames.h It should have been http://192.168.1.74/rpc/DigitalOut/new,p5 My second question stands. Can I apply a name to the new object?

thanks, Art.

06 Oct 2010

I imported the httpserverhelloworld and compiled it,unchanged. when loaded to my mbed, I get these debug comments in the serial port

Setting up... [..\fwk\if\eth\EthernetNetIf.cpp:setup@86] HW Addr is : 00:02:f7:f0:43:d1. [..\fwk\if\eth\EthernetNetIf.cpp:setup@99] DHCP Started, waiting for IP... [..\fwk\if\eth\EthernetNetIf.cpp:setup@131]

after maybe 5-10 seconds, my mbed shows a runtime error by flashing all 4 LEDs in alternating patterns.

and sometimes I see this a little later: Timeout. Error -65534 in setup.

Is this due to a program error or just a problem linking to the router?

06 Oct 2010

NVM... it was a wiring issue. corrected the wiring and the server runs correctly now.

11 Oct 2010

Finaly got this working, by using my internet browser, as above ..

how could i make this more controlable from a PC Application (Delphi)

I have got the serial RPC to work, and i hoped to be able to create a simmilar method of communication ! does any one have a solution ?

Cheers Ceri.

17 Oct 2010

The code on this page:

http://mbed.org/users/donatien/programs/NetHttpServerExample/5zb4a/docs/HttpServerExample_8cpp_source.html

does this:

svr.addHandler<FSHandler>("");

whereas the code on this page does this:

svr.addHandler<FSHandler>("/");

Is that significant?

Also, while I'm here, I've found that if I put a file named "hello.html" on my mbed it can't be served by the HTTPServer, but if I name it "hello.htm" then it works. I suspect this has something to do with the implementation of LocalFileSystem, and probably for good reason, but it had me stumped for a while.

Rob.

19 Oct 2010

Hello,

I got the HTTP server working on my mbed and can acces it with IE. Does anybody know how to configure my router so that I can set up a virtual server to the mbed? The local listening port should be 80 but what should the remote port be? I want to control the mbed from over the internet, from everywhere I am (just like with remote desktop control to remotely control a PC)

Greetings

27 Oct 2010

Hi,

Now I'm wondering, does it work with an RPC server because if I just type in the DNS (or wan ip) of my home router and then try to forword it to my mbed connected to the router at home, it doesn't work. Does anybody know how to do this? I want to control my mbed from leuven (and anywhere in the world)

06 Nov 2010

I managed to run the demo HTTP Server. As I learned from the HTTPRequestHandler instruction that

svr.addHandler<SimpleHandler>("/hello");

returns an "hello" message.

Now I wonder where the "Hello World!" response of my webserver (http://192.168.1.51/) comes from since the demo code

svr.addHandler<SimpleHandler>("/"); Default handler

has not even a simple letter after the slash? The mbed does´nt contain an index.htm file!? By the way at this state the filesystem is not activated.

chris

07 Nov 2010

Hi Chris,

The "Hello World!" is coming out of the SimpleHandler. If you want to let the mbed serve HTML files you have to link an FSHandler to the LocalFileSystem (see the HTTPServerExample from Donatien).

H

07 Nov 2010

Thanx Henny,

I located it now in the source: 00040 const char* resp = "Hello world !"; From the description I expected to pass the message as argument - did´nt expect to see it hard coded ;-)

Chris

15 Nov 2010

MULTIPLE CONNECTIONS

Hi Donatien,

Is the Http-Server able to manage multiple connections at the same time? In case I want to connect it to Internet and two or more clients send a "get request" at the same time, what happens?

Best Regards Sergio

13 Dec 2010

I think there's an issue that the maximum message size is 980 bytes. The mbed tells me I'm going to send about 1200 bytes but Firefox only receives 980 bytes...

15 Jan 2011

Seems that HTTPServer cannot deal out images ... don't really know why. Can someone explain?

09 Feb 2011

I was wondering what does "Net::poll" command do ?

05 May 2011

The stress.html filementioned is missing. Anyone has an example of a html triggering RPC? Just to see how it looks like

18 May 2011

Hello, I tried to combine the HTTPServer with the RPCLibrary and custom rpc functions. Everything works fine up until the point, when I try to include either <iostream> or <fstream> into the project. Whenever I do that and call my custom rpc function "dimLed" via web-browser, the mbed crashes. As soon as I comment out the "#include <iostream>" and "#include <fstream>" statements and the corresponding lines further donwn in the code( for example: "cout << "Unable to open file";" , "ifstream myfile ("/local/20110519.txt");" , ect....) everything works fine again. Has anybody made similar experiences?? Does anybody have a suggestion what the problem could be here?

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPServer.h"
#include "RPCFunction.h"
#include <iostream>
#include <fstream>

DigitalOut myled(LED1);

LocalFileSystem local("local");               // Create the local filesystem under the name "local"

EthernetNetIf eth;  
HTTPServer svr;

//setting up custom rpc function
//***************************************************
//Create a function of the required format
void dimLed(char * input, char * output);
//Attach it to an RPC object
RPCFunction rpc_dimLed(&dimLed, "LedDimmer");

void dimLed(char * input, char * output){
   float x;
   sscanf(input, "%f", &x);
   PwmOut myLed3 = LED3;
   myLed3 = x;
   sprintf(output, "%f", x);
}

void GetGlobalDateArray ()
{        
       ifstream myfile ("/local/20110519.txt");
    
        if (myfile.is_open()) 
        {     
            while ( myfile.good() ) 
            {
                //do something here
            }
            myfile.close();
        } 
        else 
        {
            cout << "Unable to open file";
        }    
}

int main() 
{ 
  Base::add_rpc_class<DigitalOut>();

  printf("Setting up...\n");
  EthernetErr ethErr = eth.setup();
  if(ethErr)
  {
    printf("Error %d in setup.\n", ethErr);
    return -1;
  }
  printf("Setup OK\n");

  svr.addHandler<RPCHandler>("/rpc");
  svr.bind(80);
  
  printf("Listening...\n");
  
  void GetGlobalDateArray ()
   
  Timer tm;
  tm.start();
  //Listen indefinitely
  while(true)
  { Net::poll();
    if(tm.read()>.5)
    {
      myled=!myled; //Show that we are alive
      tm.start();
    }
  }
   
}
26 Aug 2011

Hi Can someone (Donatien ?) explain in a wiki the above lines, for me, if I put in a directory /files, nothing works, it works only on the root / :

  FSHandler::mount("/webfs", "/files"); //Mount /webfs path on /files web path
  FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path
  
  svr.addHandler<SimpleHandler>("/hello");
  svr.addHandler<RPCHandler>("/rpc");
  svr.addHandler<FSHandler>("/files");
  svr.addHandler<FSHandler>("/"); //Default handler

Also how to add code, to the example given above, to call a C function on an html form button clic

Thanks

27 Aug 2011

I found an answer to my 2nd question : For the C function called from an html

html

function X10_On()
{
var req = new XMLHttpRequest();
var cmd= "http://" + location.host + "/rpc/foo/run";
	req.open("GET", cmd, true);
	req.send("");
}
... in the form add :
 X10 Lampe Chambre :
 <input type="button" value="On" id="FormButtonX10" onclick="X10_On()">
}

c

#include "RPCFunction.h"
...

//Create a function of the required format
void foo(char * input, char * output);
//Attach it to an RPC object
RPCFunction rpc_foo(&foo, "foo");

...

void foo(char * input, char * output) {
    int x,y;
    sscanf(input, "%i, %i", &x, &y);
    //Do something here......
    led2 = 0;
    led3 = 1;
    sprintf(output, "%i, %i", x, y );
}

You can of course deal with the parameter of the RPC function that you scanned !

main code from http://mbed.org/forum/mbed/post/11607/

28 Aug 2011

is there any reason it would freeze on svr.bind(80) ?

The code compiles correctly when I use the example. But when I integrate it into my code it freezes.

It is the first thing in the main()

my ram usage is @ 28kb

------

turns out it was a ram iSsue. To get around this I designated some of my arrays to the USB's RAM.

25 Oct 2011

Hi guys,

Can anyone tell me if there is a way for the HttpServer to handle files from some Directory, instead of serving files from the FLASH root ("/") I would also like to provide files from "/css", "/js", etc. I'm not figuring this out, from the example it seems that I can create virtual URL addresses, but all point to the root! Maybe I'm doing something wrong ?

  FSHandler::mount("/webfs", "/css"); 
  FSHandler::mount("/webfs", "/"); //Mount /webfs path on web root path

  httpserver.addHandler<FSHandler>("/css");
  httpserver.addHandler<FSHandler>("/"); //Default handler  

http://192.168.1.100/css/ will show the index.htm file from the FLASH root directory "/" and not from the "/css".

TIA.

25 Oct 2011

@Nelson Hi

Did you try

svr.addHandler<FSHandler>("/css");
25 Oct 2011

Yes, I did, I renamed my HttpServer object from "srv" to "httpserver", you can see in my previous code snippet that I have both "/css" and "/" ... I need to provide files from the root (index.htm) and others files form different directories such as /css, /js, /images, kind like a micro webserver would work, javascript, css and image files are organized in folders!

The main reason for this is for html porting, I may test the layout on a real webserver and then copy the structure directly (or from GIT/SVN repo) to MBed Flash and run it there!

05 Nov 2011

Hi all - I'm struggling with robustness - when a second PC attempts to access the server the mbed freezes. It also freezes sometimes when I do a refresh on the browser. Any ideas how I can solve this?

06 Nov 2011

The NetServices Server (and client) are just not robust enough, nor do they appear to be maintained.

This is a great shame, because the really hard things - the Ethernet driver, and the underlying lwIP stack - are perfectly good.

Please have a look at Michael Wei's HTTPServer - with direct lwIP API use.

http://mbed.org/users/no2chem/programs/EthernetTester/6095m/docs/main_8cpp_source.html

This bypasses the flaky C++ NetServices code.

I can vouch that Michael's server is very tough - although I have only used it with one client.

02 Feb 2012

Is there a way I can specify a home page, such as "home.htm"? This way I would only need to enter my IP: "192.168.0.113" instead of "192.168.0.113/home.htm" and still reach the home page.

Just found the answer I was looking for. "index.htm"

05 Feb 2012

Hi all

What does net::poll() function do?. Which is the library to it belongs?. I found no information about it.

12 Feb 2012

user Dario Delvalle wrote:

Hi all

What does net::poll() function do?. Which is the library to it belongs?. I found no information about it.

Hi Dario, This question has been asked a few times so I thought that I'd actually put an answer in: - The NetServices library is polled. To execute the polling action, the net::poll() is called - preferably very often (ie every iteration of the execution loop in main() ) If there is data on the Ethernet (and thus in the TCP/IP stack) that data will be processed when this is called.

This includes parsing the inbound data, determining if there is a handler for the request and then executing that handler. As an example, if an HTTP handler is defined and a request comes in, it then locates an appropriate HTTP_Handler and returns a response.

The source code for this call can be found in the NetServices library: /core in the net.h and net.cpp files.

Regards,

Anthony

27 Feb 2012

I have a server running on LAN, but now I need that can be accessed from any network and I have no idea how to do it, someone could help me?, Thanks!

01 Apr 2012

Hi, I would like to make a new RequestHander as your SimpleHandler. So, I need a sample source code of SimpleHander.cpp, because I can't understand more description by articles in this site.

01 Apr 2012

user Hirofumi Inomata wrote:

Hi, I would like to make a new RequestHander as your SimpleHandler. So, I need a sample source code of SimpleHander.cpp, because I can't understand more description by articles in this site.

I had found it in the url, http://mbed.org/users/segundo/libraries/NetServices/ljhqix/docs/SimpleHandler_8cpp_source.html

15 May 2012

file system handler (FShandler)serves only html files?. how it works exactly? Regards

10 Jun 2012

Do you have an example for the RPC DigitalOut so I can create additional functions like PwmOut and DigitalIn?

27 Jun 2012

user Dario Delvalle wrote:

file system handler (FShandler)serves only html files?. how it works exactly? Regards

it serves any files. If you want web browser no display the file (image, text, etc) you have to add in the header response the field "content-disposition".

27 Jun 2012

user s.j.saunders@... wrote:

Do you have an example for the RPC DigitalOut so I can create additional functions like PwmOut and DigitalIn?

take a look at this http://mbed.org/cookbook/RPC-Interface-Library.

11 Sep 2012

Hi, I'm a user of the mbed for few days,and I try to communicate with the card by ethernet The mbed answer to the ping, but I didn't manage to put an htm file in it yet , can someone tell me how I can do it. Thanks for your answers.

12 Sep 2012

Hi, sorry for the previous question, the answer is obvious.

30 Sep 2012

Hi guys, This library use the deprecated NetServices, somebody know if exists another HTTPServer library that work with the new library EthernetInterface and RTOS? Thanks.

20 Nov 2012

Hey guys,

I have this problem at hand and haven't been able to figure out how to work it out. The problem is as follows:

My mBed is connected toa temperature sensor. It is also connected to an ethernet port in my university and my university gives me a static IP (the DNS, the gateway and the network mask are unknown at this point in time) What I want to do is I want to connect to the mBed from another computer in a different university and fetch the data of the temperature sensor. The computer in the other university will send a request (such as "abc"). Only when this msg is validated should the mbed respond with the data.

What is the best way of doing this? If someone can help me with a code then it would be great. I am pretty naive at this side of computer science!