CMSC 433 - Project 2 - Java Networking
Due Feb. 27, 6:00PM
Write a scaled-down version of an http server. It should accept requests of the
form:
http://hostName:portNum/className/argString
as
in
http://marlowe:13301/Foobar/Args
In response to this request, the server should create an instance r of the class
Foobar, invoke r.setArg("Args"), invoke r.setOutputStream(...) with the
output stream for the http request, and then invoke new Thread(r).start().
Alternatively, if you want to do a slightly simpler version of the
project, just invoke r.run() rather than creating a thread. If you don't create
threads, you don't have to worry about synchronization. If you do the
non-threaded version of the project, there is a 5 point deduction from your
grade (bugs in
your use of threads could cost you more than 5 points, so perhaps trying a
non-threaded version first is a good idea).
The port your server listens on should be taken from the command line, using
the -D switch to java, as in project 1.
To avoid conflicts, when testing
you should use a port number calculated from your account
number as port x33yy, where x is your section number (1 or 2) and yy is your account number.
For example, if your account is as3317, listen to port 13317.
The server objects which can be used must all implement the interface:
public interface MiniServlet extends Runnable {
void setArg(String arg);
void setOutputStream(java.io.OutputStream out);
}
The servlets must be loaded dynamically (using Class.forName(...)). This
will enable us to invoke other MiniServlets besides the ones you will write.
If the code for the MiniServlet cannot be found (i.e. an unknown MiniServlet is
invoked) return the string "Content-type: text/plain" + "\n" + "Unknown
MiniServlet invoked" + "\n".
We've provided you with some
classes:
Note that we will test your MiniServlets using our web server, and your
webserver using our MiniServlets.
You also need to write some servlets that implement the MiniServlet interface.
-
Print - Takes one argument, a file name for a file containing ASCII text (e.g.,
http://marlowe.cs.umd.edu:13317/Print/fileName.html). Print then reads the
file and prints it to the output stream with Content-type: text/plain, unless the file name ends in ".html", in
which case it should be Content-type: text/html. It should reject a
request to print any file that ends in ".java" or contains
java.io.File.separatorChar (for security reasons). If the file does not exist
or if the request is rejected, then return the string "File not found or
request rejected\n", passing Content-type:text/plain.
-
ImageReplace - Takes one argument, which is a URL string. Your code will retrieve the requested
URL (if the URL can't be retrieved then
return the string "File not found\n" with Content-type text/plain), and if the retrieved document has Content-type: text/html it will
first replace any images in the
document (tags of the form <img ..... src="imageURL" ..... >) with
hyperlinks for the images, displaying the link name (e.g., <a href="modifiedImageURL">modifiedImageURL</a>),
and then return (i.e. print to the output stream) the Content-type and the potentially
modified contents. To do this you'll need to examine the imageURL to
determine whether it's a relative or absolute URL. If it's relative you
should make it absolute by prepending some part of the URL from the original
ImageReplace request. If the Content-type of the retrieved document is
text/plain, return it without changes, passing the Content-type
received with the document. Otherwise return the string "Unknown
Content-type\n", passing Content-type: text/plain.
-
ProxyWithCache - takes one argument, which is either a URL or one of the strings
"clear" or "dump". This MiniServlet acts as a caching proxy, meaning that it maintains a
cache of all the documents it has retrieved and returned since the previous
"clear" command. If the argument is a URL, the URL is looked
up in the cache, and if the URL is found the document is returned on the
output stream with its stored Content-type. If the URL is not found in the
cache, the requested URL is retrieved. If the URL can't be retrieved then
return the string "File not found\n" with Content-type text/plain.
Otherwise, if the Content-type of the retrieved
document is text/plain or
text/html then insert it into the cache (along with
its Content-type), and return it on the output stream with its
Content-type. Otherwise, do not cache the URL and return the string "Unknown
Content-type\n", passing Content-type: text/plain. If the argument string is "clear", all
entries in the cache are removed, and the string "Content-type:
text/plain" + "\n" + Cache cleared" + "\n" is returned.
Finally, if the argument string is "dump", return the URLs that are currently stored
in the cache in sorted order (as defined by String.compareTo()), separated
by newlines, passing Content-type: text/plain. If the cache is empty,
return the string "Content-type:
text/plain" + "\n" + Cache is empty" + "\n".
For any MiniServlet that requires retrieval of a document from an http server, a
failure to connect to the http server should cause up to 3 retries (catch the
exception and retry up to 3 more times after the first failure to connect). If
no connection can be made return the string
"Content-type: text/plain" + "\n" + "Connection could
not be established" + "\n".
We will make a server available on port 13301 of amoeba.cs.umd.edu.
Here are some sample queries (don't necessarily try these in the order shown):
You will need to read the Java API for the URL class and you will need to
read http://www.jmarshall.com/easy/http/
to understand what your web server needs to return to clients. You should also
look at the output of RawProxy. RawProxy shows you the http headers returned by a request.
Note: You don't have to implement RawProxy.
Web Accessibility