Accept more types of input for headers/meta
Previously, we only accepted iterables of strings like 'Header: Value'. Now, we'll also accept lists of tuples like ('Header', 'Value') as well as dictionaries like {'Header': 'Value'}. This should be more intuitive for application developers, who are already used to being able to pass dicts or lists of tuples to libraries like requests. Change-Id: I93ed2f1e8305f0168b7a4bd90c205b04730da836
This commit is contained in:
parent
12d42efad2
commit
a1e2bcde4a
@ -29,11 +29,10 @@ from posixpath import join as urljoin
|
||||
from random import shuffle
|
||||
from time import time
|
||||
from threading import Thread
|
||||
from six import StringIO, text_type
|
||||
from six import Iterator, StringIO, string_types, text_type
|
||||
from six.moves.queue import Queue
|
||||
from six.moves.queue import Empty as QueueEmpty
|
||||
from six.moves.urllib.parse import quote
|
||||
from six import Iterator, string_types
|
||||
|
||||
import json
|
||||
|
||||
@ -274,7 +273,10 @@ def split_headers(options, prefix=''):
|
||||
"""
|
||||
Splits 'Key: Value' strings and returns them as a dictionary.
|
||||
|
||||
:param options: An array of 'Key: Value' strings
|
||||
:param options: Must be one of:
|
||||
* an iterable of 'Key: Value' strings
|
||||
* an iterable of ('Key', 'Value') pairs
|
||||
* a dict of {'Key': 'Value'} pairs
|
||||
:param prefix: String to prepend to all of the keys in the dictionary.
|
||||
reporting.
|
||||
"""
|
||||
|
@ -13,6 +13,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""Miscellaneous utility functions for use with Swift."""
|
||||
import collections
|
||||
import gzip
|
||||
import hashlib
|
||||
import hmac
|
||||
@ -148,15 +149,24 @@ def parse_api_response(headers, body):
|
||||
|
||||
def split_request_headers(options, prefix=''):
|
||||
headers = {}
|
||||
if isinstance(options, collections.Mapping):
|
||||
options = options.items()
|
||||
for item in options:
|
||||
split_item = item.split(':', 1)
|
||||
if len(split_item) == 2:
|
||||
headers[(prefix + split_item[0]).title()] = split_item[1].strip()
|
||||
else:
|
||||
if isinstance(item, six.string_types):
|
||||
if ':' not in item:
|
||||
raise ValueError(
|
||||
"Metadata parameter %s must contain a ':'.\n"
|
||||
"Example: 'Color:Blue' or 'Size:Large'"
|
||||
% item
|
||||
)
|
||||
item = item.split(':', 1)
|
||||
if len(item) != 2:
|
||||
raise ValueError(
|
||||
"Metadata parameter %s must contain a ':'.\n%s"
|
||||
% (item, "Example: 'Color:Blue' or 'Size:Large'")
|
||||
"Metadata parameter %r must have exactly two items.\n"
|
||||
"Example: ('Color', 'Blue') or ['Size', 'Large']"
|
||||
% (item, )
|
||||
)
|
||||
headers[(prefix + item[0]).title()] = item[1].strip()
|
||||
return headers
|
||||
|
||||
|
||||
|
@ -592,11 +592,24 @@ class TestServiceUtils(unittest.TestCase):
|
||||
actual = swiftclient.service.split_headers(mock_headers, 'prefix-')
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_split_headers_error(self):
|
||||
mock_headers = ['notvalid']
|
||||
def test_split_headers_list_of_tuples(self):
|
||||
mock_headers = [('color', 'blue'), ('size', 'large')]
|
||||
expected = {'Prefix-Color': 'blue', 'Prefix-Size': 'large'}
|
||||
|
||||
actual = swiftclient.service.split_headers(mock_headers, 'prefix-')
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_split_headers_dict(self):
|
||||
expected = {'Color': 'blue', 'Size': 'large'}
|
||||
|
||||
actual = swiftclient.service.split_headers(expected)
|
||||
self.assertEqual(expected, actual)
|
||||
|
||||
def test_split_headers_error(self):
|
||||
self.assertRaises(SwiftError, swiftclient.service.split_headers,
|
||||
mock_headers)
|
||||
['notvalid'])
|
||||
self.assertRaises(SwiftError, swiftclient.service.split_headers,
|
||||
[('also', 'not', 'valid')])
|
||||
|
||||
|
||||
class TestSwiftUploadObject(unittest.TestCase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user