def test_clean_connection(self): pool = None pooled = PooledHTTPConnection(self.netloc, self.scheme) conn = pooled.acquire() pool = pooled._pool self.assertTrue(pool is not None) pooled.release() self.assertTrue(pooled._pool is False) poolset = pool._set self.assertEqual(len(poolset), 1) pooled_conn = list(poolset)[0] self.assertTrue(pooled_conn is conn)
def test_distinct_pools_per_scheme(self): with PooledHTTPConnection("127.0.0.1", "http", attach_context=True, pool_key='test2') as conn: pool = conn._pool_context._pool self.assertTrue(pool is _http_pools[("test2", "http", "127.0.0.1")]) with PooledHTTPConnection("127.0.0.1", "https", attach_context=True, pool_key='test2') as conn2: pool2 = conn2._pool_context._pool self.assertTrue(conn is not conn2) self.assertNotEqual(pool, pool2) self.assertTrue(pool2 is _http_pools[("test2", "https", "127.0.0.1")])
def test_dirty_connection(self): pooled = PooledHTTPConnection(self.netloc, self.scheme) conn = pooled.acquire() pool = pooled._pool conn.request("GET", "/") serversock, addr = self.sock.accept() serversock.send("HTTP/1.1 200 OK\n" "Content-Length: 6\n" "\n" "HELLO\n") time.sleep(0.3) # We would read this message like this #resp = conn.getresponse() # but we won't so the connection is dirty pooled.release() poolset = pool._set self.assertEqual(len(poolset), 0)
def proxy(request, proxy_base=None, target_base=None): kwargs = {} if None in (proxy_base, target_base): m = "proxy() needs both proxy_base and target_base argument not None" raise AssertionError(m) parsed = urlparse.urlparse(target_base) target_base = '/' + parsed.path.strip('/') proxy_base = proxy_base.strip('/') # prepare headers headers = dict( map(lambda (k, v): fix_header(k, v), filter(lambda (k, v): forward_header(k), request.META.iteritems()))) # set X-Forwarded-For, if already set, pass it through, otherwise set it # to the current request remote address SOURCE_IP = request.META.get('REMOTE_ADDR', None) if SOURCE_IP and not 'X-Forwarded-For' in headers: headers['X-Forwarded-For'] = SOURCE_IP # request.META remains cleanup for k in headers.keys(): if '_' in k: headers.pop(k) for k in EXCLUDE_HEADERS: headers.pop(k, None) kwargs['headers'] = headers kwargs['body'] = request.raw_post_data path = request.path.lstrip('/') if path.startswith(proxy_base): m = "request path '{0}' does not start with proxy_base '{1}'" m = m.format(path, proxy_base) path = path.replace(proxy_base, '', 1) path = join_urls(target_base, path) with PooledHTTPConnection(parsed.netloc, parsed.scheme) as conn: conn.request(request.method, '?'.join([path, urllib.urlencode(request.GET)]), **kwargs) response = conn.getresponse() # turn httplib.HttpResponse to django.http.Response length = response.getheader('content-length', None) data = response.read(length) status = int(response.status) django_http_response = HttpResponse(data, status=status) # do we need to exclude any headers here? for name, value in response.getheaders(): django_http_response[name] = value return django_http_response
def test_double_release(self): pooled = PooledHTTPConnection(self.netloc, self.scheme, pool_key='test_key') pooled.acquire() pool = pooled._pool cached_pool = _http_pools[("test_key", self.scheme, self.netloc)] self.assertTrue(pooled._pool is cached_pool) pooled.release() poolsize = len(pool._set) if PooledHTTPConnection._pool_disable_after_release: self.assertTrue(pooled._pool is False) if not PooledHTTPConnection._pool_ignore_double_release: with self.assertRaises(AssertionError): pooled.release() else: pooled.release() self.assertEqual(poolsize, len(pool._set))
def test_double_release(self): pooled = PooledHTTPConnection(self.netloc, self.scheme) pooled.acquire() pool = pooled._pool cached_pool = _http_pools[(self.scheme, self.netloc)] self.assertTrue(pooled._pool is cached_pool) pooled.release() poolsize = len(pool._set) if PooledHTTPConnection._pool_disable_after_release: self.assertTrue(pooled._pool is False) if not PooledHTTPConnection._pool_ignore_double_release: with self.assertRaises(AssertionError): pooled.release() else: pooled.release() self.assertEqual(poolsize, len(pool._set))
def test_context_manager_exception_safety(self): class TestError(Exception): pass for i in xrange(10): pool = None try: with PooledHTTPConnection( self.netloc, self.scheme, size=1, attach_context=True) as conn: pool = conn._pool_context._pool raise TestError() except TestError: self.assertTrue(pool is not None) self.assertEqual(pool._semaphore._Semaphore__value, 1)
def _objpool(netloc): """Helper function to return a PooledHTTPConnection object""" return PooledHTTPConnection(netloc=netloc, scheme=scheme, size=pool_size)
def proxy(request, proxy_base=None, target_base=None, redirect=False): kwargs = {} if None in (proxy_base, target_base): m = "proxy() needs both proxy_base and target_base argument not None" raise AssertionError(m) # Get strings from lazy objects proxy_base = str(proxy_base) target_base = str(target_base) parsed = urlparse.urlparse(target_base) target_path = '/' + parsed.path.strip('/') proxy_base = proxy_base.strip('/') # prepare headers headers = dict( map(lambda (k, v): fix_header(k, v), filter(lambda (k, v): forward_header(k), request.META.iteritems()))) # set X-Forwarded-For, if already set, pass it through, otherwise set it # to the current request remote address source_ip = request.META.get('REMOTE_ADDR', None) if source_ip and not 'X-Forwarded-For' in headers: headers['X-Forwarded-For'] = source_ip # request.META remains cleanup for k in headers.keys(): if '_' in k: headers.pop(k) for k in EXCLUDE_HEADERS: headers.pop(k, None) kwargs['headers'] = headers kwargs['body'] = request.body path = smart_str(request.path, encoding='utf-8').lstrip('/') if not path.startswith(proxy_base): m = "request path '{0}' does not start with proxy_base '{1}'" m = m.format(path, proxy_base) raise AssertionError(m) path = path.replace(proxy_base, '', 1) # redirect to target instead of proxing if redirect: redirect_url = join_urls(target_base, path) qs = request.GET.urlencode() return HttpResponseRedirect('?'.join([redirect_url, qs])) path = join_urls(target_path, path) with PooledHTTPConnection(parsed.netloc, parsed.scheme) as conn: conn.request(request.method, '?'.join([path, request.GET.urlencode()]), **kwargs) response = conn.getresponse() # turn httplib.HttpResponse to django.http.Response length = response.getheader('content-length', None) data = response.read(length) status = int(response.status) django_http_response = HttpResponse(data, status=status) # do we need to exclude any headers here? for name, value in response.getheaders(): django_http_response[name] = value return django_http_response
def _objpool(netloc): return PooledHTTPConnection(netloc=netloc, scheme=scheme, size=pool_size)