簡體   English   中英

Python - 有序標頭HTTP請求

[英]Python - Ordered Headers HTTP Requests

我目前正在使用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庫沒有支持

擴展評論,這是一個非常非常簡單的OrderedHeadersrequests可能滿意:

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))

下面是一個更詳細的示例,它使用拓撲排序來確定必須在其他標頭之前給出哪些標頭。 它需要更多的代碼,但你可以清楚地說明你的標題必須具有哪些排序,然后像任何其他字典一樣使用該類。

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, k, 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需要在version之前, User-Agent需要在Accept-Encoding之前, Accept-Encoding需要在versionname之前沒有排序,因此放在最后。

您可以按任何順序在OrderedHeaders上設置值,排序在.items() 但是你可以確定總是可以進行聲音排序:如果你犯了一個錯誤並定義了一個循環依賴(例如'version'>'User-Agent'>'version'),你會得到一個toposort.CircularDependencyError at“編譯時”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM