61 lines
1.6 KiB
Python
61 lines
1.6 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
"""
|
||
|
hyper/http20/util
|
||
|
~~~~~~~~~~~~~~~~~
|
||
|
|
||
|
Utility functions for use with hyper.
|
||
|
"""
|
||
|
from collections import defaultdict
|
||
|
|
||
|
|
||
|
def combine_repeated_headers(kvset):
|
||
|
"""
|
||
|
Given a list of key-value pairs (like for HTTP headers!), combines pairs
|
||
|
with the same key together, separating the values with NULL bytes. This
|
||
|
function maintains the order of input keys, because it's awesome.
|
||
|
"""
|
||
|
def set_pop(set, item):
|
||
|
set.remove(item)
|
||
|
return item
|
||
|
|
||
|
headers = defaultdict(list)
|
||
|
keys = set()
|
||
|
|
||
|
for key, value in kvset:
|
||
|
headers[key].append(value)
|
||
|
keys.add(key)
|
||
|
|
||
|
return [(set_pop(keys, k), b'\x00'.join(headers[k])) for k, v in kvset
|
||
|
if k in keys]
|
||
|
|
||
|
|
||
|
def split_repeated_headers(kvset):
|
||
|
"""
|
||
|
Given a set of key-value pairs (like for HTTP headers!), finds values that
|
||
|
have NULL bytes in them and splits them into a dictionary whose values are
|
||
|
lists.
|
||
|
"""
|
||
|
headers = defaultdict(list)
|
||
|
|
||
|
for key, value in kvset:
|
||
|
headers[key] = value.split(b'\x00')
|
||
|
|
||
|
return dict(headers)
|
||
|
|
||
|
|
||
|
def h2_safe_headers(headers):
|
||
|
"""
|
||
|
This method takes a set of headers that are provided by the user and
|
||
|
transforms them into a form that is safe for emitting over HTTP/2.
|
||
|
|
||
|
Currently, this strips the Connection header and any header it refers to.
|
||
|
"""
|
||
|
stripped = {
|
||
|
i.lower().strip()
|
||
|
for k, v in headers if k == 'connection'
|
||
|
for i in v.split(',')
|
||
|
}
|
||
|
stripped.add('connection')
|
||
|
|
||
|
return [header for header in headers if header[0] not in stripped]
|