MyTetra Share
Делитесь знаниями!
Basics of telnet and HTTP
Время создания: 25.04.2013 22:54
Раздел: root - Internet
Запись: Yurons/mytetra/master/base/1366919692li9ls9j4og/text.html на raw.github.com

Basics of telnet and HTTP

 

January 23, 2009 by Jason Garber

 

Say you want to request a webpage… Normally, one would use a web browser, right? But sometimes you just need to see what is really going on… In this blog post I will show the basics of using the telnet command to work with the HTTP protocol.

 

For reference: http://www.w3.org/Protocols/rfc2616/rfc2616.html

 

Most of these commands were run on Linux, but telnet on Windows should work too.

telnet <ip-or-host> <port>

Background…

 

If you are using the HTTP protocol, which is port 80, then you must follow the HTTP protocol conventions (which are simple). HTTP has two primary versions at this point: 1.0 and 1.1.

 

In the HTTP 1.0 days, a single website was bound to a single IP address. What this means is that an HTTP request sent to a given IP address would return content from only one site. This is quite limiting and inconvenient. To have to assign a new IP for every different domain name… What a bother. Not to mention that the current internet protocol standard, IPv4, is limited to several billion addresses and quickly running out.

 

More recently, HTTP 1.1 has become the standard. This enables something called Name Based Virtual Hosting. By requiring a “Host” header to be sent along with the request, HTTP servers can in turn “look up” the correct website and return it based on the name. Hundreds or even thousands of different domains can now be hosted on a single IP address.

 

(keep in mind that SSL certificates each require a seperate IP address. Due to encryption issues, the IP address is needed to determine which SSL certificate to use…)

 

So with that introduction, allow me to show you the basics of HTTP…

Using HTTP over Telnet

 

The telnet utility is a simple (but useful) utility that allows one to establish connections to a remote server. From my perspective, it is most useful with plain text protocols (like HTTP), but my knowledge of telnet is not very deep…

 

Here is an example (commands you would type are in red):

[jason@neon ~]$ telnet gahooa.com 80

Trying 74.220.208.72…

Connected to gahooa.com (74.220.208.72).

Escape character is ‘^]’.

GET / <press enter>

<html>

<body>

Hi, you have reached Gahooa!

</body>

</html>

Connection closed by foreign host.

 

Because it was an HTTP 1.0 request, the server DID NOT wait for additional headers. Again, quite limiting – only sending one header line.

And… HTTP 1.1

 

Here is an example of an Apache Virtual Host configuration directive.

<VirtualHost 74.220.208.72:80>

# Defines the main name by which this VirtualHost responds to

ServerName gahooa.com

 

# Additional names (space delimited) which this VirtualHost will respond to.

ServerAlias www.gahooa.com

 

# Apache will append the requested URI to this path in order to find the resource to serve.

DocumentRoot /home/gahooa/sites/gahooa.com/docroot

 

</VirtualHost>

 

When we issue the following HTTP 1.1 request, we are in effect asking for the file at:

/home/gahooa/sites/gahooa.com/docroot/index.html

 

Keep in mind that because this is HTTP 1.1, the web server will continue to accept header lines until it encounters a blank line:

A blank line…

[jason@neon ~]$ telnet gahooa.com 80

Trying 74.220.208.72…

Connected to gahooa.com (74.220.208.72).

Escape character is ‘^]’.

GET /index.html HTTP/1.1 <press enter>

Host: www.gahooa.com <press enter>

<press enter again>

HTTP/1.1 200 OK

Date: Wed, 03 Sep 2008 21:00:46 GMT

Server: Apache/2.2.9 (Unix)

Transfer-Encoding: chunked

Content-Type: text/html

<take note of blank line here>

<html>

<body>

Hi, you have reached Gahooa!

</body>

</html>

Connection closed by foreign host.

 

A couple notes:

HTTP 1.1 continues to accept header lines until it recieves a blank line

HTTP 1.1 sends a number of header lines in the response. Then a blank line. Then the response content.

Redirects

 

One of the main points of writing this article was to describe how to debug strange redirect problems. Redirects are done by sending a “Location” header in the response. For more information on the Location header, please see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30

[jason@neon ~]$ telnet gahooa.com 80

Trying 74.220.208.72…

Connected to gahooa.com (74.220.208.72).

Escape character is ‘^]’.

GET /test-redirect.php HTTP/1.1 <press enter>

Host: www.gahooa.com <press enter>

<press enter again>

HTTP/1.1 200 OK

Date: Wed, 03 Sep 2008 21:00:46 GMT

Server: Apache/2.2.9 (Unix)

Transfer-Encoding: chunked

Content-Type: text/html

Location: http://www.google.com <take note of this line>

 

