在Python中进行HTTPS连接时HTTP 400请求错误?

在Python中进行HTTPS连接时HTTP 400请求错误?,python,https,Python,Https,在Python3.8中,通过HTTPS生成XML-RPC时,我收到一个HTTP400-错误请求 当我们在HTTPS请求中提供Host头时,似乎出现了这个问题,而在此之前的putrequest()调用中没有skip_Host=True。这两个信息的--skip_host参数和host头是否相互排斥?如果是,我应该使用哪一个 导入http.client connection=http.client.HTTPSConnection(“duckduckgo.com”、“443”) connection.

在Python3.8中,通过
HTTPS
生成
XML-RPC
时,我收到一个
HTTP400-错误请求

当我们在
HTTPS
请求中提供
Host
头时,似乎出现了这个问题,而在此之前的
putrequest
()调用中没有
skip_Host=True
。这两个信息的--
skip_host
参数和
host
头是否相互排斥?如果是,我应该使用哪一个

导入http.client
connection=http.client.HTTPSConnection(“duckduckgo.com”、“443”)
connection.putrequest(“GET”,“/”)#如果必须提供主机,则需要跳过_host=True
connection.putheader(“用户代理”、“Python/3.8”)
connection.putheader(“Host”,“duckduckgo.com”)#需要跳过_Host=True才能工作
connection.endheaders()
response=connection.getresponse()
打印(response.status、response.reason)

更新:正如官方文档中提到的,此问题不会发生在所有HTTPS服务器上。

跳过主机
保留为其默认值,即
False
,并且使用
putheader
指定
主机
头会导致发送
主机
头两次(在本例中使用不同的值). 可通过将
debuglevel
设置为正值来检查这一点

导入http.client >>>connection=http.client.HTTPSConnection(“duckduckgo.com”、“443”) >>>连接。设置调试级别(1) >>>connection.putrequest(“GET”、“/”) >>>connection.putheader(“用户代理”、“Python/3.8”) >>>connection.putheader(“主机”,“duckduckgo.com”) >>>connection.endheaders() 发送:b'GET/HTTP/1.1\r\n主机:duckduckgo.com:443\r\n接受编码:identity\r\n用户代理:Python/3.8\r\n主机:duckduckgo.com\r\n\r\n >>> >>>response=connection.getresponse() 答复:“HTTP/1.1 400错误请求\r\n” 标头:服务器标头:日期标头:内容类型标头:内容长度标头:连接标头:X-XSS-Protection标头:X-Content-Type-Options标头:引用者策略标头:预期CT
在本文中提到,发送两次
主机
头可能会让某些web服务器感到“困惑”。请参见
putrequest
中的以下注释:

            if not skip_host:
                # this header is issued *only* for HTTP/1.1
                # connections. more specifically, this means it is
                # only issued when the client uses the new
                # HTTPConnection() class. backwards-compat clients
                # will be using HTTP/1.0 and those clients may be
                # issuing this header themselves. we should NOT issue
                # it twice; some web servers (such as Apache) barf
                # when they see two Host: headers
您的代码将通过添加
skip_host=True
或不明确指定
host
头来工作。这两种方法都会导致发送一次
主机

导入http.client >>>connection=http.client.HTTPSConnection(“duckduckgo.com”、“443”) >>>connection.putrequest(“GET”,“/”,skip_host=True) >>>connection.putheader(“用户代理”、“Python/3.8”) >>>connection.putheader(“主机”,“duckduckgo.com”) >>>connection.endheaders() >>>response=connection.getresponse() >>>打印(response.status、response.reason) 200行 >>>#或 >>>connection=http.client.HTTPSConnection(“duckduckgo.com”、“443”) >>>connection.putrequest(“GET”、“/”) >>>connection.putheader(“用户代理”、“Python/3.8”) >>>connection.endheaders() >>>response=connection.getresponse() >>>打印(response.status、response.reason) 200行
至于使用哪一个,似乎建议,除非您有理由指定
主机
头(使用
putheader
),否则您可以依赖模块自动发送
主机
头,即将
跳过主机
保留为其默认值,即
,不要使用
putheader

指定
Host
头。我听说有多个主机被发送到某处。非常感谢@Nikolas Chatzis深入澄清!