It’s often possible to emulate a web client by talking to a web server by hand, via telnet.
$ telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Mon, 04 Feb 2008 09:18:05 GMT
Server: Apache/2.2.7 (Unix) mod_ssl/2.2.7 OpenSSL/0.9.7l DAV/2 mod_python/3.3.1 Python/2.5.1
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html
<html><body><h1>It works!</h1></body></html>
Connection closed by foreign host.
This gives you the full output of the web server, headers and all. This is sometimes useful in debugging web apps, without having to turn on a packet sniffer. As long as you knew how to talk HTTP (and there are differences between 1.0 and 1.1), you can observe some of these underlying outputs directly. Trouble comes if you wanted to do the same with an SSL-enabled host. If you have a server enabled as such and try to telnet to a secured port (say, 443), you should get an error message along the lines of:
Bad Request
You're speaking plain HTTP to an SSL-enabled server port.
The solution is to use openssl instead. In the wonderful grab-bag of functionality implemented in the openssl command-line tool, it actually has a secure client for testing SSL connections.
$ openssl s_client -connect localhost:443
CONNECTED(00000003)
...lots of certificate-related stuff here...
---
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Mon, 04 Feb 2008 09:19:01 GMT
Server: Apache/2.2.7 (Unix) mod_ssl/2.2.7 OpenSSL/0.9.7l DAV/2 mod_python/3.3.1 Python/2.5.1
Last-Modified: Sat, 20 Nov 2004 20:16:24 GMT
Accept-Ranges: bytes
Content-Length: 44
Connection: close
Content-Type: text/html
<html><body><h1>It works!</h1></body></html>
Connection closed by foreign host.
Note that this is a general SSL client. I used HTTPS as a concrete example, but the same can be applied to other SSL-secured ports. If you’re designing a server application or protocol that works through a TLS or SSL layer, chances are this client can be a good debugging tool.
UPDATE: I’m really going to miss being able to do this when HTTP/2 becomes fully deployed. HTTP/2 is a binary protocol, which means that you can no longer type text at the server and expect a response. Binary protocols are friendly for performance, not developer sanity. – yliu, May 2015
another good tool for that (operating on a different level, though) is the firefox poster add-on (https://addons.mozilla.org/en-US/firefox/addon/2691). it supports all kinds of http interactions (head, get, post, put, delete), produces a little bit more formatted output (which is not necessary, but a nice touch), and works with http and https.
Thanks for your tip. I also use stunnel to connect to SSL server. STunnel is a good SSL tunneling program and can turn an HTTP-only client to a full HTTPS client.
STunnel : http://www.stunnel.org
I learned something today about HTTP/2, with your update. Thank you!
Do you know how to do the same with ssh instead of HTTPS?
SSH is not a plaintext protocol, unlike HTTP, so there is not much purpose in trying to talk with it manually. You’d be better off writing a program that implements the SSH protocol (up to as much as you want to) using the IETF RFCs. Or just using an SSH library.