Making HTTP Requests with Telnet

In case you didn't know, I am a big fan of curl. You can check out the very basic slides from a talk I gave here along with some example code. Whether I'm playing with a new API or explaining how requests on the internet work, curl has been my goto tool and learning how to "actually" use it has paid off greatly. Today however, I discovered something new to use as an aid to teach HTTP.

While studying for an Internet Technology midterm, I came across a slide that mentioned telnet. In case you aren't familiar with telnet, it is a tool that allows you to open a TCP connection with a server. Now I've used telnet a few times to show someone how to manually send an email through SMTP, and to connect to a TCP socket for one reason or another, but I'd never really thought about using it to demonstrate HTTP requests. Let's take an example.

$ telnet example.com 80
Trying 93.184.216.119...
Connected to example.com.
Escape character is '^]'.

Cool, we've opened a TCP connection over port 80, which is HTTP. Now let's make our HTTP request!

If you aren't familiar with what an actual HTTP request looks like, it follows the pattern of, method url version. For our example, we are going to make a request using the GET method, on the base url (/), using HTTP version 1.1.

$ GET / HTTP/1.1

The next thing we need to do is add the Host header. This header is used by the web server to properly match the request and serve the right response. The host is just the domain name.

$ Host: example.com

Now we need to enter an extra new line to let the web server know that we are done with our request, and BOOM!

HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: max-age=604800
Content-Type: text/html
Date: Fri, 14 Mar 2014 05:51:23 GMT
Etag: "359670651"
Expires: Fri, 21 Mar 2014 05:51:23 GMT
Last-Modified: Fri, 09 Aug 2013 23:54:35 GMT
Server: ECS (ewr/1584)
X-Cache: HIT
x-ec-custom-error: 1
Content-Length: 1270

<!doctype html>
<html>
<head>
    <title>Example Domain</title>
    ...

The web server has accepted our request and sent back a response, which is the HTML web page! I think that this is a perfect way to demonstrate what is actually happening when you try to visit a site.

The full request can be seen here, $ denoting input:

$ telnet example.com 80
Trying 93.184.216.119...
Connected to example.com.
Escape character is '^]'.
$ GET / HTTP/1.1
$ Host: example.com

...

Naturally, the next thing I wondered was how would I show this with an HTTPS connection since we can't realistically do an SSL handshake. A quick Google search showed that OpenSSL was the right tool.

openssl s_client -connect example.com:443

You'll see the certificate whiz by and then be able to make your request!