diff --git a/AUTHORS.rst b/AUTHORS.rst index 424493b149..470356aac1 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -190,3 +190,4 @@ Patches and Suggestions - Antti Kaihola (`@akaihola `_) - "Dull Bananas" (`@dullbananas `_) - Alessio Izzo (`@aless10 `_) +- Hod Bin Noon (`@hodbn `_) diff --git a/requests/adapters.py b/requests/adapters.py index fa4d9b3cc9..a59f399365 100644 --- a/requests/adapters.py +++ b/requests/adapters.py @@ -459,7 +459,8 @@ def send(self, request, stream=False, timeout=None, verify=True, cert=None, prox try: low_conn.putrequest(request.method, url, - skip_accept_encoding=True) + skip_accept_encoding=True, + skip_host='Host' in request.headers) for header, value in request.headers.items(): low_conn.putheader(header, value) diff --git a/tests/test_lowlevel.py b/tests/test_lowlevel.py index 4127fb115e..0197ef10bf 100644 --- a/tests/test_lowlevel.py +++ b/tests/test_lowlevel.py @@ -24,6 +24,32 @@ def test_chunked_upload(): assert r.request.headers['Transfer-Encoding'] == 'chunked' +def test_chunked_upload_uses_only_specified_host_header(): + """Ensure we use only the specified Host header for chunked requests.""" + text_200 = (b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 0\r\n\r\n') + wanted_host = 'sample-host' + expected_header = 'Host: {}'.format(wanted_host).encode('utf-8') + def single_host_resp_handler(sock): + request_content = consume_socket_content(sock, timeout=0.5) + assert expected_header in request_content + assert request_content.count(b'Host: ') == 1 + sock.send(text_200) + + return request_content + + close_server = threading.Event() + server = Server(single_host_resp_handler, wait_to_close_event=close_server) + data = iter([b'a', b'b', b'c']) + + with server as (host, port): + url = 'http://{}:{}/'.format(host, port) + r = requests.post(url, data=data, headers={'Host': wanted_host}, stream=True) + close_server.set() # release server block + + assert r.status_code == 200 + + def test_digestauth_401_count_reset_on_redirect(): """Ensure we correctly reset num_401_calls after a successful digest auth, followed by a 302 redirect to another digest auth prompt.