Now that you have learned basic socket programming using TCP and HTTP,
you will use libmicrohttpd
to build a web server. To do this,
you must build the library and link against it. You then will need to write
the web server, using microhttpd.h
as the interface to the library.
Documentation for libmicrohttpd is minimal, but can be found in the header
file, microhttpd.h
in the src/include directory. There are also
simple examples in the src
directory.
To get started, do the following:
select
externally,
2 = Use select
internally--this means you will run this
from a seperate thread,
3 = Use a thread per connectionfd_set
for
reading, writing and exceptions. You pass these into libmicrohttpd which
sets its sockets correctly in your fd_set
s. You then can
use select()
in your own code for reading and writing.
select
to you so that you simply call MHD_run once each iteration through your
main loop and it handles the processing of connections for you.
The image to the right is what I call a (B)roken UML (BUML) diagram to illustrate the sequence of events that occur between the daemon and the client (in this case, your web server). Note that the dark arrow heads indicate the direction of a function call (i.e., who made the function call) and time increases from the top of the figure down towards the bottom of the figure.
Initially the Web Server calls MHD_start_daemon
followed by MHD_run
. At some point, a TCP connection is
established with the daemon, which calls
the AcceptPolicyCallback
function suplied by the
daemon. Assuming this returns MHD_YES
, the connection is
established and an HTTP request is received over the TCP connection.
For the purposes of this project, your AcceptPolicyCallback function
should always return MHD_YES.
When a request is received by libmicrohttpd, it determines the type
of request and calls the AccessHandlerCallback, which passes the
session to the Web Server. The Web Server will not return
from this function until it has optionally called the functions listed
in the figure, including MHD_queue_response
. In essence,
a single request will cause a single response to be created. After
MHD_queue_response
is called, the daemon will send the
response to the network. Note that if the Web Server created
the response object by using MHD_create_response_from_callback
,
the daemon will begin writing the response object to the
network and continually call
the MHD_ContentReaderCallback
function until the Web
Server has given it all of its data.
In order to handle requests, the Web Server registers Handlers.
When a request is received, it will specify a URI on the first line.
URIs on this line always begin with '/'. The Web Server registers
prefixes which determine which handler is called. To register
a prefix, the server calls MHD_register_handler
(and to
unregister a prefix, it calls MHD_unregister_handler
).
For example, a Web Server might register "/" and "/images" as the first and second handlers respectively. Anything beginning with "/images" would call the second handler while anything begining with just "/" would call the first handler.
You will be graded on the following: