You are here: Home / Past Courses / Fall 2013 - ECPE 177 / Projects / Project 1 - HTTP Server

Project 1 - HTTP Server

Project Objectives

In this project, you will be implementing a simple web server in the Python3 programming language. In doing so, you will gain: 

  • Hands-on experience with the Hyper Text Transfer Protocol (HTTP)
  • Hands-on experience with TCP sockets
  • Hands-on experience with Python programming, including details such as file I/O, string parsing, and command-line argument parsing.

To support these objectives, you are not allowed to use any pre-built HTTP, URL-parsing, or socket management libraries.

 

Requirements

The HTTP 1.1 protocol is extremely detailed and complex.  You could spend a week reading RFC 2616 which formally describes the protocol. Fortunately, there is no need to do so for this project, as we are only going to be implementing a tiny subset of the standard. Your high-level goal is the following:

Implement a sufficient part of the HTTP 1.1 protocol in your web server such that a user could download the official "Project 1 demo website" (describe in Testing, below) using any of the following web browsers: Chrome, Firefox, Safari, and Internet Explorer. Your server should faithfully transmit any file requested by the web browser when downloading the demo website, which may include HTML, CSS, Javascript, or images. Once rendered by the browser, the website hosted by your web server should be indistinguishable when compared to the site hosted on the original web server. Any broken images, missing text, JavaScript warnings, etc... will be taken as an indication that your server is corrupting the files it transmits.  (Obviously, if the web server is corrupting files, then we cannot expect the web browser to be able to display a perfect-looking website)

 

You must use the Python 3 programming language, specifically version 3.2.x or newer, which should be widely available.
(Note: On most systems, the binary will be called python3.  To be safe, run python --version and python3 --version at the command line to see what you have.) 

You must develop your web server on a Linux operating system.  Either a virtual machine or dual-boot arrangement is acceptable. (Your assignments will be graded on a Ubuntu 12.04 LTS machine, if you are interested in developing in exactly the same environment.)

You must support web browsers sending requests using version 1.1 of the HTTP protocol, and accept connections (and deliver responses) via TCP.

You must support HTTP status codes 200 and 404 as possible responses by your server.

A single-threaded solution that handles requests sequentially is acceptable in Project 1 for full credit.  (Note, however, that later projects will involve converting your web server into a design that can handle concurrent requests, so a bit of advanced planning here may simplify work later...)

It is acceptable, in this solution, for your web server to close the connection upon completing a single request.  In fact, if you only have a single-threaded web server, this simplification is necessary. (Note, however, that the HTTP/1.1 standard allows a web browser to send multiple sequential requests in a single connection, so we will be implementing this functionality in a later project.)

Your web server should be runnable from a file called server.py.  You can import additional Python files (so that your entire project is not in a single file), but the user should not invoke these helper files directly.

Listening on port 80 requires root-level access.  Because I don't want to run your programs with root-level permissions while grading, you should instead listen on port 8080, which does not require root access.  In your web browser, access your server by specifying the port number in the URL, e.g. http://localhost:8080/file.html

The following command-line arguments should be supported:
  • --help   :  This argument will print out a helpful message describing what arguments the program takes
  • --base=/path/to/directory   : This argument allows you to specify the base directory where the website is stored on the server
  • --port=####   : This argument allows you to specify the port number the web server listens on

You should use the argparse Python library instead of parsing the arguments yourself. Argparse will provide the --help and --version arguments for "free".

Example invocations:

$ ./server.py --help
usage: server.py [-h] [--version] [--base BASE_DIR] [--port PORT]

Web Server for COMP/ECPE 177

optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--base BASE_DIR Base dir containing website
--port PORT Port number to listen on
$ ./server.py --base=/home/shafer/ecpe177_fall2013/website/html --port=80
<< Server runs and starts listening on port 80 >> 

 

Restrictions

You cannot use the following Python built-in modules in this course. Zero points will be awarded for an assignment that uses: 

In addition to the list above, you cannot use pre-written HTTP server, URL parsing, or socket management libraries obtained from other online sources.

This assignment is to completed individually. You can discuss problems and potential solutions with other students, but you cannot share completed programs or significant pieces of completed code.

See the honor code in the syllabus for specific rules on re-using code found online or in other references. (Specifically, the amount of code reused, and the policy for documenting the reuse)

 

Testing

The official "Project 1 Demo Website" is the five page design template (ignoring the sixth "Download Now!" link).   You can view the demo website live at http://luiszuno.com/themes/vintage/.  

project1-website.jpg

This is a fake website provided as a design example.  However, for our purposes, it looks good, and provides all the types of files a real website would have, including:

  • HTML files containing the page content
  • Cascading style sheets (CSS) that specify format for the page content
  • JavaScript programs that enable animation, drop-down menus, and other glitz
  • Images in a variety of formats

Browse the real website and remember how it looks.  When you access the same files, using the same web browser, but delivered through *your* web server, you want the result to look the same!

To test, follow this process:

  1. Downloadable the Demo Website from the Sakai resources section.  It should be called website.zip
  2. Unzip the website archive. Remember where you put it.  (You can browse it to get a sense of the files and directory structure.  The "html" subdirectory has the important files.)
  3. Run your web server.  Specify on the command line the root directory of your website in this demo site. For example: 
    ./server.py --base=/home/myusername/website/html
  4. Run your web browser and access the following URLs for testing.   Be sure to browse the site after it appears, to ensure the links work!
    http://127.0.0.1:8080/index.html
    http://localhost:8080/index.html 
    http://localhost:8080/   (No file name is specified here.  What should your server do?)

 

Tip:  It is *unlikely* that your web server will work perfectly on the first attempt.  I suggest identifying and accessing individual CSS files, JavaScript files, images, and HTML files.   Load one at a time.  Once you are convinced that each type of resource is being served correctly, then go and test the entire site.

 

Resources

See the main resource page for links that helped me when developing my solution.

See also: example Python client and example Python server

 

Submission

In standard Linux style, submit your final project as a .tar.gz compressed archive.

To create the archive, assuming your files are in the folder "project1", run:

$ tar -cvzf project1.tar.gz project1

Once created, upload this file to the corresponding Sakai assignment and submit.

To extract your archive, I will run:

$ tar -xvf project1.tar.gz