我目前正在使用python 2.7请求库,并且不支持有序标头.我可以将有序数据用于发布和获取(如有序字典),但根本不支持标题.甚至没有在python 3中
我知道HTTP协议RFC,表明标题的顺序是无关紧要的,但问题是我实现的第三方服务不起作用,除非标题是有序的.我知道这是因为我已经用其他语言实现了有序的头部请求并且它可以工作(比如java),是的我100%肯定,因为我检查了burp,并且wireshark确保这是请求之间的唯一区别.但是我已经在python中拥有5000行,所以由于这样的问题,迁移到那里是一个痛苦的决定.
我想到的唯一解决方案是在TCP上自己实现http协议,但这不是一个聪明的解决方案.我不能拥有与可用解决方案相同的代码质量,这可能是我的代码失败的一个方面.
请参阅下面的简化代码示例:
data=(("param1","something"),("param2","something_else"))
headers={'id': 'some_random_number','version':'some_random_number','signature':'some_random_number','Content-Type':'application/x-www-form-urlencoded','charset':'utf-8','Content-Length':str(len(urllib.urlencode(data))),'name':'random','User-Agent':'Firefox','Connection':'Keep-Alive','Accept-Encoding':'gzip'}
requests.post("myservice.com",headers=headers,data=data)
请求标题的顺序就像那样发送(不是实际的顺序,只是一个例子来说明我的观点)
'version':'some_random_number'
'Accept-Encoding':'gzip'
'id': 'some_random_number'
'User-Agent':'Firefox'
'signature':'some_random_number'
'Connection':'Keep-Alive'
'Content-Type':'application/x-www-form-urlencoded'
'charset':'utf-8'
'name':'random'
这对我来说是个问题.我不知道该做什么.任何帮助非常感谢.我试过urllib库没有支持
class OrderedHeaders(object):
def __init__(self,*headers):
self.headers = headers
def items(self):
return iter(self.headers)
oh = OrderedHeaders(('Accept-Charset','Foo'),('Bar','Foobar'))
for k,v in oh.items():
print("%s:%s" % (k,v))
下面是一个更详细的示例,它使用topological sorting来确定在其他标头之前必须给出哪些标头.它需要更多的代码,但你可以清楚地说明你的标题必须具有哪些排序,然后像任何其他字典一样使用该类.
import sys
import toposort
class OrderedHeaders(dict):
# The precedence of headers is determined once. In this example,# 'Accept-Encoding' must be sorted behind 'User-Agent'
# (if defined) and 'version' must be sorted behind both
# 'Accept-Encoding' and 'Connection' (if defined).
PRECEDENCE = toposort.toposort_flatten({'Accept-Encoding': {'User-Agent'},'version': {'Accept-Encoding','Connection'}})
def items(self):
s = []
for k,v in dict.items(self):
try:
prec = self.PRECEDENCE.index(k)
except ValueError:
# no defined sort for this header,so we put it behind
# any other sorted header
prec = sys.maxsize
s.append((prec,k,v))
return ((k,v) for prec,v in sorted(s))
# Initialize like a dict
headers = OrderedHeaders(name='random',Connection='Keep-Alive')
...
# Setting more values
headers['Accept-Encoding'] = 'gzip'
headers['version'] = '0.1'
headers['User-Agent'] = 'Firefox'
...
# Headers come out of '.items()' like they should
for k,v in headers.items():
print("%s: %s" % (k,v))
版画
Connection: Keep-Alive
User-Agent: Firefox
Accept-Encoding: gzip
version: 0.1
name: random
因为Connection需要在版本之前,User-Agent需要在Accept-Encoding之前,Accept-Encoding需要在版本和名称之前没有排序,因此放在最后.
您可以按任何顺序在OrderedHeaders上设置值,排序在.items()中完成.但是你可以确定总是可以进行声音排序:如果你犯了一个错误并定义了一个循环依赖(例如’version’>’User-Agent’>’version’),你会得到一个toposort.CircularDependencyError在“编译时”.