1
0
mirror of https://github.com/kevin1024/vcrpy.git synced 2025-12-08 16:53:23 +00:00

Make request.headers always a CaseInsensitiveDict.

Previously request.headers was a normal dict (albeit with the
request.add_header interface) which meant that some code paths would do
case-sensitive matching, for example remove_post_data_parameters which
tests for 'Content-Type'. This change allows all code paths to get the same
case-insensitive treatment.

Additionally request.headers becomes a property to enforce upgrading it to
a CaseInsensitiveDict even if assigned.
This commit is contained in:
Aron Griffis
2015-08-24 12:58:34 -04:00
parent efe6744eda
commit eda64bc3be
5 changed files with 24 additions and 21 deletions

View File

@@ -17,11 +17,7 @@ def _request_with_auth(url, username, password):
def _find_header(cassette, header): def _find_header(cassette, header):
for request in cassette.requests: return any(header in request.headers for request in cassette.requests)
for k in request.headers:
if header.lower() == k.lower():
return True
return False
def test_filter_basic_auth(tmpdir): def test_filter_basic_auth(tmpdir):

View File

@@ -1,19 +1,16 @@
from six import BytesIO, text_type from six import BytesIO, text_type
from six.moves.urllib.parse import urlparse, urlencode, urlunparse from six.moves.urllib.parse import urlparse, urlencode, urlunparse
import copy
import json import json
from .compat import collections from .compat import collections
def remove_headers(request, headers_to_remove): def remove_headers(request, headers_to_remove):
headers = copy.copy(request.headers) new_headers = request.headers.copy()
headers_to_remove = [h.lower() for h in headers_to_remove] for k in headers_to_remove:
keys = [k for k in headers if k.lower() in headers_to_remove] if k in new_headers:
if keys: del new_headers[k]
for k in keys: request.headers = new_headers
headers.pop(k)
request.headers = headers
return request return request

View File

@@ -1,6 +1,6 @@
import json import json
from six.moves import urllib, xmlrpc_client from six.moves import urllib, xmlrpc_client
from .util import CaseInsensitiveDict, read_body from .util import read_body
import logging import logging
@@ -66,9 +66,8 @@ def _identity(x):
def _get_transformer(request): def _get_transformer(request):
headers = CaseInsensitiveDict(request.headers)
for checker, transformer in _checker_transformer_pairs: for checker, transformer in _checker_transformer_pairs:
if checker(headers): return transformer if checker(request.headers): return transformer
else: else:
return _identity return _identity

View File

@@ -1,10 +1,11 @@
from six import BytesIO, text_type from six import BytesIO, text_type
from six.moves.urllib.parse import urlparse, parse_qsl from six.moves.urllib.parse import urlparse, parse_qsl
from .util import CaseInsensitiveDict
class Request(object): class Request(object):
""" """
VCR's representation of a request. VCR's representation of a request.
There is a weird quirk in HTTP. You can send the same header twice. For There is a weird quirk in HTTP. You can send the same header twice. For
this reason, headers are represented by a dict, with lists as the values. this reason, headers are represented by a dict, with lists as the values.
@@ -32,9 +33,19 @@ class Request(object):
self.body = body.read() self.body = body.read()
else: else:
self.body = body self.body = body
self.headers = {} self.headers = CaseInsensitiveDict()
for key in headers: for key, value in headers.items():
self.add_header(key, headers[key]) self.add_header(key, value)
@property
def headers(self):
return self._headers
@headers.setter
def headers(self, value):
if not isinstance(value, CaseInsensitiveDict):
value = CaseInsensitiveDict(value)
self._headers = value
@property @property
def body(self): def body(self):

View File

@@ -15,7 +15,7 @@ def vcr_fetch_impl(cassette, real_fetch_impl):
@functools.wraps(real_fetch_impl) @functools.wraps(real_fetch_impl)
def new_fetch_impl(self, request, callback): def new_fetch_impl(self, request, callback):
headers = dict(request.headers) headers = request.headers.copy()
if request.user_agent: if request.user_agent:
headers.setdefault('User-Agent', request.user_agent) headers.setdefault('User-Agent', request.user_agent)