From 3035a93ed2c467fb248a77389274033ff540590c Mon Sep 17 00:00:00 2001 From: David Goetz Date: Tue, 30 Jul 2013 11:52:23 -0700 Subject: [PATCH] Tell swift to figure out content type Be able to tell swift to figure out the content-type even if it is sent because old client code / curl has trouble sending blank content-type headers. Change-Id: Ie65ddf8993a19ea74e0b85a2ae56da84a617c19d --- swift/proxy/controllers/obj.py | 10 ++++++-- test/unit/proxy/test_server.py | 47 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/swift/proxy/controllers/obj.py b/swift/proxy/controllers/obj.py index 9cc30caf2e..050ae986e2 100644 --- a/swift/proxy/controllers/obj.py +++ b/swift/proxy/controllers/obj.py @@ -874,11 +874,17 @@ class ObjectController(Controller): req.headers['X-Timestamp'] = normalize_timestamp(time.time()) # Sometimes the 'content-type' header exists, but is set to None. content_type_manually_set = True - if not req.headers.get('content-type'): + detect_content_type = \ + config_true_value(req.headers.get('x-detect-content-type')) + if detect_content_type or not req.headers.get('content-type'): guessed_type, _junk = mimetypes.guess_type(req.path_info) req.headers['Content-Type'] = guessed_type or \ 'application/octet-stream' - content_type_manually_set = False + if detect_content_type: + req.headers.pop('x-detect-content-type') + else: + content_type_manually_set = False + error_response = check_object_creation(req, self.object_name) or \ check_content_type(req) if error_response: diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index eaff66cc44..19ef32d42b 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -2035,6 +2035,53 @@ class TestObjectController(unittest.TestCase): res = controller.POST(req) self.assertEquals(res.status_int, 400) + def test_PUT_not_autodetect_content_type(self): + with save_globals(): + controller = proxy_server.ObjectController( + self.app, 'a', 'c', 'o.html') + + headers = {'Content-Type': 'something/right', 'Content-Length': 0} + it_worked = [] + + def verify_content_type(ipaddr, port, device, partition, + method, path, headers=None, + query_string=None): + if path == '/a/c/o.html': + it_worked.append( + headers['Content-Type'].startswith('something/right')) + + set_http_connect(204, 204, 201, 201, 201, + give_connect=verify_content_type) + req = Request.blank('/a/c/o.html', {}, headers=headers) + self.app.update_request(req) + res = controller.PUT(req) + self.assertNotEquals(it_worked, []) + self.assertTrue(all(it_worked)) + + def test_PUT_autodetect_content_type(self): + with save_globals(): + controller = proxy_server.ObjectController( + self.app, 'a', 'c', 'o.html') + + headers = {'Content-Type': 'something/wrong', 'Content-Length': 0, + 'X-Detect-Content-Type': 'True'} + it_worked = [] + + def verify_content_type(ipaddr, port, device, partition, + method, path, headers=None, + query_string=None): + if path == '/a/c/o.html': + it_worked.append( + headers['Content-Type'].startswith('text/html')) + + set_http_connect(204, 204, 201, 201, 201, + give_connect=verify_content_type) + req = Request.blank('/a/c/o.html', {}, headers=headers) + self.app.update_request(req) + res = controller.PUT(req) + self.assertNotEquals(it_worked, []) + self.assertTrue(all(it_worked)) + def test_client_timeout(self): with save_globals(): self.app.account_ring.get_nodes('account')