Skip to content
Permalink
Browse files

Add Authentication strip logic to ConnectionPool

  • Loading branch information...
sethmlarson committed Mar 26, 2018
1 parent 3d7f98b commit f99912beeaf230ee3634b938d3ea426ffd1f3e57
Showing with 39 additions and 1 deletion.
  1. +32 −1 test/with_dummyserver/test_connectionpool.py
  2. +7 −0 urllib3/connectionpool.py
@@ -5,11 +5,15 @@
import unittest
import time
import warnings
import json

import mock

from .. import (
TARPIT_HOST, VALID_SOURCE_ADDRESSES, INVALID_SOURCE_ADDRESSES,
TARPIT_HOST,
VALID_SOURCE_ADDRESSES,
INVALID_SOURCE_ADDRESSES,
requires_network
)
from ..port_helpers import find_unused_port
from urllib3 import (
@@ -743,6 +747,8 @@ def setUp(self):
self.pool = HTTPConnectionPool(self.host, self.port)
self.addCleanup(self.pool.close)

self.base_url_alt = 'http://%s:%d' % (self.host_alt, self.port)

def test_max_retry(self):
try:
r = self.pool.request('GET', '/redirect',
@@ -861,6 +867,31 @@ def test_multi_redirect_history(self):
actual = [(history.status, history.redirect_location) for history in r.retries.history]
self.assertEqual(actual, expected)

def test_redirect_cross_host_no_forward_auth_headers(self):
url = '/redirect?target=%s/headers' % self.base_url_alt
headers = {'Authentication': 'foo'}

resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False)

self.assertEqual(resp.status, 200)

data = json.loads(resp.data.decode('utf-8'))

self.assertNotIn('Authentication', data)

def test_redirect_cross_host_forward_auth_headers(self):
url = '/redirect?target=%s/headers' % self.base_url_alt
headers = {'Authentication': 'foo'}
retry = Retry(redirect=2, forward_auth_headers_across_hosts=True)

resp = self.pool.urlopen('GET', url, headers=headers, assert_same_host=False, retries=retry)

self.assertEqual(resp.status, 200)

data = json.loads(resp.data.decode('utf-8'))

self.assertEqual(data['Authentication'], 'foo')


class TestRetryAfter(HTTPDummyServerTestCase):
def setUp(self):
@@ -697,6 +697,13 @@ def drain_and_release_conn(response):
# drain and return the connection to the pool before recursing
drain_and_release_conn(response)

# Strip the Authentication header if redirecting to a new host
# and we don't want to forward that header across hosts.
if (not retries.forward_auth_headers_across_hosts
and 'Authentication' in headers
and not self.is_same_host(redirect_location)):
headers.pop('Authentication')

retries.sleep_for_retry(response)
log.debug("Redirecting %s -> %s", url, redirect_location)
return self.urlopen(

0 comments on commit f99912b

Please sign in to comment.
You can’t perform that action at this time.