如何使用 Telnet 发送 HTTP 请求 [关闭]
Posted
技术标签:
【中文标题】如何使用 Telnet 发送 HTTP 请求 [关闭]【英文标题】:How to send an HTTP request using Telnet [closed] 【发布时间】:2013-03-24 05:36:58 【问题描述】:如何使用Telnet获取网页内容?
例如https://***.com/questions
的内容。
【问题讨论】:
例如telnet telehack.com
。 List of examples
这个评论/例子,比最高评价的答案要好得多 - 如果使用没有 dns 的设备(比如我正在设置的一些 cisco 路由器),只需 nslookup IP先连接,再连接。
【参考方案1】:
你可以的
telnet ***.com 80
然后粘贴
GET /questions HTTP/1.0
Host: ***.com
# add the 2 empty lines above but not this one
这是一个成绩单
$ telnet ***.com 80
Trying 151.101.65.69...
Connected to ***.com.
Escape character is '^]'.
GET /questions HTTP/1.0
Host: ***.com
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
...
【讨论】:
Hrm,它对我来说工作得很好(而且“接受”标题也不是必需的)。如果您足够快地执行它(并且使用与真实浏览器相同的标头),那么实际上不可能区分 CLI 请求和来自浏览器的请求。区分的唯一方法是查看更大的上下文(例如,后续请求或缺少后续请求,或它们的时间安排,但即便如此,它也不是确定性的,因为用户可能会使用扩展或设置来禁用外部资源的加载)。 在导致HTTP/1.1 400 Bad Request
响应的行的开头有多余的空格。我修好了它并附上了一份成绩单。干杯。
HTTP/1.0 对我不起作用。不应该是 HTTP/1.1 吗?【参考方案2】:
telnet 服务器名 80
GET /index.html↵
↵
↵ 表示“返回”,您需要按两次返回
【讨论】:
GET /index.html
后面必须加两个换行符,否则不行。 标题部分的结尾由一个空字段(行)指示,导致传输两个连续的 CR-LF 对。 — from Wikipedia
如果你想自动化这个: echo "GET /"; sleep 1; | telnet localhost 80
(来自***.com/questions/7013137/…)
HTTP/1.0 真的没必要吗? HTTP 规范没有将其标记为可选,但大多数服务器似乎没有它也能正常工作。这是一种无证行为,还是在其他地方有记录?
@DiegoQueiroz:IIRC 它被解释为“HTTP v0.9”。【参考方案3】:
对于后代,您的问题是如何向 https://***.com/questions
发送 http 请求。真正的答案是:您不能使用 telnet,因为这是一个仅可访问 https 的 url。
因此,您可能想使用openssl
而不是telnet
,例如这样
$ openssl s_client -connect ***.com:443
...
---
GET /questions HTTP/1.1
Host: ***.com
这将为您提供 https 响应。
【讨论】:
或nc --ssl ***.com 443
如果已安装netcat
如果服务器坚持 CR/LF 行终止(根据 HTTP 协议规范,但经常被忽略)添加 -crlf
到选项。
@user4104817 在 macOS 上 nc
不能这样做,但 brew install nmap
提供了带有该选项的 ncat
命令【参考方案4】:
为了稍微扩展之前的答案,有一些复杂情况。
telnet
不是特别可编写脚本的;您可能更喜欢使用nc
(又名netcat
),它可以更好地处理非终端输入和信号。
另外,与telnet
不同,nc
实际上允许 SSL(因此https
而不是http
流量——那么您需要端口 443 而不是端口 80)。
HTTP 1.0 和 1.1 之间存在差异。最新版本的协议要求将 Host:
标头包含在请求中 POST
或 GET
行之后的单独行中,并在其后跟一个空行以标记请求标头的结尾。
HTTP 协议要求回车/换行换行结束。许多服务器对此很宽容,但有些则不然。您可能想使用
printf "%\r\n" \
"GET /questions HTTP/1.1" \
"Host: ***.com" \
"" |
nc --ssl ***.com 443
如果您回退到 HTTP/1.0,您并不总是需要 Host:
标头,但许多现代服务器无论如何都需要标头;如果多个站点托管在同一 IP 地址上,则服务器无法从 GET /foo HTTP/1.0
知道您的意思是 http://site1.example.com/foo
还是 http://site2.example.net/foo
如果这两个站点都托管在同一服务器上(在没有 @987654336 的情况下) @ 标头,HTTP 1.0 服务器可能只是默认到与您想要的不同的站点,因此您不会得到您想要的内容)。
HTTPS 协议在这些细节上与 HTTP 相同;唯一真正的区别在于会话的初始设置方式。
【讨论】:
这是一个带有netcat的单行代码: echo "GET / HTTP/1.1"; echo "Host: example.com"; echo; sleep 1; | ncat --ssl example.com 443
我真的看不出比 printf
有任何优势。也许sleep
在某些情况下会有所帮助。
我觉得没关系,我猜printf
可以做更多的事情,但echo
在这种情况下就足够了。我只是认为与 netcat 共享单行代码会很有用。
太棒了。对 MacOs Catalina 稍作调整,改用 ncat
,因为 nc
不提供 --ssl
。
如果算作单行,printf
版本当然也可以简单地通过删除换行符折叠成一行。以上是关于如何使用 Telnet 发送 HTTP 请求 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章