def test_raw_request_without_proxy(self, patched_putrequest, *unused_args): host = '1.2.3.4' port = '31337' method = 'FAKEMETHOD' action = '/fakeendpoint' conn = Connection(secure=True, host=host, port=port) conn.request(action, params={}, data=None, headers=None, method=method, raw=True) patched_putrequest.assert_called_once_with(method, action)
def test_retry_connection(self): con = Connection(timeout=0.2, retry_delay=0.1) con.connection = Mock() connect_method = 'libcloud.common.base.Connection.request' with patch(connect_method) as mock_connect: try: mock_connect.side_effect = socket.gaierror('') con.request('/') except socket.gaierror: pass
def test_debug_log_class_handles_request(self): with StringIO() as fh: libcloud.enable_debug(fh) conn = Connection(url="http://test.com/") conn.connect() self.assertEqual(conn.connection.host, "http://test.com") with requests_mock.mock() as m: m.get("http://test.com/test", text="data") conn.request("/test") log = fh.getvalue() self.assertTrue(isinstance(conn.connection, LoggingConnection)) self.assertIn("-i -X GET", log) self.assertIn("data", log)
def test_debug_log_class_handles_request(self): with StringIO() as fh: libcloud.enable_debug(fh) conn = Connection(url='http://test.com/') conn.connect() self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/test', text='data') conn.request('/test') log = fh.getvalue() self.assertTrue(isinstance(conn.connection, LoggingConnection)) self.assertIn('-i -X GET', log) self.assertIn('data', log)
def test_debug_log_class_handles_request(self): with StringIO() as fh: libcloud.enable_debug(fh) conn = Connection(url='http://test.com/') conn.connect() self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/test', text='data') conn.request('/test') log = fh.getvalue() self.assertTrue(isinstance(conn.connection, LoggingConnection)) self.assertIn('-i -X GET', log) self.assertIn('data', log)
def test_retry_connection(self): con = Connection(timeout=1, retry_delay=0.1) con.connection = Mock() connect_method = 'libcloud.common.base.Connection.request' with patch(connect_method) as mock_connect: try: mock_connect.side_effect = socket.gaierror('') con.request('/') except socket.gaierror: pass except Exception: self.fail('Failed to raise socket exception')
def test_cache_busting(self): params1 = {"foo1": "bar1", "foo2": "bar2"} params2 = [("foo1", "bar1"), ("foo2", "bar2")] con = Connection() con.connection = Mock() con.pre_connect_hook = Mock() con.pre_connect_hook.return_value = {}, {} con.cache_busting = False con.request(action="/path", params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertFalse("cache-busting" in args[0]) self.assertEqual(args[0], params1) con.request(action="/path", params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertFalse("cache-busting" in args[0]) self.assertEqual(args[0], params2) con.cache_busting = True con.request(action="/path", params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertTrue("cache-busting" in args[0]) con.request(action="/path", params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertTrue("cache-busting" in args[0][len(params2)])
def test_cache_busting(self): params1 = {'foo1': 'bar1', 'foo2': 'bar2'} params2 = [('foo1', 'bar1'), ('foo2', 'bar2')] con = Connection() con.connection = Mock() con.pre_connect_hook = Mock() con.pre_connect_hook.return_value = {}, {} con.cache_busting = False con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params1) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params2) con.cache_busting = True con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0]) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0][len(params2)])
def test_cache_busting(self): params1 = {"foo1": "bar1", "foo2": "bar2"} params2 = [("foo1", "bar1"), ("foo2", "bar2")] con = Connection() con.connection = Mock() con.pre_connect_hook = Mock() con.pre_connect_hook.return_value = {}, {} con.cache_busting = False con.request(action="/path", params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertFalse("cache-busting" in args[0]) self.assertEqual(args[0], params1) con.request(action="/path", params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertFalse("cache-busting" in args[0]) self.assertEqual(args[0], params2) con.cache_busting = True con.request(action="/path", params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertTrue("cache-busting" in args[0]) con.request(action="/path", params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertTrue("cache-busting" in args[0][len(params2)])
def test_cache_busting(self): params1 = {'foo1': 'bar1', 'foo2': 'bar2'} params2 = [('foo1', 'bar1'), ('foo2', 'bar2')] con = Connection() con.connection = Mock() con.pre_connect_hook = Mock() con.pre_connect_hook.return_value = {}, {} con.cache_busting = False con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params1) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertFalse('cache-busting' in args[0]) self.assertEqual(args[0], params2) con.cache_busting = True con.request(action='/path', params=params1) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0]) con.request(action='/path', params=params2) args, kwargs = con.pre_connect_hook.call_args self.assertTrue('cache-busting' in args[0][len(params2)])
def test_debug_log_class_handles_request_with_compression(self): request = zlib.compress(b'data') with StringIO() as fh: libcloud.enable_debug(fh) conn = Connection(url='http://test.com/') conn.connect() self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/test', content=request, headers={'content-encoding': 'zlib'}) conn.request('/test') log = fh.getvalue() self.assertTrue(isinstance(conn.connection, LoggingConnection)) self.assertIn('-i -X GET', log)
def test_raw_request_with_proxy(self, patched_putrequest, *unused_args): proxy_url = 'http://127.0.0.1:3128' host = '1.2.3.4' port = '31337' method = 'FAKEMETHOD' action = '/fakeendpoint' conn = Connection(secure=True, host=host, port=port) conn.set_http_proxy(proxy_url) conn.responseCls = FakeResponse conn.request(action, params={}, data=None, headers=None, method=method, raw=True) proxied_action = "https://%s:%s%s" % (host, port, action) patched_putrequest.assert_called_once_with(method, proxied_action)
def get_response_object(url, method='GET', headers=None, retry_failed=None): """ Utility function which uses libcloud's connection class to issue an HTTP request. :param url: URL to send the request to. :type url: ``str`` :param method: HTTP method. :type method: ``str`` :param headers: Optional request headers. :type headers: ``dict`` :param retry_failed: True to retry failed requests. :return: Response object. :rtype: :class:`Response`. """ parsed_url = urlparse.urlparse(url) parsed_qs = parse_qs(parsed_url.query) secure = parsed_url.scheme == 'https' headers = headers or {} method = method.upper() con = Connection(secure=secure, host=parsed_url.netloc) response = con.request(action=parsed_url.path, params=parsed_qs, headers=headers, method=method, retry_failed=retry_failed) return response
def test_parse_errors_can_be_retried(self): class RetryableThrowingError(Response): parse_error_counter: int = 0 success_counter: int = 0 def __init__(self, *_, **__): super().__init__(mock.MagicMock(), mock.MagicMock()) def parse_body(self): return super().parse_body() def parse_error(self): RetryableThrowingError.parse_error_counter += 1 if RetryableThrowingError.parse_error_counter > 1: return "success" else: raise RateLimitReachedError() def success(self): RetryableThrowingError.success_counter += 1 if RetryableThrowingError.success_counter > 1: return True else: return False con = Connection() con.connection = Mock() con.responseCls = RetryableThrowingError result = con.request(action="/", retry_failed=True) self.assertEqual(result.success(), True)
def get_response_object(url, method='GET', headers=None): """ Utility function which uses libcloud's connection class to issue an HTTP request. :param url: URL to send the request to. :type url: ``str`` :param method: HTTP method. :type method: ``str`` :param headers: Optional request headers. :type headers: ``dict`` :return: Response object. :rtype: :class:`Response`. """ parsed_url = urlparse.urlparse(url) parsed_qs = parse_qs(parsed_url.query) secure = parsed_url.scheme == 'https' headers = headers or {} method = method.upper() con = Connection(secure=secure, host=parsed_url.netloc) response = con.request(action=parsed_url.path, params=parsed_qs, headers=headers, method=method) return response
def test_RawResponse_class_read_method(self): """ Test that the RawResponse class includes a response property which exhibits the same properties and methods as httplib.HTTPResponse for backward compat <1.5.0 """ TEST_DATA = '1234abcd' conn = Connection(host='mock.com', port=80, secure=False) conn.connect() with requests_mock.Mocker() as m: m.register_uri('GET', 'http://mock.com/raw_data', text=TEST_DATA, headers={'test': 'value'}) response = conn.request('/raw_data', raw=True) data = response.response.read() self.assertEqual(data, TEST_DATA) header_value = response.response.getheader('test') self.assertEqual(header_value, 'value') headers = response.response.getheaders() self.assertEqual(headers, [('test', 'value')]) self.assertEqual(response.response.status, 200)
def test_RawResponse_class_read_method(self): """ Test that the RawResponse class includes a response property which exhibits the same properties and methods as httplib.HTTPResponse for backward compat <1.5.0 """ TEST_DATA = "1234abcd" conn = Connection(host="mock.com", port=80, secure=False) conn.connect() with requests_mock.Mocker() as m: m.register_uri( "GET", "http://mock.com/raw_data", text=TEST_DATA, headers={"test": "value"}, ) response = conn.request("/raw_data", raw=True) data = response.response.read() self.assertEqual(data, TEST_DATA) header_value = response.response.getheader("test") self.assertEqual(header_value, "value") headers = response.response.getheaders() self.assertEqual(headers, [("test", "value")]) self.assertEqual(response.response.status, 200)
def test_RawResponse_class_read_method(self): """ Test that the RawResponse class includes a response property which exhibits the same properties and methods as httplib.HTTPResponse for backward compat <1.5.0 """ TEST_DATA = '1234abcd' conn = Connection(host='mock.com', port=80, secure=False) conn.connect() with requests_mock.Mocker() as m: m.register_uri('GET', 'http://mock.com/raw_data', text=TEST_DATA, headers={'test': 'value'}) response = conn.request('/raw_data', raw=True) data = response.response.read() self.assertEqual(data, TEST_DATA) header_value = response.response.getheader('test') self.assertEqual(header_value, 'value') headers = response.response.getheaders() self.assertEqual(headers, [('test', 'value')]) self.assertEqual(response.response.status, 200)
def test_debug_log_class_handles_request_with_compression(self): request = zlib.compress(b"data") with StringIO() as fh: libcloud.enable_debug(fh) conn = Connection(url="http://test.com/") conn.connect() self.assertEqual(conn.connection.host, "http://test.com") with requests_mock.mock() as m: m.get( "http://test.com/test", content=request, headers={"content-encoding": "zlib"}, ) conn.request("/test") log = fh.getvalue() self.assertTrue(isinstance(conn.connection, LoggingConnection)) self.assertIn("-i -X GET", log)
def get_response_object(url): parsed_url = urlparse.urlparse(url) parsed_qs = parse_qs(parsed_url.query) secure = parsed_url.scheme == 'https' con = Connection(secure=secure, host=parsed_url.netloc) response = con.request(method='GET', action=parsed_url.path, params=parsed_qs) return response
def test_connection_url_merging(self): """ Test that the connection class will parse URLs correctly """ conn = Connection(url='http://test.com/') conn.connect() self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/test', text='data') response = conn.request('/test') self.assertEqual(response.body, 'data')
def test_connection_url_merging(self): """ Test that the connection class will parse URLs correctly """ conn = Connection(url="http://test.com/") conn.connect() self.assertEqual(conn.connection.host, "http://test.com") with requests_mock.mock() as m: m.get("http://test.com/test", text="data") response = conn.request("/test") self.assertEqual(response.body, "data")
def test_connection_url_merging(self): """ Test that the connection class will parse URLs correctly """ conn = Connection(url='http://test.com/') conn.connect() self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/test', text='data') response = conn.request('/test') self.assertEqual(response.body, 'data')
def test_request_parses_errors(self): class ThrowingResponse(Response): def __init__(self, *_, **__): super().__init__(mock.MagicMock(), mock.MagicMock()) def parse_body(self): return super().parse_body() def parse_error(self): raise RateLimitReachedError() def success(self): return False con = Connection() con.connection = Mock() con.responseCls = ThrowingResponse with self.assertRaises(RateLimitReachedError): con.request(action="/")
def test_connect_with_prefix(self): """ Test that a connection with a base path (e.g. /v1/) will add the base path to requests """ conn = Connection(url="http://test.com/") conn.connect() conn.request_path = "/v1" self.assertEqual(conn.connection.host, "http://test.com") with requests_mock.mock() as m: m.get("http://test.com/v1/test", text="data") response = conn.request("/test") self.assertEqual(response.body, "data")
class MockHttpFileFixturesTests(unittest.TestCase): """ Test the behaviour of MockHttp """ def setUp(self): Connection.conn_class = TestMockHttp Connection.responseCls = Response self.connection = Connection() def test_unicode_response(self): r = self.connection.request("/unicode") self.assertEqual(r.parse_body(), "Ś") def test_json_unicode_response(self): self.connection.responseCls = JsonResponse r = self.connection.request("/unicode/json") self.assertEqual(r.object, {"test": "Ś"}) def test_xml_unicode_response(self): self.connection.responseCls = XmlResponse response = self.connection.request("/unicode/xml") self.assertEqual(response.object.text, "Ś")
def test_connect_with_prefix(self): """ Test that a connection with a base path (e.g. /v1/) will add the base path to requests """ conn = Connection(url='http://test.com/') conn.connect() conn.request_path = '/v1' self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/v1/test', text='data') response = conn.request('/test') self.assertEqual(response.body, 'data')
def test_connect_with_prefix(self): """ Test that a connection with a base path (e.g. /v1/) will add the base path to requests """ conn = Connection(url='http://test.com/') conn.connect() conn.request_path = '/v1' self.assertEqual(conn.connection.host, 'http://test.com') with requests_mock.mock() as m: m.get('http://test.com/v1/test', text='data') response = conn.request('/test') self.assertEqual(response.body, 'data')
def get_response_object(url): """ Utility function which uses libcloud's connection class to issue an HTTP request. :param url: URL to send the request to. :type url: ``str`` :return: Response object. :rtype: :class:`Response`. """ parsed_url = urlparse.urlparse(url) parsed_qs = parse_qs(parsed_url.query) secure = parsed_url.scheme == 'https' con = Connection(secure=secure, host=parsed_url.netloc) response = con.request(method='GET', action=parsed_url.path, params=parsed_qs) return response
def test_context_is_reset_after_request_has_finished(self): context = {'foo': 'bar'} def responseCls(connection, response): connection.called = True self.assertEqual(connection.context, context) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request('/') # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection() con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request('/') except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request('/') except ValueError: pass self.assertEqual(con.context, {})
def test_context_is_reset_after_request_has_finished(self): context = {"foo": "bar"} def responseCls(connection, response) -> mock.MagicMock: connection.called = True self.assertEqual(connection.context, context) return mock.MagicMock(spec=Response) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request("/") # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection(timeout=1, retry_delay=0.1) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request("/") except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request("/") except ValueError: pass self.assertEqual(con.context, {})
def test_context_is_reset_after_request_has_finished(self): context = {'foo': 'bar'} def responseCls(connection, response): connection.called = True self.assertEqual(connection.context, context) con = Connection() con.called = False con.connection = Mock() con.responseCls = responseCls con.set_context(context) self.assertEqual(con.context, context) con.request('/') # Context should have been reset self.assertTrue(con.called) self.assertEqual(con.context, {}) # Context should also be reset if a method inside request throws con = Connection() con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.connection.request = Mock(side_effect=ssl.SSLError()) try: con.request('/') except ssl.SSLError: pass self.assertEqual(con.context, {}) con.connection = Mock() con.set_context(context) self.assertEqual(con.context, context) con.responseCls = Mock(side_effect=ValueError()) try: con.request('/') except ValueError: pass self.assertEqual(con.context, {})
def get_response_object(url): """ Utility function which uses libcloud's connection class to issue an HTTP request. :param url: URL to send the request to. :type url: ``str`` :return: Response object. :rtype: :class:`Response`. """ parsed_url = urlparse.urlparse(url) parsed_qs = parse_qs(parsed_url.query) secure = parsed_url.scheme == 'https' con = Connection(secure=secure, host=parsed_url.netloc) response = con.request(method='GET', action=parsed_url.path, params=parsed_qs) return response
def test_content_length(self): con = Connection() con.connection = Mock() # GET method # No data, no content length should be present con.request('/test', method='GET', data=None) call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # '' as data, no content length should be present con.request('/test', method='GET', data='') call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # 'a' as data, content length should be present (data in GET is not # correct, but anyways) con.request('/test', method='GET', data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1') # POST, PUT method # No data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None) call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # '' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # No data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # '' as data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # 'a' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1')
def test_content_length(self): con = Connection() con.connection = Mock() ## GET method # No data, no content length should be present con.request('/test', method='GET', data=None) call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # '' as data, no content length should be present con.request('/test', method='GET', data='') call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # 'a' as data, content length should be present (data in GET is not # corect, but anyways) con.request('/test', method='GET', data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1') ## POST, PUT method # No data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None) call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # '' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # 'a' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1')
def test_content_length(self): con = Connection() con.connection = Mock() # GET method # No data, no content length should be present con.request("/test", method="GET", data=None) call_kwargs = con.connection.request.call_args[1] self.assertTrue("Content-Length" not in call_kwargs["headers"]) # '' as data, no content length should be present con.request("/test", method="GET", data="") call_kwargs = con.connection.request.call_args[1] self.assertTrue("Content-Length" not in call_kwargs["headers"]) # 'a' as data, content length should be present (data in GET is not # correct, but anyways) con.request("/test", method="GET", data="a") call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs["headers"]["Content-Length"], "1") # POST, PUT method # No data, content length should be present for method in ["POST", "PUT", "post", "put"]: con.request("/test", method=method, data=None) call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs["headers"]["Content-Length"], "0") # '' as data, content length should be present for method in ["POST", "PUT", "post", "put"]: con.request("/test", method=method, data="") call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs["headers"]["Content-Length"], "0") # No data, raw request, do not touch Content-Length if present for method in ["POST", "PUT", "post", "put"]: con.request("/test", method=method, data=None, headers={"Content-Length": "42"}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call("Content-Length", "42"), putheader_call_list) # '' as data, raw request, do not touch Content-Length if present for method in ["POST", "PUT", "post", "put"]: con.request("/test", method=method, data=None, headers={"Content-Length": "42"}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call("Content-Length", "42"), putheader_call_list) # 'a' as data, content length should be present for method in ["POST", "PUT", "post", "put"]: con.request("/test", method=method, data="a") call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs["headers"]["Content-Length"], "1")
def test_content_length(self): con = Connection() con.connection = Mock() ## GET method # No data, no content length should be present con.request('/test', method='GET', data=None) call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # '' as data, no content length should be present con.request('/test', method='GET', data='') call_kwargs = con.connection.request.call_args[1] self.assertTrue('Content-Length' not in call_kwargs['headers']) # 'a' as data, content length should be present (data in GET is not # corect, but anyways) con.request('/test', method='GET', data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1') ## POST, PUT method # No data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None) call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # '' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '0') # No data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # '' as data, raw request, do not touch Content-Length if present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data=None, headers={'Content-Length': '42'}, raw=True) putheader_call_list = con.connection.putheader.call_args_list self.assertIn(call('Content-Length', '42'), putheader_call_list) # 'a' as data, content length should be present for method in ['POST', 'PUT', 'post', 'put']: con.request('/test', method=method, data='a') call_kwargs = con.connection.request.call_args[1] self.assertEqual(call_kwargs['headers']['Content-Length'], '1')