如何使用 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: 标头包含在请求中 POSTGET 行之后的单独行中,并在其后跟一个空行以标记请求标头的结尾。

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 请求 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

使用 telnet 的 HTTP 请求没有得到任何响应

telnet客户端模拟浏览器发送请求

如何通过 telnet 发送 POST 请求

是否可以通过 telnet 发送 LDAP“请求”?

如何使用 Telnet 生成 HTTP POST 请求?

HTTP GET 给出 400 错误请求(telnet,arduino)