Sunday, February 21, 2010

Day 33

I finished the HTTP server on time for my demo on Friday, which went smoothly. This week Micah and I will be in Chicago doing some work for a web based company. Their website hosts coupons for businesses. A business, say Gino's East will post a possible coupon on their website for maybe 50% off a large pizza, and if 300 people sign up for the coupon, then Gino's will carry through with it. Anyone who wants the coupon can sign up for it on the day it is hosted, but tomorrow brings a new coupon and the end to the sales of the old one. They have been very successful, and their site is pretty awesome.

Ok, I will just share some of the basic tid-bits of how the server worked.

I made a very very basic site for the server to host in order to test to make sure it worked. This site had certain requirements which my server had to support. It had to have a few basic pages (like the initial page '/index.html and a homepage), catch incorrect URL requests and respond with a 404, support common MIME types (images, pdf, even small video files), have an Echo page which would spit back out the arguments past to it via the URL, and handle several requests at the same time.

Hosting the basic pages was fairly straight forward once you know how to format a request and response. The most basic request header looked like this:

GET /index.html HTTP/1.1
Host: localhost:80

The form is Request type page requested protocol
Host: resource name : port

The resource name could be localhost or could ben something like www.google.com.

The most basic response header would look like this:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 500

The form is Protocol response code and response type (for an error page the code would be 404 and type Not Found)

Typically there is a flurry of other information like cookie and browser information. After the header would follow the body of the response.

For my home page, and like I said... super basic pages, the response body would just be some html like
<%html><%h1>This is the home page!

Sweet website right?

But then for a page with an image or pdf there were a lot of extra steps. First, in the response header you have to figure out what the page's MIME type will be, and then you have to get the size of the page. An image would be like image/jpeg or image/gif, and then you send the size viz the Content-Length param.

Once you ship the header, you have to send the response body, which will contain the image file. TCP/IP sends all files in little chunks, so you can't just ship the whole image at once. You have to break it up into individual bytes and stream it onto an output stream. This was a bit of a pain at first because even with some of the built in Java support for these IO streams, it can be a bit tricky figuring out which types to use, and how to make all the needed conversions.

For example, to send an image as a byte stream given only its location there are several steps you need to take. First, in Java, you need to create a File object for the image. For this, you need a File Output Stream to read the file and put it into local memory. Then you need to turn that file into a byte stream, and get its size. Finally you write that byte stream into a Byte Array Output Stream, which can then ship the bytes onto your Socket's output stream.

A fairly lengthy process to merely ship photo's from computer to computer, but it is reliable and will work with virtually any file type.

At last, making an echo page is pretty simple. When you receive a request with some input params, they are tide into the URL something like this:
www.justinmmartin.com:80/index.html?a=1&b=2&c=3

where a,b,c are the params. The request has the params in the initial GET line:

GET /index.html?a=1&b=2&c=3 HTTP/1.1

So you can just parse out the string, snatch up the params by splitting the string on certain characters, and then add them back into HTML to be shipped out in your response.

A relatively broad summary for what needs to be done to create a basic server, but hopefully you get the picture.

No comments:

Post a Comment