4956: Add maximum request size checking to http_request patch in api.py.
authorPeter Amstutz <peter.amstutz@curoverse.com>
Tue, 3 Mar 2015 21:24:21 +0000 (16:24 -0500)
committerPeter Amstutz <peter.amstutz@curoverse.com>
Tue, 3 Mar 2015 21:24:21 +0000 (16:24 -0500)
Raises MediaUploadSizeError if the request is too big.

sdk/python/arvados/api.py
sdk/python/tests/test_api.py

index a227e436a322948b92ec5f6adabad41e00e773ae..949ead36443eae97f34fdb6be8badfb7b3ba8248 100644 (file)
@@ -21,6 +21,12 @@ class CredentialsFromToken(object):
     @staticmethod
     def http_request(self, uri, **kwargs):
         from httplib import BadStatusLine
+
+        if (self.max_request_size and
+            kwargs.get('body') and
+            self.max_request_size < len(kwargs['body'])):
+            raise apiclient_errors.MediaUploadSizeError("Request size %i bytes exceeds published limit of %i bytes" % (len(kwargs['body']), self.max_request_size))
+
         if 'headers' not in kwargs:
             kwargs['headers'] = {}
 
@@ -38,10 +44,12 @@ class CredentialsFromToken(object):
             # previous call did not succeed, so this is slightly
             # risky.
             return self.orig_http_request(uri, **kwargs)
+
     def authorize(self, http):
         http.arvados_api_token = self.api_token
         http.orig_http_request = http.request
         http.request = types.MethodType(self.http_request, http)
+        http.max_request_size = 0
         return http
 
 # Monkey patch discovery._cast() so objects and arrays get serialized
@@ -147,6 +155,7 @@ def api(version=None, cache=True, host=None, token=None, insecure=False, **kwarg
 
     svc = apiclient_discovery.build('arvados', version, **kwargs)
     svc.api_token = token
+    kwargs['http'].max_request_size = svc._rootDesc.get('maxRequestSize', 0)
     kwargs['http'].cache = None
     return svc
 
index 5cf2d2b58c8c4086a075b78eee0d34024ab81db1..1080b3c859d3337fe5bd03ff98d2bb8f992c3a94 100644 (file)
@@ -100,6 +100,11 @@ class ArvadosApiClientTest(unittest.TestCase):
             self.api.humans().delete(uuid='xyz-xyz-abcdef').execute()
         self.assertIn("500", str(err_ctx.exception))
 
+    def test_request_too_large(self):
+        with self.assertRaises(apiclient_errors.MediaUploadSizeError):
+            text = "X" * (128 * 1024 * 1024)
+            arvados.api('v1').collections().create(body={"manifest_text": text}).execute()
+
 
 if __name__ == '__main__':
     unittest.main()