We all use HTTP, develop for HTTP and think that we know HTTP. But, I believe as engineers we should never take things for granted; rather we should dissect everything that comes before us, recursively as many times as possible. So, let's keep applying this principle for HTTP.


cURL is a great tool for sending HTTP requests. Let's try to send one.

curl http://httpbin.org/ip

Hmm, okay it can do stuff. Let's make it a bit more verbose shall we? Just add a -v flag.

curl -v http://httpbin.org/ip

Ah now things are interesting. Do you see a few lines starting with '>'? Well those are the headers that are SENT to the server. And the lines starting with '<'? They are response headers that are received. The last part is the content itself. Of course, the < and > are there for representation only, they are not transmitted.


telnet is a great tool to make raw socket connections and really dissect almost any TCP based protocol like HTTP. Lets try this.

telnet httpbin.org 80

Afterwards, type in a raw HTTP request yourself!

GET /ip HTTP/1.1
Host: httpbin.org

Now, press enter or return twice!

Who needs Firefox, Chrome or cURL! Looks like Telnet is all we need ;) Okay enough jokes for now. This is serious business. You see in the end HTTP is just a plain socket connection that has some specific "lingo" to send requests and receive responses. (Protocol, duh).

Dissecting the Request

Let's see how exactly we made the request.

GET /ip HTTP/1.1
Host: httpbin.org

Pretty straightforward. The HTTP method in caps, the path and the HTTP version in the first line. After that, the request headers follow. In our case we just mentioned the 'Host' header to play safe with VirtualHost-enabled systems.

Back in the days, running a website was expensive because you needed an entire box (a server computer) to host a single website. Then we invented a way to serve multiple websites from the same IP address / machine with virtual hosts in the Apache Web Server.

The internet as we know it exists for this 'Host' header.

The two newlines indicate we are done with our request, and the server can parse it and send back a response.

Let's be bad

Let's send a malformed HTTP request (muhahaha).

telnet httpbin.org 80

Afterwards, type in a malformed request yourself!


Now, press enter or return twice!

Yup :( It was a Bad Request. We'll write our own HTTP server with plain old sockets soon. Till then, why not explore the exciting world of HTTP response headers on Google ;) Yeah and take a look at RFC 2616.