From 31b35ab838dfab92ea199a2688fefb74215aa7e9 Mon Sep 17 00:00:00 2001 From: Nate Prewitt Date: Wed, 21 Sep 2016 10:19:44 -0600 Subject: [PATCH] removing redundant logic from prepare_content_length --- requests/models.py | 22 ++++++++++------------ tests/test_requests.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/requests/models.py b/requests/models.py index b9a9d360..ea25e356 100644 --- a/requests/models.py +++ b/requests/models.py @@ -424,7 +424,6 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): # Nottin' on you. body = None content_type = None - length = None if not data and json is not None: # urllib3 requires a bytes-like body. Python 2's json.dumps @@ -475,17 +474,16 @@ class PreparedRequest(RequestEncodingMixin, RequestHooksMixin): self.body = body def prepare_content_length(self, body): - if hasattr(body, 'seek') and hasattr(body, 'tell'): - curr_pos = body.tell() - body.seek(0, 2) - end_pos = body.tell() - self.headers['Content-Length'] = builtin_str(max(0, end_pos - curr_pos)) - body.seek(curr_pos, 0) - elif body is not None: - l = super_len(body) - if l: - self.headers['Content-Length'] = builtin_str(l) - elif (self.method not in ('GET', 'HEAD')) and (self.headers.get('Content-Length') is None): + """Prepare Content-Length header based on request method and body""" + if body is not None: + length = super_len(body) + if length: + # If length exists, set it. Otherwise, we fallback + # to Transfer-Encoding: chunked. + self.headers['Content-Length'] = builtin_str(length) + elif self.method not in ('GET', 'HEAD') and self.headers.get('Content-Length') is None: + # Set Content-Length to 0 for methods that can have a body + # but don't provide one. (i.e. not GET or HEAD) self.headers['Content-Length'] = '0' def prepare_auth(self, auth, url=''): diff --git a/tests/test_requests.py b/tests/test_requests.py index 24f296f0..3ea30db0 100755 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -90,6 +90,16 @@ class TestRequests: req = requests.Request(method, httpbin(method.lower())).prepare() assert 'Content-Length' not in req.headers + @pytest.mark.parametrize('method', ('POST', 'PUT', 'PATCH', 'OPTIONS')) + def test_no_body_content_length(self, httpbin, method): + req = requests.Request(method, httpbin(method.lower())).prepare() + assert req.headers['Content-Length'] == '0' + + @pytest.mark.parametrize('method', ('POST', 'PUT', 'PATCH', 'OPTIONS')) + def test_empty_content_length(self, httpbin, method): + req = requests.Request(method, httpbin(method.lower()), data='').prepare() + assert req.headers['Content-Length'] == '0' + def test_override_content_length(self, httpbin): headers = { 'Content-Length': 'not zero'