From ab39cf066784dc01869a7e22a9289e154410e4e5 Mon Sep 17 00:00:00 2001 From: Mike Fedosin Date: Mon, 17 Oct 2016 15:50:28 +0300 Subject: [PATCH] Prevent changing content type in request Now if body contains json, its content type forcibly changes to application/json, which is not correct in some case, like json-patch request. This code fixes this situation and sets application/json contnent type only if this header hasn't been set before. Change-Id: I4e0c44d444519f056dfa48c9603dbc3ca6b01822 Closes-bug: #1634110 --- keystoneauth1/session.py | 2 +- keystoneauth1/tests/unit/test_session.py | 19 +++++++++++++++++++ keystoneauth1/tests/unit/utils.py | 6 +++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/keystoneauth1/session.py b/keystoneauth1/session.py index 0039d609..087a34b1 100644 --- a/keystoneauth1/session.py +++ b/keystoneauth1/session.py @@ -543,7 +543,7 @@ class Session(object): 'for=%s;by=%s' % (self.original_ip, user_agent)) if json is not None: - headers['Content-Type'] = 'application/json' + headers.setdefault('Content-Type', 'application/json') kwargs['data'] = self._json.encode(json) for k, v in self.additional_headers.items(): diff --git a/keystoneauth1/tests/unit/test_session.py b/keystoneauth1/tests/unit/test_session.py index 1229f8c6..deba09c4 100644 --- a/keystoneauth1/tests/unit/test_session.py +++ b/keystoneauth1/tests/unit/test_session.py @@ -284,6 +284,25 @@ class SessionTests(utils.TestCase): session.get, self.TEST_URL) + def test_json_content_type(self): + session = client_session.Session() + self.stub_url('POST', text='response') + resp = session.post( + self.TEST_URL, + json=[{'op': 'replace', + 'path': '/name', + 'value': 'new_name'}], + headers={'Content-Type': 'application/json-patch+json'}) + + self.assertEqual('POST', self.requests_mock.last_request.method) + self.assertEqual(resp.text, 'response') + self.assertTrue(resp.ok) + self.assertRequestBodyIs( + json=[{'op': 'replace', + 'path': '/name', + 'value': 'new_name'}]) + self.assertContentTypeIs('application/json-patch+json') + class RedirectTests(utils.TestCase): diff --git a/keystoneauth1/tests/unit/utils.py b/keystoneauth1/tests/unit/utils.py index 41f8c85f..1aef9da3 100644 --- a/keystoneauth1/tests/unit/utils.py +++ b/keystoneauth1/tests/unit/utils.py @@ -53,7 +53,7 @@ class TestCase(testtools.TestCase): if json: kwargs['text'] = jsonutils.dumps(json) headers = kwargs.setdefault('headers', {}) - headers['Content-Type'] = 'application/json' + headers.setdefault('Content-Type', 'application/json') if parts: url = '/'.join([p.strip('/') for p in [base_url] + parts]) @@ -71,6 +71,10 @@ class TestCase(testtools.TestCase): elif body: self.assertEqual(body, last_request_body) + def assertContentTypeIs(self, content_type): + last_request = self.requests_mock.last_request + self.assertEqual(last_request.headers['Content-Type'], content_type) + def assertQueryStringIs(self, qs=''): r"""Verify the QueryString matches what is expected.