我有一个邮递员请求,可以从服务器获取正确的响应,但是当我使用它从代码片段部分生成的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 协议(超文本传输协议)定向到
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请求使用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 身份验证方法。