Python 如何获取http";获得;烧瓶中二进制格式的参数?

Python 如何获取http";获得;烧瓶中二进制格式的参数?,python,http,flask,bittorrent,Python,Http,Flask,Bittorrent,我正在尝试写一个bittorrent跟踪器。跟踪器协议将二进制十六进制编码到http“GET”参数中。它看起来类似于以下内容: http://localhost:5000/announce?info_hash=%C5O%94%1b%1a9%86%86%12B%D7U%D0%ACF%E9%FA%3c%5d2 如果我使用request.args,它将尝试将“info_hash”解码为字符串,这将不起作用,因为info_hash应该是一些原始二进制序列,不能用任何字符串编码表示 那么,我是否可以使用

我正在尝试写一个bittorrent跟踪器。跟踪器协议将二进制十六进制编码到http“GET”参数中。它看起来类似于以下内容:

http://localhost:5000/announce?info_hash=%C5O%94%1b%1a9%86%86%12B%D7U%D0%ACF%E9%FA%3c%5d2
如果我使用request.args,它将尝试将“info_hash”解码为字符串,这将不起作用,因为info_hash应该是一些原始二进制序列,不能用任何字符串编码表示

那么,我是否可以使用任何东西来提取以字节为单位的结果,而不必滚动我自己的解析器


谢谢

不幸的是,在标准库中似乎没有一种真正简单的方法来实现这一点

方法是通过
request.query\u string
获取原始查询字符串并对其进行解析。问题是Python标准库函数都假定值也是Unicode,这对于Bittorrent跟踪器来说当然不是真的,正如您所指出的

问题是,标准库具有所有必需的功能,即
parse_qs
from
urllib.parse
函数,只需稍加修改即可实现:

def parse_qs_to_bytes(qs, keep_blank_values=False, strict_parsing=False,
             max_num_fields=None):
  
    parsed_result = {}
    pairs = parse_qsl(qs, keep_blank_values, strict_parsing,
                      max_num_fields=max_num_fields)
    for name, value in pairs:
        if name in parsed_result:
            parsed_result[name].append(value)
        else:
            parsed_result[name] = [value]
    return parsed_result


def parse_qsl(qs, keep_blank_values=False, strict_parsing=False,
              max_num_fields=None):
    if max_num_fields is not None:
        num_fields = 1 + qs.count('&') + qs.count(';')
        if max_num_fields < num_fields:
            raise ValueError('Max number of fields exceeded')
    pairs = [s2 for s1 in qs.split('&') for s2 in s1.split(';')]
    r = []
    for name_value in pairs:
        if not name_value and not strict_parsing:
            continue
        nv = name_value.split('=', 1)
        if len(nv) != 2:
            if strict_parsing:
                raise ValueError("bad query field: %r" % (name_value,))
            # Handle case of a control-name with no equal sign
            if keep_blank_values:
                nv.append('')
            else:
                continue
        if len(nv[1]) or keep_blank_values:
            name = nv[0].replace('+', ' ')
            name = unquote(name)
            value = nv[1].replace('+', ' ')
            value = unquote_to_bytes(value) # changed line from original to prevent coercing into unicode
            r.append((name, value))
    return r


def parse_qs_to_bytes(qs,keep_blank_value=False,strict_parsing=False,
最大数量字段=无):
已解析的_结果={}
pairs=parse_qsl(qs,keep_blank_值,strict_解析,
最大数量字段=最大数量字段)
对于名称,成对的值:
如果解析结果中的名称:
已分析的_结果[名称]。追加(值)
其他:
解析的_结果[名称]=[值]
返回解析的结果
def parse_qsl(qs,keep_blank_values=False,strict_parse=False,
最大数量字段=无):
如果max_num_字段不是None:
num_fields=1+qs.count('&')+qs.count(';'))
如果最大数量字段<数量字段:
raise VALUERROR('超出最大字段数')
pairs=[s1在qs.split('&')中用于s1.split(';')中的s2]
r=[]
对于成对的name_值:
如果不命名\u值且不严格\u解析:
持续
nv=name_value.split('=',1)
如果len(nv)!=2:
如果是严格的语法分析:
raise VALUERROR(“错误的查询字段:%r”%(名称\u值,))
#处理不带等号的控件名称的大小写
如果将_保留为空_值:
内文附加(“”)
其他:
持续
如果len(nv[1])或保留空白值:
名称=nv[0]。替换('+','')
name=unquote(name)
值=nv[1]。替换('+','')
value=unquote_to_bytes(value)#更改了原始行以防止强制转换为unicode
r、 追加((名称、值))
返回r
因此,您应该能够调用
parse\u qs\u bytes\u to\u bytes(request.query\u string.decode())