在Python中使用特定/不存在的http版本协议发送http请求

时间:2014-11-11 21:10:08

标签: python urllib httplib

有一些方法可以在python中使用特定的http版本协议发送http请求。我认为,使用httplib或urllib,它是不可能的。

例如:GET / HTTP / 6.9

提前致谢。

2 个答案:

答案 0 :(得分:1)

您可以通过继承httplib.HTTPConnection并重新定义类属性_http_vsn_str来轻松完成:

from httplib import HTTPConnection


class MyHTTPConnection(HTTPConnection):

    _http_vsn_str = '6.9'


conn = MyHTTPConnection("www.stackoverflow.com")
conn.request("GET", "/")
response = conn.getresponse()

print "Status: {} {}".format(response.status, response.reason)
print "Headers: {}".format(response.getheaders())
print "Body: {}".format(response.read())

当然,这会导致大多数服务器400 Bad Request

Status: 400 Bad Request
Headers: [('date', 'Tue, 11 Nov 2014 21:21:12 GMT'), ('connection', 'close'), ('content-type', 'text/html; charset=us-ascii'), ('content-length', '311')]
Body: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request</h2>
<hr><p>HTTP Error 400. The request is badly formed.</p>
</BODY></HTML>

答案 1 :(得分:1)

您问题的简单答案是:您是对的,httpliburllib都没有公开的内置功能来执行此操作。 (另外,对于大多数事情,你真的不应该使用urllib - 特别是urlopen

当然,您可以始终依赖这些模块的实施细节,如Lukas Graf's answer

或者,您可以分叉其中一个模块并对其进行修改,这可以保证您的代码可以在其他Python 2.x实现上运行。*。请注意,httplib是顶部有the source链接的模块之一,这意味着服务器作为示例代码,而不仅仅是黑盒库。

或者您可以重新实现需要挂钩的最低级功能,但这是公开记录的。对于httplib,我相信httplib.HTTPConnection.putrequest,这是几百行。

或者你可以选择一个不同的库,其中包含更多的钩子,所以你可以少拿钩。

但实际上,如果您正在尝试制作手动指纹结果的自定义请求,那么为什么要使用HTTP库呢?为什么不这样做?

msg = 'GET / HTTP/6.9\r\n\r\n'
s = socket.create_connection((host, 80))
with closing(s):
    s.send(msg)
    buf = ''.join(iter(partial(s.recv, 4096), ''))

*考虑到永远不会有2.8,所有现有的主要2.7实现共享相同的源模块,并没有太大的好处,并且它不太可能任何新的2.x实现都会有所不同。如果您转到3.x,httplib已经重新组织并重命名,而urllib已完全删除,那么您已经有更大的更改需要担心。 < / p>