Title: Problem Set 1 - zhttpto Web Server
Date: 2014-01-14
Category: PS
Tags: Problem Sets, Web Server
Author: David Evans and Weilin Xu
Slug: ps1

<div class="due">
Due: 11:59pm on Sunday, 26 January
</div>

## Purpose

The goals of this assignment are to:

- Get everyone in the class set up with the main tools we will use in
  this course including [rust](|filename|../../tools/virtualbox.md) and [using
  github](|filename|../../tools/github.md) to manage your code and
  submit your assignments. 

- Introduce the Rust programming language and get some experience
  writing code in Rust.

- Preview several of the main concepts we will cover in this class
  including: processes, threats, memory management, and network
  protocols.  You are not expected to understand everything we use in
  this assignment, but we hope this exposure will get you to start
  considering more deeply what is going on in computer systems.

Note that this assignment may require you to learn aspects of Rust that
were not covered in class or in the tutorials (although the tutorials
were designed to cover most of what you need to complete this
assignment).  You should be resourceful in searching for helpful
documentation, but we encourage you to use the [scheduled office
hours](https://www.google.com/calendar/embed?src=7ibtm6lnt88vl00h7a0e8n0bc4%40group.calendar.google.com&ctz=America/New_York)
and [class IRC channel](|filename|../../tools/irc.md) to get help.

   <div class="collaboration">

**Collaboration Policy.** For this problem set, everyone should submit
their own assignment.  You should discuss the problems with others and
are expected to help your classmates in ways that benefit their
learning, but not provide answers thoughtlessly.  You should attempt
every problem on your own first before seeking help and must fully
understand everything you submit as your own work.

   </div>

# Getting Started

Before continuing with this assignment, you should:

1. [Set up your computing environment for this course including Rust.](|filename|../../tools/virtualbox.md)

2. [Set up git and your github account.](|filename|../../tools/github.md)

3. [Set up the repository and get the starting code.](|filename|../../tools/private-repos.md)

After finishing these steps, you should have a `ps1` directory that
include the starting `zhttpo.rs` code for this assignment.

Make sure you have [set up the repository and starting
code](|filename|../../tools/private-repos.md) correctly.  For these
problems, you should work in your `ps1` repository, and put all the code
in files in that directory.

## Background

A web server is a program that responds to HTTP requests.  [HTTP
(Hypertext Transfer Protocol)](http://tools.ietf.org/html/rfc2616) is
the protocol that specifies how web clients and servers should
communicate with each other.

A simple web server can just open a socket to listen for requests, and
send back a response when a request arrives.  Tim Berners-Lee led the
development of the first web server, starting in 1990.

The most popular web server today (and since 1996) is
[Apache](http://httpd.apache.org), which is about [2.2 million
lines](http://www.ohloh.net/p/apache) of (mostly C) code.  Your web
server will provide some of the same functionalities as Apache, but will
be much simpler!

# Warm-up

Before working on the web server code, complete [Part 2 of the Rust
tutorial](http://aml3.github.io/RustTutorial/html/02.html).  (We won't
check your code for the other exercises, but you should do them also.)

   <div class="problem">
<b>Problem 0.</b> (write your answer in <span class="file">joiner.rs</span>)
<br>
Complete the last exercise in the tutorial, implementing the joiner program that combines two message shares and outputs the result.
</div>

   <div class="smallquote">
_Just because you're paranoid doesn't mean they aren't after you._ (Joseph Heller)
   </div>

# Making the Zhttpto Web Server

For this assignment, we have provided starting code for a miniscule web
server in `zhttpto.rs` (pronounced "zepto").  Its so small, it doesn't
yet even understand HTTP and responds to every request with the same web
page response.  For this assignment, you will modify the web server code
to serve simple static pages.

Compile (`rustc zhttpto.rs`) and run (`./zhttpto` on Unix) the server.
The server is listening on port 4414.  Open a web browser to
`http://localhost:4414`.  If the server is running correctly, you should
see a welcoming response page.  (We will got more into how network
sockets work and the design of network protocols like HTTP later in the
class.)

In the shell that is running the server, you should see text output
showing the messages received by the server.  The most interesting line
is the _User-Agent_, which is what your web browser is telling the
server.  Typical _User-Agent_ strings incorporate a history of web
browser development.  For example, the request from my Firefox browser
includes: _User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7;
rv:22.0) Gecko/20100101 Firefox/22.0_.

For the short answer (prose) questions, you should create a file
`answers.md` in your `ps1` repository.  The `.md` suffix is for
[Markdown](http://daringfireball.net/projects/markdown/), a convenient
way of generating HTML content.  It is not necessary to do any fancy
formatting, though, you can just use plain text for your answers unless
more is necessary for clarity.  The first lines of your `answers.md`
file should be:

    :::text
    Title: Problem Set 1 Answers
    Author: <your name>

<div class="problem">

<b>Problem 1.</b> (write your answer in <span
class="file">answers.md</span>, clearly marked as <tt>1.</tt>) 
<br>
Copy the <em>User-Agent</em> string reported by your browser.  Explain as many of
the things in that string as you can.

</div>

## Living Dangerously!

Take a look at the provided code in `zhttpto.rs`.  For the rest of the
problem set, you will be modifying that code.

For the next problem, your goal is to add a counter to the server that
increments with each request.  

If you do this in a straightforward way, by declaring a mutable [static
variable](http://static.rust-lang.org/doc/master/rust.html#static-items) 
you are likely to encounter a compile-time errors like this:

    zhttpto.rs:50:27: 50:40 error: use of mutable static requires unsafe function or block
    zhttpto.rs:50                            visitor_count += 1;
                                             ^~~~~~~~~~~~~
    zhttpto.rs:59:50: 59:63 error: use of mutable static requires unsafe function or block
    zhttpto.rs:59                              </body></html>\r\n", visitor_count);
                                                                    ^~~~~~~~~~~~~

<div class="problem"><b>Problem 2.</b> (2. in <span class="file">answers.md</span>) 
<br>
Speculate on why Rust thinks it is unsafe to modify a global variable like this.
</div>

One of the major themes of this course is how to use concurrency safely,
and we will study some of the potential problems caused by mutable
shared memory as well as different strategies for solving them.  For
now, you can just live dangerously and use an [unsafe
block](http://static.rust-lang.org/doc/master/rust.html#unsafe-blocks) around
the dangerous code.

<div class="problem"><b>Problem 3.</b> (modify <span class="file">zhttpto.rs</span>) 
<br>
Modify the server so it maintains a
  count of the number of requests, and adds a message to the response
  that includes a count of the number of requests.  You should see the
  number increase each time your reload the page.

</div>

## Serving Files

Even with the counter, our web server is not very useful!  For the rest
of this assignment, your goal is to modify the web server to serve
requested static pages.

If the first line of the incoming request matches `GET /<path> HTTP/1.1`
where `<path>` is a non-empty file system path.  Your server should
respond by sending the contents of the file `<cwd>/<path>` where `<cwd>`
is the current working directory (where you started the web server) in
the response.

If the incoming request contains an empty path, your server should
respond as it did in the previous problem.

<div class="warning">
<b>Warning!</b> Setting up a server that sends any requested file on your
  machine to anyone on the Internet would normally be a <a href="https://encrypted.google.com/search?hl=en&q=allinurl%3Aauth_user_file.txt">very dangerous</a>
  and <a href="https://duckduckgo.com/?q=wp-config.php+%22MySQL+database+password%22">reckless</a> thing to do!  This is only (hopefully) safe now since you
  are running the server in the VM that does not contain any sensitive
  files.  Nevertheless, it is recommended that you don't announce your IP address or leave your server running except while you are testing it. 
</div>

<div class="problem"><b>Problem 4.</b> (modify <span class="file">zhttpto.rs</span>) 
<br>
Modify the server to respond with requested files, as described above.
</div>

As noted above, your zhttpto server is ridiculously insecure, and will
happily serve any file that is requested.  We'll talk a lot more later
in class about how to improve security, but for now, you should make
some simple improvements to your server to restrict the files it will
serve.

   <div class="problem"><b>Problem 5.</b> (modify <span class="file">zhttpto.rs</span>) 

Modify the server to only serve files that have <tt>.html</tt>
extensions and that are in the directory where the server is started
(including any subirectories of that directory).  If a requests asks for
a file that is not permitted, your server should respond with an error
page (this should use the 403 HTTP response code in place of the 200 in
the normal response; if you are feeling humorous, you can use
[418](https://tools.ietf.org/html/rfc2324) instead.).  
   </div>

### Submission

Use [this form](http://rust-class.org/ps1-submission.html) to submit your problem set.


<!-- 

Remember to commit the changes, and push them to the main repository.
(You can check that everything worked as expected by visiting the
repository through the github website.)

Once you decide to submit your project for grading after commiting some
code and documents, you should add a tag on your code repository with a
version number, and submit your assignment by providing the
corresponding URL using the form.
-->

### Teaser

We will return to the web server in Problem Set 3, where you'll learn
more about network protocols, threads, and managing resources to improve
the functionality and performance of your web server.

<div id="disqus_thread"></div>

<script type="text/javascript">
        /* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
        var disqus_shortname = 'rust-class'; // required: replace example with your forum shortname
	var disqus_url = 'http://www.rust-class.org/pages/ps1.html';

        /* * * DON'T EDIT BELOW THIS LINE * * */
        (function() {
            var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
            dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
            (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
        })();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>


<div class="credits">
This assignment was created by David Evans and Weilin Xu for
University&nbsp;of&nbsp;Virginia cs4414 Fall 2013, and revised for
Spring 2014 by Weilin Xu.
</div>

