Assigned: Friday, Apr 15, 2016
Due: Friday, Apr 22, 2016 at 10:30pm
Collaboration: Complete this assignment with your assigned partner. You are expected to work collaboratively, not divide up the assigned work. You may use your classmates as a resource, but please cite them. Sharing of complete or nearly-complete answers is not permitted.
Submitting Your Work: Submit your answers to me by email before the due date. You can submit your work in the body of the email or in an attachment. Please CC your partner on the email.
In this lab you will implement and test a very simple web server using the hypertext transport protocol (HTTP), a text-based application-layer protocol. The basic outline is as follows. Your server will establish a listening socket and wait for connections in an infinite loop (so that it can serve as many as come in while it is waiting). It will then need to accept a connection, then receive and parse the HTTP request. If the request is valid, the server should read the file from the file system and send the file contents (in small chunks, say 2 kilobytes) to the requestor preceded by the appropriate response header lines. If the request is not valid, a 400 error code should be sent instead. If there is some other error reading the file, a 404 error code should be sent.
Create a file called wwwserv.py. The port your server listens on should be a clearly identifiable variable; its value should be greater than 5000, where users have rights to establish port listeners. You will want to make it a variable because if you kill the server, the port will remain “in use” for a short while to ensure that no stray requests for the port filter in.
After creating, binding, and listening on the socket, your server body should act like the following:
while True
Establish connection with a client
Try
Read a request
If the request is invalid
Send a 400 status code, close the connection, and continue
Open the requested file (strip the leading '/' for a relative path)
Send a single response header to the client
Send the file to the client in small chunks
Close the file and connection
Handle IO Error (sending a 404 status code and closing the connection)In lieu of a proper logging system, your server should report simple messages to the console as it takes these steps.
Place a simple HTML file, such as example.html in the same directory as your wwwserv.py. Requests to your web server for files will be relative to the server’s directory. For example, if you used port 8765 and were running your program on the machine rosser, you can request the file via a web browser with the url http://rosser.cs.grinnell.edu:8765/example.html or using telnet, as demonstrated in Kurose and Ross. You can even make such a telnet-based request to a “real” web server, as in the following transcript, which you can try yourself.
curtsinger@turing:~$ telnet www.cs.grinnell.edu 80
Trying 132.161.196.27...
Connected to baran.cs.grinnell.edu.
Escape character is ''.
GET /curtsinger/teaching/2016S/CSC216/labs/simple-server/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
[ ... Lots of intermediate stuff snipped out ...]
</html>
Connection closed by foreign host.
curtsinger@turing:~$ Submit answers to the following questions when you turn in your lab:
GET request. Then go back to your original connection and issue a GET request.
What happened? Why?wwwserv.py filetelnet sessions:
You can find a basic python tutorial at sthurlow.com/python/. Your textbook includes example Python socket code on pages 159–161 (UDP) and 165–167 (TCP).
if (foo == 1 and
bar != ") or
baz == "bish":
print "Success!n"
while 1:
print "Are we there yet?n"myString = "foo bar baz"
myStringSub = myString[2:4] # myStringSub will be "o b"
myStringSub2 = myString[5:] # myStringSub2 will be "ar baz"myString = "foo bar baz"
myStringParts = myString.split()
# myStringParts[0] is "foo", myStringParts[1] is "bar" and myStringParts[2] is "baz"
# len(myStringParts) is 3try:
fileHandle = open( "myFilename" ) # Open file and return a file handle (object)
chunk = fileHandle.read(64) # Read 64 bytes from the file (advancing file pointer)
if chunk == '': # Test whether EOF has been reached (no string data from read method)
print "No more file!"
fileHandle.close() # Close the file
except IOError:
print "Something went wrong (like a file not found or bad permissions)!"This assignment was developed by Jerod Weinman, who adapted it from Janet Davis’ Lab 10: A Simple Web Client and Server and Programming Assignment 1: Web Server by James F. Kurose and Keith W. Ross.