|
|
 |
|
Project 4: The HTTPD Service
The HTTPD service provides web browser access to running services. Among other
things, this means you can use it to examine services running on remote machines
as easily as on the local one, which can be handy for debugging.
For example, it's hard to know which component is the problem when your resolve
a name and don't get the answer you expect.
By dumping the current DDNS subtree maintained by a DDNS Service, and then the
DDNS Resolver cache contents, you get at least a clue as to which one is causing problems..
Enabling Web Access to Services
To allow a browser to talk to one of your services, you need to do three things:
- Declare the service's Java class as implementing the HTTPProviderInterface interface.
For example,
public class DDNSService extends NetLoadableService
implements HTTPProviderInterface,DDSNServiceInterface
- Implement one routine:
/**
* Serves web pages. The uriArray is the parsed URI:
* The 0th element is always null.
* The 1st element names this service (e.g., "ddns").
* Elements beyond that are optional, and their use depends
* on the service.
*/
@Override
public String httpServe(String[] uriArray) {...}
The returned string is what will displayed by the browser. It is assumed
to be plain text, unless it begins with "<html>" (in which case it's taken
to be an HTML page).
- Make sure configuration file field net.services includes edu.uw.cs.cse461.httpd.HTTPDService.
It can also be useful to bring up your HTTPD service on a well known port. (The root uses port 46199.)
Configuration file field httpd.port can be used to indicate to you want the HTTPD service to use a specific
port. (Otherwise, it uses an ephemeral port.)
Implementation
A small web server implementation,
nanoHTTPD,
was included in your project as part of the original source
distribution.
I've made one small modification to that source (to allow request of a particular port number),
and provided a wrapper class, HTTPDService.
nano opens a TCP server socket and waits for HTTP requests on it. When it gets one, it invokes
its server() method of HTTPDService, passing it the requested URI.
HTTPDService parses the URI to determine which service to direct it to.
In particular, it assumes that the first component of the URI is the name of a service or application
that (a) has registered itself with NetBase, and (b) implements the HTTPDServiceProviderInterface.
It uses the first component of the URI to fetch a handle to the service or app from NetBase,
then invokes its httpServe() method, handing it the parsed URI components.
httpServe() returns a String representing the web page to be returned to the browser.
If the String begins with "<html>", it's assumed the String is HTML, and an HTML response is returned.
Otherwise, it's assumed the String contains plain text, and that is returned to the browser.
For example, if the web server on a system running name server with SOA jz.uw12au.cse461
creates port 192.168.1.77:36128, typing in the browser the URI http://192.168.1.77:36128/ddns
will invoke the httpServe() method of service ddns (assuming it exists).
The full implementation of that method in my code is:
is:
@Override
public String httpServe(String[] uriArray) { return toString();}
What you see in the browser is a dump of the name server's resource records, because that's what my toString()
produces.
Solution Web Pages
The solution code (including the cse461.cs server)
implements at least the following web pages. (On cse461.cs, the port is 46199.)
http://<hostname>:<port>/ddnsresolver/<ddns name>
Causes the remote DDNS resolver instance to resolve the ddns name and return the result.
Allows you to test your DDNS Resolver Service implementation.
http://<hostname>:<port>/ddns
Dumps the current name mappings for the DDNS Resolver Service on the host.
Additionally, as of V1.06:
http://<hostname>:<port> or
http://<hostname>:<port>/httpd
Produces a page of links to all services and applications that are capable of producing web pages.
The Web Server Name Subtree
We follow the usual convention of prefixing a name with www. to indicate
an HTTPD service. For instance, the root's HTTPD service has name www..
Unfortunately, this convention means you can't determine whether there is a
web server for a zone unless that zone is at least partially working. For instance,
if the zone name is jz.uw12au.cse461, the the HTTPD service would have
naem www.jz.uw12au.cse461.. That name can't be resolved unless the
zone is sufficiently functional.
To help alleviate this problem, we adopt the convention that, when possible,
the port 46199 should be used for the HTTPD service. This isn't always
possible, of course; for instance, two zones running on the same machine
can't both be allocated port 46199. If you can determine the IP of the zone,
then http://zoneip:46199/ is a pretty good guess for the HTTPD
service (should the zone be running one).
|