bash - 如何使用bash进行http请求?

标签 bash http tcp

当我尝试使用 bash 进行 HTTP 请求时,出现以下错误。有人知道如何解决这个问题吗?谢谢。

$ exec 3<>/dev/tcp/httpbin.org/80
$ echo -e 'GET /get HTTP/1.1\r\nUser-Agent: bash\r\nAccept: */*\r\nAccept-Encoding: gzip\r\nhost: http://httpbin.org\r\nConnection: Keep-Alive\r\n\r\n' >&3
$ cat <&3
HTTP/1.1 400 Bad Request
Server: awselb/2.0
Date: Wed, 31 Mar 2021 00:43:01 GMT
Content-Type: text/html
Content-Length: 524
Connection: close

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
</body>
</html>
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->
<!-- a padding to disable MSIE and Chrome friendly error page -->

最佳答案

您的 Host header 不正确。这应该是主机名,而不是 URL:

$ echo -e 'GET /get HTTP/1.1\r
User-Agent: bash\r
Accept: */*\r
Accept-Encoding: gzip\r
host: httpbin.org\r
Connection: Keep-Alive\r
\r
' >&3

结果是:

$ cat <&3
HTTP/1.1 200 OK
Date: Wed, 31 Mar 2021 00:55:23 GMT
Content-Type: application/json
Content-Length: 279
Connection: keep-alive
Server: gunicorn/19.9.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Accept-Encoding": "gzip",
    "Host": "httpbin.org",
    "User-Agent": "bash",
    "X-Amzn-Trace-Id": "Root=1-6063c87b-09303a470da318290e856d71"
  },
  "origin": "96.237.56.197",
  "url": "http://httpbin.org/get"
}

关于让脚本终止的第二个问题 正确地,一种选择是解析 Content-Length header ,并且仅 读取那么多字节。像这样的东西:

#!/bin/bash

exec 3<>/dev/tcp/httpbin.org/80

cat <<EOF | dos2unix >&3
GET /get HTTP/1.1
User-Agent: bash
host: httpbin.org

EOF

while :;  do
    read line <&3
    line=$(echo "$line" | tr -d '\r')
    [[ -z $line ]] && break

    if [[ $line =~ "Content-Length" ]]; then
        set -- $line
        content_length=$2
    fi
done

echo "length: $content_length"
dd bs=1 count=$content_length <&3 2> /dev/null

这适用于这个特定的测试用例,但它非常脆弱 (例如,如果没有 Content-Length header 怎么办?)。

我只会使用 curl 而不是尝试使用 bash 作为 http 客户端。

关于bash - 如何使用bash进行http请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66880172/

相关文章:

.net - UserNamePasswordValidator 和证书

bash - 无法在 makefile 中捕获命令退出代码

linux - 如何使用 Bash 将文本文件的最后一行读入变量?

linux - 如何从 docker 容器内的主机 bash 脚本运行并保留在容器中的 bash 中

node.js - 限制事件驱动的 Nodejs HTTP 请求

c# - C# 中的远程主机强制关闭现有连接

delphi - 如何处理网络丢失和 Indy IdTCPServer

linux - sed 正在用另一个命令的输出替换匹配的文本,但该命令的输出包含扩展字符

html - WavPack用于html音频播放

http - 检查 url 中的数据自上次以来是否已更改?