如何使用 Telnet 发送 HTTP 请求

如何获得一个网页的内容使用 Telnet

例如,https://stackoverflow.com/questions的内容。

204819 次浏览

telnet ServerName 80


GET /index.html↵
↵

↵ means 'return', you need to hit return twice

You could do

telnet stackoverflow.com 80

And then paste

GET /questions HTTP/1.0
Host: stackoverflow.com




# add the 2 empty lines above but not this one

Here is a transcript

$ telnet stackoverflow.com 80
Trying 151.101.65.69...
Connected to stackoverflow.com.
Escape character is '^]'.
GET /questions HTTP/1.0
Host: stackoverflow.com


HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...

For posterity, your question was how to send an http request to https://stackoverflow.com/questions. The real answer is: you cannot with telnet, cause this is an https-only reachable url.

So, you might want to use openssl instead of telnet, like this for instance

$ openssl s_client -connect stackoverflow.com:443
...
---
GET /questions HTTP/1.1
Host: stackoverflow.com

This will give you the https response.

To somewhat expand on earlier answers, there are a few complications.

telnet is not particularly scriptable; you might prefer to use nc (aka netcat) instead, which handles non-terminal input and signals better.

Also, unlike telnet, nc actually allows SSL (and so https instead of http traffic -- you need port 443 instead of port 80 then).

There is a difference between HTTP 1.0 and 1.1. The recent version of the protocol requires the Host: header to be included in the request on a separate line after the POST or GET line, and to be followed by an empty line to mark the end of the request headers.

The HTTP protocol requires carriage return / line feed line endings. Many servers are lenient about this, but some are not. You might want to use

printf "%s\r\n" \
"GET /questions HTTP/1.1" \
"Host: stackoverflow.com" \
"" |
nc --ssl stackoverflow.com 443

If you fall back to HTTP/1.0 you don't always need the Host: header, but many modern servers require the header anyway; if multiple sites are hosted on the same IP address, the server doesn't know from GET /foo HTTP/1.0 whether you mean http://site1.example.com/foo or http://site2.example.net/foo if those two sites are both hosted on the same server (in the absence of a Host: header, a HTTP 1.0 server might just default to a different site than the one you want, so you don't get the contents you think you are getting).

The HTTPS protocol is identical to HTTP in these details; the only real difference is in how the session is set up initially.

For what it's worth, Telnet was once a fairly ubiquitous protocol for unencrypted remote terminal access (standard port number 23). When encrypted remote access over SSH (port 22) became available in 1995, it basically caused a mass extinction of Telnet servers, but the client software still exists, and allows you to easily talk to any text-based server, such as an HTTP server (or an SMTP server, or an FTP server, or etc).

The Telnet protocol has some non-textual control sequences which of course an HTTP server will not transmit most of the time, though it could happen by accident e.g. if you triggered it to send random binary data, in which case the client could intercept the control codes and corrupt the data.

Netcat has no such protocol-specific features, and is purely a tool for putting bytes on the wire. In addition to its simpler and more robust general-purpose design, it has features to allow you to control specific behaviors of the raw socket from the command line, and to control details of its interactive behavior for scripting etc. Unlike the Telnet client, it also allows you to set up a listening socket, so a simple server.

(On some platforms, there are multiple Netcat implementations, some of which are less featureful than others. If you can't find netcat, maybe look for nc or ncat. There is also a separate tool socat which can be useful for network troubleshooting.)