postman请求和它生成的curl cmd或python代码之间的http请求区别

问题描述 投票:0回答:1

我有一个邮递员请求,可以从服务器获取正确的响应,但是当我使用它从代码片段部分生成的curl命令或python脚本时,它失败了。但它们应该是等价的?我希望了解服务器如何看待请求与我收到的错误消息不同,但无法访问服务器本身。

邮递员给出的curl命令是

curl --location --request POST 'http://10.50.50.50:8081/v1' \
--header 'Content-Type: application/json' \
--data-raw '{
    "min_tokens": 128
}'

我从服务器收到的错误是“访问被拒绝”,所以我认为它正在到达服务器,但与邮递员请求和被拒绝有所不同?邮差请求的其他哪些部分没有被curl命令捕获?

我还尝试了来自postman的python http客户端lib代码

conn = http.client.HTTPSConnection(url, port,  context = 
ssl._create_unverified_context())
payload = json.dumps({
  "min_tokens": 128
})
headers = {
  'Content-Type': 'application/json'
}
conn.request("POST", "/v1", payload, headers)
res = conn.getresponse()

这次我遇到了一些 ssl 错误

self._sslobj.do_handshake() ssl.SSLError:[SSL]记录层失败 (_ssl.c:1000)

我也尝试了同样的Python请求库

  payload = json.dumps({
    "min_tokens": 128
  })
  headers = {
    'Content-Type': 'application/json'
  }

  try:
      response = requests.post(url, data=payload, headers=headers, verify=False, proxies={})
      response.raise_for_status()  # Raise an exception for bad status codes
      print(response.text)
  except requests.exceptions.RequestException as e:
      print("Error:", e)

并获得 403

错误:403客户端错误:禁止网址:http://10.50.50.50:8081/v1

考虑到邮递员中的请求只有一个标头和正文,curl 或 python 代码中还有什么不同?我在公司代理后面并安装了自定义 CA,邮递员默认使用它们的方式与curl 或 python lib 应该相同吗?我尝试过未经验证的 ssl 和带/不带代理,但服务器的响应相同

http python-requests request postman
1个回答
0
投票

CURL 请求

您的请求将使用 HTTP 协议(超文本传输协议)定向到

http://10.50.50.50:8081/v1
。这意味着没有传输层加密。另请注意,请求中不包含身份验证数据(这解释了您的“访问被拒绝”错误。

curl --location --request POST 'http://10.50.50.50:8081/v1' \
--header 'Content-Type: application/json' \
--data-raw '{
    "min_tokens": 128
}'

如果您想要额外的输出,可以使用

-v
标志。这将使 CURL 发出额外的输出。这对于调试来说非常方便。

输出示例

$ curl http://google.de// -v
* Host google.de:80 was resolved.
* IPv6: 2a00:1450:4001:831::2003
* IPv4: 142.250.184.195
*   Trying [2a00:1450:4001:831::2003]:80...
* Connected to google.de (2a00:1450:4001:831::2003) port 80
> GET // HTTP/1.1
> Host: google.de
> User-Agent: curl/8.9.1
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.de/
< Content-Type: text/html; charset=UTF-8
< Content-Security-Policy-Report-Only: object-src 
...

Python 请求

您的python请求使用HTTPS协议(安全超文本传输协议),该协议使用TLS(传输层安全)进行传输加密(默认端口为443)。对于这些安全功能,服务器和客户端都必须先交换加密详细信息,然后才能发送任何有效负载。

conn = http.client.HTTPSConnection(url, port,  context = ssl._create_unverified_context())
payload = json.dumps({
  "min_tokens": 128
})
headers = {
  'Content-Type': 'application/json'
}
conn.request("POST", "/v1", payload, headers)
res = conn.getresponse()

这次我遇到了一些 ssl 错误

self._sslobj.do_handshake() ssl.SSLError: [SSL] record layer failure (_ssl.c:1000)

在不了解库的情况下,我会说,这个问题是由服务器引起的,服务器拒绝建立连接。换句话说,服务器立即终止连接,而不发送任何响应(即你的握手错误)。

您必须使用协议选择器

https://...
而不是
http://...
,因为您明确尝试在代码中建立 HTTPS 连接。

备用客户

在第三个示例中,您使用了另一种方法,类似于 CURL 命令。此代码不会强制安全连接!如果你在这里使用相同的 URL,服务器一定会有响应。

  payload = json.dumps({
    "min_tokens": 128
  })
  headers = {
    'Content-Type': 'application/json'
  }

  try:
      response = requests.post(url, data=payload, headers=headers, verify=False, proxies={})
      response.raise_for_status()  # Raise an exception for bad status codes
      print(response.text)
  except requests.exceptions.RequestException as e:
      print("Error:", e)

正如预期的那样,服务器发送响应,验证连接是否已建立。

并获得 403

Error: 403 Client Error: Forbidden for url: http://10.50.50.50:8081/v1

HTTP 状态 403 定义为 “服务器理解该请求,但拒绝授权。”;进一步“如果请求中提供了身份验证凭据,服务器会认为它们不足以授予访问权限。”.

由于您没有在请求中提供任何授权标头,这可能反过来表明您的请求所针对的资源/端点不是公开的,或者代理服务禁止连接。

尝试找出 postman 包含哪种身份验证数据并将其添加到您的 CURL 命令或 python 代码中。对于使用

HTTP 状态 401 进行应答的服务器,响应中会发送身份验证质询。更多信息可以在 RFC 2617 中找到,它定义了简单的 HTTP 身份验证方法。

© www.soinside.com 2019 - 2024. All rights reserved.