Updated Branches: refs/heads/0.13.1 [created] 7e18941c4
Fix a regression introduced in 0.13.0 and make sure to include Content-Length 0 with PUT and POST requests. Also add test cases for it. Part of LIBCLOUD-362. Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/a73cc099 Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/a73cc099 Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/a73cc099 Branch: refs/heads/0.13.1 Commit: a73cc099b5c6f04eeaef10a6de7147daf9f98cc7 Parents: 9c0d11a Author: Tomaz Muraus <[email protected]> Authored: Thu Aug 8 14:39:13 2013 +0200 Committer: Tomaz Muraus <[email protected]> Committed: Wed Sep 4 11:57:54 2013 +0200 ---------------------------------------------------------------------- CHANGES | 8 ++++ libcloud/common/base.py | 6 ++- libcloud/test/test_connection.py | 88 +++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/a73cc099/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 640bd2f..1206d98 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,13 @@ -*- coding: utf-8 -*- +Changes with Apache Libcloud in development + + *) General + + - Fix a regression introduced in 0.13.0 and make sure to include + Content-Length 0 with PUT and POST requests. (LIBCLOUD-362) + [Tomaz Muraus] + Changes with Apache Libcloud 0.13.0: *) General http://git-wip-us.apache.org/repos/asf/libcloud/blob/a73cc099/libcloud/common/base.py ---------------------------------------------------------------------- diff --git a/libcloud/common/base.py b/libcloud/common/base.py index 464bec8..0634588 100644 --- a/libcloud/common/base.py +++ b/libcloud/common/base.py @@ -592,9 +592,11 @@ class Connection(object): headers.update({'Host': self.host}) # Encode data if necessary - if data: + if data is not None: data = self.encode_data(data) - headers.update({'Content-Length': str(len(data))}) + # Only send Content-Length 0 with POST and PUT request + if len(data) > 0 or (len(data) == 0 and method in ['POST', 'PUT']): + headers.update({'Content-Length': str(len(data))}) params, headers = self.pre_connect_hook(params, headers) http://git-wip-us.apache.org/repos/asf/libcloud/blob/a73cc099/libcloud/test/test_connection.py ---------------------------------------------------------------------- diff --git a/libcloud/test/test_connection.py b/libcloud/test/test_connection.py new file mode 100644 index 0000000..938e170 --- /dev/null +++ b/libcloud/test/test_connection.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- +# Licensed to the Apache Software Foundation (ASF) under one or more§ +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import sys +import unittest + +from mock import Mock + +from libcloud.common.base import Connection + + +class ConnectionClassTestCase(unittest.TestCase): + def setUp(self): + self.originalConnect = Connection.connect + self.originalResponseCls = Connection.responseCls + + Connection.connect = Mock() + Connection.responseCls = Mock() + + def tearDown(self): + Connection.connect = self.originalConnect + Connection.responseCls = Connection.responseCls + + 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 is 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, no content length should be present + con.request('/test', method='POST', data=None) + call_kwargs = con.connection.request.call_args[1] + self.assertTrue('Content-Length' not in call_kwargs['headers']) + + con.request('/test', method='PUT', data=None) + call_kwargs = con.connection.request.call_args[1] + self.assertTrue('Content-Length' not in call_kwargs['headers']) + + # '' as data, content length should be present + con.request('/test', method='POST', data='') + call_kwargs = con.connection.request.call_args[1] + self.assertEqual(call_kwargs['headers']['Content-Length'], '0') + + con.request('/test', method='PUT', 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 + con.request('/test', method='POST', data='a') + call_kwargs = con.connection.request.call_args[1] + self.assertEqual(call_kwargs['headers']['Content-Length'], '1') + + con.request('/test', method='PUT', data='a') + call_kwargs = con.connection.request.call_args[1] + self.assertEqual(call_kwargs['headers']['Content-Length'], '1') + + +if __name__ == '__main__': + sys.exit(unittest.main())