The Location header in the response instructs the requestor to re-request the resource, but from the URI specified in the Location header. In the above example, if you were debugging redirect issues, you would simply initiate another HTTP request to http://www.google.com

Python instead of telnet

 

Finally, I’d like to illustrate a really simple python program that would facilitate playing around with the same:

import socket

S = socket.socket(socket.AF_INET)

S.connect(("www.gahooa.com", 80))

 

S.send("GET / HTTP/1.1\r\n")

S.send("Host: www.gahooa.com\r\n")

S.send("\r\n")

 

print S.recv(1000)

 

S.close()

Conclusion

 

When you are not familiar with protocols such as HTTP, understanding “how things work” can be daunting. But like many technologies out there, they really are simple (once understood).

 

The more truth and understanding you can fit into your perspective, the better you will be able to make informed decisions.

 

Making HTTP requests via telnet

Simple telnet HTTP requests

Using Telnet is a great way to learn about HTTP requests.

For example.. back in the 90s microsoft was running their sites on apache. Nowadays they are eating their own dog food.  ;-)

Here is a simple HEAD request to microsoft.com via telnet.

$ telnet microsoft.com 80

Trying 207.46.232.182...

Connected to microsoft.com.

Escape character is '^]'.

HEAD / HTTP/1.0

 

HTTP/1.1 301 Moved Permanently

Connection: close

Date: Thu, 12 Jul 2007 15:25:37 GMT

Server: Microsoft-IIS/6.0

X-Powered-By: ASP.NET

Location: http://www.microsoft.com

Content-Length: 31

Content-Type: text/html

Set-Cookie: ASPSESSIONIDSCAQCSBR=FMPJMMPAMGNBFELIPABIHHMN; path=/

Cache-control: private

 

Connection closed by foreign host.

The command above was simple. HEAD / HTTP/1.0 followed by 2 line feeds.

The 80 specified in the telnet command is the port that you are hitting when you type http://microsoft.com/ in a browser. If another port is used you will see it after a colon. ex: http://tonycode.com:8080/ hits the server running on port 8080. If there was one. :-)

When doing GET commands you usually end up sending headers with your command. You should always send the Host header (this isn’t required for HTTP/1.0 but many servers are running multiple sites so you’ll want to send this.)

Here’s an example of a GET against my home page.

$ telnet tonycode.com 80

Trying 208.97.136.171...

Connected to tonycode.com.

Escape character is '^]'.

GET / HTTP/1.1

Host: tonycode.com

 

HTTP/1.1 200 OK

Date: Thu, 12 Jul 2007 16:10:02 GMT

Server: Apache/1.3.37 (Unix) mod_throttle/3.1.2 DAV/1.0.3 mod_fastcgi/2.4.2 mod_gzip/1.3.26.1a PHP/4.4.7 mod_ssl/2.8.22 OpenSSL/0.9.7e

MS-Author-Via: DAV

Last-Modified: Wed, 11 Jul 2007 14:10:28 GMT

ETag: "19cf7aa-68d-4694e4d4"

Accept-Ranges: bytes

Content-Length: 1677

Content-Type: text/html

 

<!DOCTYPE html PUBLIC "-//W3C//DTD

I spared you the full contents of my home page. Why did it return the entire page? Because we did a GET instead of HEAD.

Remembering all the headers you need can get tricky so I usually use [LiveHttpHeaders to get what I need and then I can make modifications for testing or scripting purposes.

 

Scripting telnet HTTP requests

I recently needed to hit several production servers that lived behind a VIP. I had access to the servers directly but their behavior was controlled by the host that they were called with so if I used the machine name I was out of luck. Also, port numbers in the request would throw it off. So I needed to send http requests directly to the server and lie about the hostname I was using to access them.

Here is a script file that I run and pipe into telnet.

echo "open $1 $2"

sleep 2

echo "GET $4 HTTP/1.0"

echo "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4"

echo "Host: $3"

echo

echo

sleep 2

lets put this in a file called getpage and then we run the following

./getpage tonycode.com 80 tonycode.com /| telnet

ok. what did we just do?

  • getpage is sending commands on stdout and telnet is getting them via the pipe
    • getpage 1st tells telnet to open a connection to tonycode.com ($1) port 80 ($2).
    • getpage waits 2 seconds for the connection. Adjust as necessary.
    • getpage sends the request. GET / HTTP/1.0 and sets the host ($3) to tonycode.com.
      • Note $4 is the resource to fetch and we set it to /.
      • I even threw in the user agent header for fun.
      • Those 2 empty echo statements are necessary to tell the server this is the end of the request.
        • Finally getpage sleeps for 2 seconds to allow time for the response to come back. Leave out this line and you’ll get nada.

 
MyTetra Share v.0.59
Яндекс индекс цитирования