From 4b6ed760d4303744907feefd81e60f38ae3750ef Mon Sep 17 00:00:00 2001 From: Mark Rawlings Date: Tue, 3 Mar 2015 18:03:58 +0000 Subject: [PATCH] Reinstate Max URI length checking to V2_0 Client A previous commit 799e288f48e5d99731dedbfb94808a8cbe01c05c has broken the ability to recognise long URIs (>8192) and raise an exception used to prevent the excessive URI being sent to the server. This impacts the commands net-list and security-group-rule-list. The previous edit removed one of the duplicate _check_uri_length functions. This edit 'swaps' the removal and updates the unit test stubbing accordingly. The capability to split excessive URIs into managable chunks remained in the code, but no longer executed because this exception was not raised. It should be noted that as a side effect of recognising the long URI, data is returned with the exception that indicates 'how excessive' the URI length was. This allows the URI to be broken into chunks that will be supported. Restore the capability to recognise that an excessive URI has been provided and to raise the expected exception with related data. Closes-Bug: #1422736 Change-Id: I1b719bed406b83c5f2deac06e127798a91f51ad7 --- neutronclient/client.py | 10 ---------- neutronclient/tests/unit/test_cli20.py | 11 +++++++++++ neutronclient/tests/unit/test_cli20_network.py | 6 +++--- neutronclient/tests/unit/test_cli20_securitygroup.py | 6 +++--- neutronclient/v2_0/client.py | 11 +++++++++++ 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/neutronclient/client.py b/neutronclient/client.py index 0a68ff063..bc645f195 100644 --- a/neutronclient/client.py +++ b/neutronclient/client.py @@ -48,9 +48,6 @@ class HTTPClient(object): USER_AGENT = 'python-neutronclient' CONTENT_TYPE = 'application/json' - # 8192 Is the default max URI len for eventlet.wsgi.server - MAX_URI_LEN = 8192 - def __init__(self, username=None, user_id=None, tenant_name=None, tenant_id=None, password=None, auth_url=None, @@ -149,16 +146,9 @@ class HTTPClient(object): return resp, resp.text - def _check_uri_length(self, action): - uri_len = len(self.endpoint_url) + len(action) - if uri_len > self.MAX_URI_LEN: - raise exceptions.RequestURITooLong( - excess=uri_len - self.MAX_URI_LEN) - def do_request(self, url, method, **kwargs): # Ensure client always has correct uri - do not guesstimate anything self.authenticate_and_fetch_endpoint_url() - self._check_uri_length(url) # Perform the request once. If we get a 401 back then it # might be because the auth token expired, so try to diff --git a/neutronclient/tests/unit/test_cli20.py b/neutronclient/tests/unit/test_cli20.py index 86c79b417..3f360c705 100644 --- a/neutronclient/tests/unit/test_cli20.py +++ b/neutronclient/tests/unit/test_cli20.py @@ -618,6 +618,17 @@ class ClientV2TestJson(CLITestV20Base): self.mox.VerifyAll() self.mox.UnsetStubs() + def test_do_request_with_long_uri_exception(self): + long_string = 'x' * 8200 # 8200 > MAX_URI_LEN:8192 + params = {'id': long_string} + + try: + self.client.do_request('GET', '/test', body='', params=params) + except exceptions.RequestURITooLong as cm: + self.assertNotEqual(cm.excess, 0) + else: + self.fail('Expected exception NOT raised') + class ClientV2UnicodeTestXML(ClientV2TestJson): format = 'xml' diff --git a/neutronclient/tests/unit/test_cli20_network.py b/neutronclient/tests/unit/test_cli20_network.py index 1ac49b637..31754be26 100644 --- a/neutronclient/tests/unit/test_cli20_network.py +++ b/neutronclient/tests/unit/test_cli20_network.py @@ -551,14 +551,14 @@ class CLITestV20NetworkJSON(test_cli20.CLITestV20Base): filters, response = self._build_test_data(data) # 1 char of extra URI len will cause a split in 2 requests - self.mox.StubOutWithMock(self.client.httpclient, + self.mox.StubOutWithMock(self.client, "_check_uri_length") - self.client.httpclient._check_uri_length(mox.IgnoreArg()).AndRaise( + self.client._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) for data in sub_data_lists: filters, response = self._build_test_data(data) - self.client.httpclient._check_uri_length( + self.client._check_uri_length( mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.MyUrlComparator( diff --git a/neutronclient/tests/unit/test_cli20_securitygroup.py b/neutronclient/tests/unit/test_cli20_securitygroup.py index ec18fb8ee..8032e0390 100644 --- a/neutronclient/tests/unit/test_cli20_securitygroup.py +++ b/neutronclient/tests/unit/test_cli20_securitygroup.py @@ -265,14 +265,14 @@ class CLITestV20SecurityGroupsJSON(test_cli20.CLITestV20Base): def test_extend_list_exceed_max_uri_len(self): def mox_calls(path, data): # 1 char of extra URI len will cause a split in 2 requests - self.mox.StubOutWithMock(self.client.httpclient, + self.mox.StubOutWithMock(self.client, '_check_uri_length') - self.client.httpclient._check_uri_length(mox.IgnoreArg()).AndRaise( + self.client._check_uri_length(mox.IgnoreArg()).AndRaise( exceptions.RequestURITooLong(excess=1)) responses = self._build_test_data(data, excess=1) for item in responses: - self.client.httpclient._check_uri_length( + self.client._check_uri_length( mox.IgnoreArg()).AndReturn(None) self.client.httpclient.request( test_cli20.end_url(path, item['filter']), diff --git a/neutronclient/v2_0/client.py b/neutronclient/v2_0/client.py index 0feac68e9..2e63bb2a2 100644 --- a/neutronclient/v2_0/client.py +++ b/neutronclient/v2_0/client.py @@ -184,6 +184,12 @@ class ClientBase(object): # Raise the appropriate exception exception_handler_v20(status_code, des_error_body) + def _check_uri_length(self, action): + uri_len = len(self.httpclient.endpoint_url) + len(action) + if uri_len > self.MAX_URI_LEN: + raise exceptions.RequestURITooLong( + excess=uri_len - self.MAX_URI_LEN) + def do_request(self, method, action, body=None, headers=None, params=None): # Add format and tenant_id action += ".%s" % self.format @@ -192,6 +198,8 @@ class ClientBase(object): params = utils.safe_encode_dict(params) action += '?' + urlparse.urlencode(params, doseq=1) + self._check_uri_length(action) + if body: body = self.serialize(body) @@ -456,6 +464,9 @@ class Client(ClientBase): 'healthmonitors': 'healthmonitor', } + # 8192 Is the default max URI len for eventlet.wsgi.server + MAX_URI_LEN = 8192 + @APIParamsCall def list_ext(self, path, **_params): """Client extension hook for lists.