Telnet 101
Telnet has been around since before the dawn of (Unix) time but surprisingly few people know how to use this extremely useful tool to track down problems with many popular services. A few seconds with Telnet can save hours of frustrating searching, trial and error, and screaming at the computer.
Telnet can be used to simulate many plain-text protocols. I've used it to talk to MySQL, Memcached and Postfix. Here I'll show how to use it to test that an HTTP daemon can serve content over HTTP/1.1.
What is HTTP?
Before we can use telnet to simulate HTTP we need to know more about HTTP - what is it and how it works.
HTTP/1.1 - HyperText Transfer Protocol - is a plain-text protocol defined in RFC2616. It's used for a great many things, but the most visible one for most people is as a transport mechanism for web pages.
When you request a webpage a few special operations are performed (which I'll gloss over because they're beyond the scope of this article). After those have completed your web browser connects to the web server and sends it a requests for a page. A typical request for a web page looks something like this:
GET / HTTP/1.1
Host: example.com
The format of the request is:
[HTTPMETHOD] [PATH TO WEBPAGE] HTTP/1.1
Host: [SERVERNAME]
[BLANK LINE]
The server responds with something similar except after the blank line there's usually the page you requested.
HTTP/1.1 200 OK
Server: Apache/2.2.3 (Red Hat)
Last-Modified: Tue, 15 Nov 2005 13:24:10 GMT
ETag: "b300b4-1b6-4059a80bfd280"
Accept-Ranges: bytes
Content-Type: text/html; charset=UTF-8
Connection: close
Date: Thu, 10 Dec 2009 10:37:33 GMT
Age: 7114
Content-Length: 438
<HTML>
<HEAD>
<TITLE>Example Web Page</TITLE>
</HEAD>
<body>
<p>You have reached this web page by typing "example.com",
"example.net",
or "example.org" into your web browser.</p>
<p>These domain names are reserved for use in documentation and are not available
for registration. See <a href="http://www.rfc-editor.org/rfc/rfc2606.txt">RFC
2606</a>, Section 3.</p>
</BODY>
</HTML>
The format of the response is:
HTTP/1.1 [RESPONSE STATUS]
[RESPONSE HEADERS]
[BLANK LINE]
[REQUESTED WEBPAGE]
There's a lot more to the HTTP protocol, but it's all document in rather a lot of (rather dry) detail in RFC2616. Mostly you can just skim the RFC for the parts you're interested in.
Simulated Awesome
Okay, so now we've got an idea how HTTP can be used to request a webpage. How do we go from that to using telnet to show it works?
The telnet manpage says that the telnet command can take arguments for host and port. In the above example we were requesting a page from example.com so that's the host we'll use. Typically HTTP is served on port 80, and this is true of example.com so we'll use that as the port.
telnet example.com 80
With that we're connected to the HTTP service - the web server - on example.com. You'll see output something like this as connects:
Trying 192.0.32.10...
Connected to example.com.
Escape character is '^]'.
Once connected you'll be left with your cursor on a blank line. This is where you can start pretending to be a web browser.
Type in the GET request shown in the "What is HTTP?" section above (including the blank line at the end). After a short delay you should get back the example.com webpage.
How is this useful?
Requesting a webpage by hand can quickly expose several common problems.
- Misconfigured firewalls mean telnet won't connect.
- The status code returned can tell you a lot about what the server did with your request. RFC2616 contains a list of HTTP status codes and their meaning.
- You avoid problems which may be caused by your browser caching the old version of files you request.
- You can easily check all the headers that the server sends back.
- By adding headers such as Accept-Encoding you can check that your assets are being served gzipped when it is requested.
Telnet isn't limited to checking just HTTP either. SMTP, IMAP, POP and many others can be simulated using telnet. It's not a silver bullet, but it's a very useful tool.
curl -LO http://barkingiguana.com/2009/12/10/telnet-101.html.orig
curl -LO http://barkingiguana.com/2009/12/10/telnet-101.html.orig.asc
gpg --verify telnet-101.html.orig{.asc,}
If you'd like to have a conversation about this post, email craig@barkingiguana.com. I don't bite.