Skip to content

Commit

Permalink
Make upload header handling case-insensitive.
Browse files Browse the repository at this point in the history
  • Loading branch information
lotten committed Jun 26, 2013
1 parent 4bca5d8 commit 60383d6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 8 deletions.
26 changes: 18 additions & 8 deletions boto/s3/key.py
Expand Up @@ -40,6 +40,8 @@
from boto.s3.user import User
from boto import UserAgent
from boto.utils import compute_md5
from boto.utils import find_matching_headers
from boto.utils import merge_headers_by_name
try:
from hashlib import md5
except ImportError:
Expand Down Expand Up @@ -836,23 +838,31 @@ def sender(http_conn, method, path, data, headers):
headers = {}
else:
headers = headers.copy()
# Overwrite user-supplied user-agent.
for header in find_matching_headers('User-Agent', headers):
del headers[header]
headers['User-Agent'] = UserAgent
if self.storage_class != 'STANDARD':
headers[provider.storage_class_header] = self.storage_class
if 'Content-Encoding' in headers:
self.content_encoding = headers['Content-Encoding']
if 'Content-Language' in headers:
self.content_encoding = headers['Content-Language']
if 'Content-Type' in headers:
if find_matching_headers('Content-Encoding', headers):
self.content_encoding = merge_headers_by_name(
'Content-Encoding', headers)
if find_matching_headers('Content-Language', headers):
self.content_language = merge_headers_by_name(
'Content-Language', headers)
content_type_headers = find_matching_headers('Content-Type', headers)
if content_type_headers:
# Some use cases need to suppress sending of the Content-Type
# header and depend on the receiving server to set the content
# type. This can be achieved by setting headers['Content-Type']
# to None when calling this method.
if headers['Content-Type'] is None:
if (len(content_type_headers) == 1 and
headers[content_type_headers[0]] is None):
# Delete null Content-Type value to skip sending that header.
del headers['Content-Type']
del headers[content_type_headers[0]]
else:
self.content_type = headers['Content-Type']
self.content_type = merge_headers_by_name(
'Content-Type', headers)
elif self.path:
self.content_type = mimetypes.guess_type(self.path)[0]
if self.content_type == None:
Expand Down
21 changes: 21 additions & 0 deletions boto/utils.py
Expand Up @@ -944,3 +944,24 @@ def compute_hash(fp, buf_size=8192, size=None, hash_algorithm=md5):
data_size = fp.tell() - spos
fp.seek(spos)
return (hex_digest, base64_digest, data_size)


def find_matching_headers(name, headers):
"""
Takes a specific header name and a dict of headers {"name": "value"}.
Returns a list of matching header names, case-insensitive.
"""
return [h for h in headers if h.lower() == name.lower()]


def merge_headers_by_name(name, headers):
"""
Takes a specific header name and a dict of headers {"name": "value"}.
Returns a string of all header values, comma-separated, that match the
input header name, case-insensitive.
"""
matching_headers = find_matching_headers(name, headers)
return ','.join(str(headers[h]) for h in matching_headers
if headers[h] is not None)

0 comments on commit 60383d6

Please sign in to comment.