Пример #1
0
    def test_admin_setup(self):
        # PUTs for account and 16 .hash's
        self.test_origin.app = FakeApp(iter([("204 No Content", {}, "") for i in xrange(201)]))
        resp = Request.blank(
            "/origin/.prep",
            environ={"REQUEST_METHOD": "PUT"},
            headers={"X-Origin-Admin-User": "******", "X-Origin-Admin-Key": "unittest"},
        ).get_response(self.test_origin)
        self.assertEquals(resp.status_int, 204)
        self.assertEquals(self.test_origin.app.calls, 101)

        self.test_origin.app = FakeApp(iter([("404 Not Found", {}, "")]))
        req = Request.blank(
            "/origin/.prep",
            environ={"REQUEST_METHOD": "PUT"},
            headers={"X-Origin-Admin-User": "******", "X-Origin-Admin-Key": "unittest"},
        )
        self.assertRaises(Exception, req.get_response, self.test_origin)

        self.test_origin.app = FakeApp(iter([("204 No Content", {}, ""), ("404 Not Found", {}, "")]))
        req = Request.blank(
            "/origin/.prep",
            environ={"REQUEST_METHOD": "PUT"},
            headers={"X-Origin-Admin-User": "******", "X-Origin-Admin-Key": "unittest"},
        )
        self.assertRaises(Exception, req.get_response, self.test_origin)
Пример #2
0
    def test_bucket_acl_PUT(self):
        elem = Element('AccessControlPolicy')
        owner = SubElement(elem, 'Owner')
        SubElement(owner, 'ID').text = 'id'
        acl = SubElement(elem, 'AccessControlList')
        grant = SubElement(acl, 'Grant')
        grantee = SubElement(grant, 'Grantee', nsmap={'xsi': XMLNS_XSI})
        grantee.set('{%s}type' % XMLNS_XSI, 'Group')
        SubElement(grantee, 'URI').text = \
            'http://acs.amazonaws.com/groups/global/AllUsers'
        SubElement(grant, 'Permission').text = 'READ'

        xml = tostring(elem)
        req = Request.blank('/bucket?acl',
                            environ={'REQUEST_METHOD': 'PUT'},
                            headers={'Authorization': 'AWS test:tester:hmac'},
                            body=xml)
        status, headers, body = self.call_swift3(req)
        self.assertEquals(status.split()[0], '200')

        req = Request.blank('/bucket?acl',
                            environ={'REQUEST_METHOD': 'PUT',
                                     'wsgi.input': StringIO(xml)},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Transfer-Encoding': 'chunked'})
        self.assertIsNone(req.content_length)
        self.assertIsNone(req.message_length())
        status, headers, body = self.call_swift3(req)
        self.assertEquals(status.split()[0], '200')
Пример #3
0
    def test_proxy_client_logging(self):
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank('/', environ={
            'REQUEST_METHOD': 'GET',
            'REMOTE_ADDR': '1.2.3.4',
            'HTTP_X_FORWARDED_FOR': '4.5.6.7,8.9.10.11'})
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[0], '4.5.6.7')  # client ip
        self.assertEquals(log_parts[1], '1.2.3.4')  # remote addr

        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank('/', environ={
            'REQUEST_METHOD': 'GET',
            'REMOTE_ADDR': '1.2.3.4',
            'HTTP_X_CLUSTER_CLIENT_IP': '4.5.6.7'})
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[0], '4.5.6.7')  # client ip
        self.assertEquals(log_parts[1], '1.2.3.4')  # remote addr
Пример #4
0
    def test_origin_db_post_fail(self):
        self.test_origin.app = FakeApp(
            iter([("204 No Content", {}, ""), ("404 Not Found", {}, "")])  # call to _get_cdn_data  # put to .hash
        )
        req = Request.blank("http://origin_db.com:8080/v1/acc/cont", environ={"REQUEST_METHOD": "PUT"})
        resp = req.get_response(self.test_origin)
        self.assertEquals(resp.status_int, 500)

        self.test_origin.app = FakeApp(
            iter(
                [
                    ("204 No Content", {}, ""),  # call to _get_cdn_data
                    ("204 No Content", {}, ""),  # put to .hash
                    ("404 Not Found", {}, ""),  # HEAD check to list container
                    ("404 Not Found", {}, ""),  # PUT to list container
                ]
            )
        )
        req = Request.blank("http://origin_db.com:8080/v1/acc/cont", environ={"REQUEST_METHOD": "PUT"})
        resp = req.get_response(self.test_origin)
        self.assertEquals(resp.status_int, 500)

        self.test_origin.app = FakeApp(
            iter(
                [
                    ("204 No Content", {}, ""),  # call to _get_cdn_data
                    ("204 No Content", {}, ""),  # put to .hash
                    ("204 No Content", {}, ""),  # HEAD check to list container
                    ("404 Not Found", {}, ""),  # PUT to list container
                ]
            )
        )
        req = Request.blank("http://origin_db.com:8080/v1/acc/cont", environ={"REQUEST_METHOD": "PUT"})
        resp = req.get_response(self.test_origin)
        self.assertEquals(resp.status_int, 500)
Пример #5
0
    def test_extract_tar_works(self):
        # On systems where $TMPDIR is long (like OS X), we need to do this
        # or else every upload will fail due to the path being too long.
        self.app.max_pathlen += len(self.testdir)
        for compress_format in ['', 'gz', 'bz2']:
            base_name = 'base_works_%s' % compress_format
            dir_tree = [
                {base_name: [{'sub_dir1': ['sub1_file1', 'sub1_file2']},
                             {'sub_dir2': ['sub2_file1', u'test obj \u2661']},
                             'sub_file1',
                             {'sub_dir3': [{'sub4_dir1': '../sub4 file1'}]},
                             {'sub_dir4': None},
                             ]}]

            build_dir_tree(self.testdir, dir_tree)
            mode = 'w'
            extension = ''
            if compress_format:
                mode += ':' + compress_format
                extension += '.' + compress_format
            tar = tarfile.open(name=os.path.join(self.testdir,
                                                 'tar_works.tar' + extension),
                               mode=mode)
            tar.add(os.path.join(self.testdir, base_name))
            tar.close()
            req = Request.blank('/tar_works/acc/cont/')
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'
            resp_body = self.handle_extract_and_iter(req, compress_format)
            resp_data = utils.json.loads(resp_body)
            self.assertEquals(resp_data['Number Files Created'], 6)

            # test out xml
            req = Request.blank('/tar_works/acc/cont/')
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'
            resp_body = self.handle_extract_and_iter(
                req, compress_format, 'application/xml')
            self.assert_('<response_status>201 Created</response_status>' in
                         resp_body)
            self.assert_('<number_files_created>6</number_files_created>' in
                         resp_body)

            # test out nonexistent format
            req = Request.blank('/tar_works/acc/cont/?extract-archive=tar',
                                headers={'Accept': 'good_xml'})
            req.environ['REQUEST_METHOD'] = 'PUT'
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'

            def fake_start_response(*args, **kwargs):
                pass

            app_iter = self.bulk(req.environ, fake_start_response)
            resp_body = ''.join([i for i in app_iter])

            self.assert_('Response Status: 406' in resp_body)
Пример #6
0
    def test_get_account_info_cache(self):
        # Works with fake apps that return ints in the headers
        cached = {'status': 404,
                  'bytes': 3333,
                  'total_object_count': 10}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        resp = get_account_info(req.environ, FakeApp())
        self.assertEqual(resp['bytes'], 3333)
        self.assertEqual(resp['total_object_count'], 10)
        self.assertEqual(resp['status'], 404)

        # Works with strings too, like you get when parsing HTTP headers
        # that came in through a socket from the account server
        cached = {'status': 404,
                  'bytes': '3333',
                  'container_count': '234',
                  'total_object_count': '10',
                  'meta': {}}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        resp = get_account_info(req.environ, FakeApp())
        self.assertEqual(resp['status'], 404)
        self.assertEqual(resp['bytes'], 3333)
        self.assertEqual(resp['container_count'], 234)
        self.assertEqual(resp['meta'], {})
        self.assertEqual(resp['total_object_count'], 10)
Пример #7
0
    def test_policy_index(self):
        # Policy index can be specified by X-Backend-Storage-Policy-Index
        # in the request header for object API
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(policy_idx='1'), {})
        app.access_logger = FakeLogger()
        req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'PUT'})
        resp = app(req.environ, start_response)
        ''.join(resp)
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[20], '1')

        # Policy index can be specified by X-Backend-Storage-Policy-Index
        # in the response header for container API
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank('/v1/a/c', environ={'REQUEST_METHOD': 'GET'})

        def fake_call(app, env, start_response):
            start_response(app.response_str,
                           [('Content-Type', 'text/plain'),
                            ('Content-Length', str(sum(map(len, app.body)))),
                            ('X-Backend-Storage-Policy-Index', '1')])
            while env['wsgi.input'].read(5):
                pass
            return app.body

        with mock.patch.object(FakeApp, '__call__', fake_call):
            resp = app(req.environ, start_response)
            ''.join(resp)
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[20], '1')
Пример #8
0
    def test_check_signature_multi_bytes_secret_failure(self):
        # Test v2 check_signature with multi bytes invalid secret
        req = Request.blank('/photos/puppy.jpg', headers={
            'Host': 'johnsmith.s3.amazonaws.com',
            'Date': 'Tue, 27 Mar 2007 19:36:42 +0000',
            'Authorization': ('AWS AKIAIOSFODNN7EXAMPLE:'
                              'bWq2s1WEIj+Ydj0vQ697zp+IXMU='),
        })
        sigv2_req = S3Request(req.environ, storage_domain='s3.amazonaws.com')
        # This is a failure case with utf-8 non-ascii multi-bytes charactor
        # but we expect to return just False instead of exceptions
        self.assertFalse(sigv2_req.check_signature(
            u'\u30c9\u30e9\u30b4\u30f3'))

        # Test v4 check_signature with multi bytes invalid secret
        amz_date_header = self.get_v4_amz_date_header()
        req = Request.blank('/photos/puppy.jpg', headers={
            'Authorization':
                'AWS4-HMAC-SHA256 '
                'Credential=test/%s/us-east-1/s3/aws4_request, '
                'SignedHeaders=host;x-amz-content-sha256;x-amz-date,'
                'Signature=X' % amz_date_header.split('T', 1)[0],
            'X-Amz-Content-SHA256': '0123456789',
            'X-Amz-Date': amz_date_header
        })
        sigv4_req = SigV4Request(
            req.environ, storage_domain='s3.amazonaws.com')
        self.assertFalse(sigv4_req.check_signature(
            u'\u30c9\u30e9\u30b4\u30f3'))
Пример #9
0
    def test_proxy_client_logging(self):
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank(
            "/",
            environ={"REQUEST_METHOD": "GET", "REMOTE_ADDR": "1.2.3.4", "HTTP_X_FORWARDED_FOR": "4.5.6.7,8.9.10.11"},
        )
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[0], "4.5.6.7")  # client ip
        self.assertEquals(log_parts[1], "1.2.3.4")  # remote addr

        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank(
            "/", environ={"REQUEST_METHOD": "GET", "REMOTE_ADDR": "1.2.3.4", "HTTP_X_CLUSTER_CLIENT_IP": "4.5.6.7"}
        )
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEquals(log_parts[0], "4.5.6.7")  # client ip
        self.assertEquals(log_parts[1], "1.2.3.4")  # remote addr
Пример #10
0
    def test_PUT_encryption_override(self):
        # set crypto override to disable encryption.
        # simulate another middleware wanting to set footers
        other_footers = {
            'Etag': 'other etag',
            'X-Object-Sysmeta-Other': 'other sysmeta',
            'X-Object-Sysmeta-Container-Update-Override-Etag':
                'other override'}
        body = 'FAKE APP'
        env = {'REQUEST_METHOD': 'PUT',
               'swift.crypto.override': True,
               'swift.callback.update_footers':
                   lambda footers: footers.update(other_footers)}
        hdrs = {'content-type': 'text/plain',
                'content-length': str(len(body))}
        req = Request.blank('/v1/a/c/o', environ=env, body=body, headers=hdrs)
        self.app.register('PUT', '/v1/a/c/o', HTTPCreated, {})
        resp = req.get_response(self.encrypter)
        self.assertEqual('201 Created', resp.status)

        # verify that other middleware's footers made it to app
        req_hdrs = self.app.headers[0]
        for k, v in other_footers.items():
            self.assertEqual(v, req_hdrs[k])

        # verify object is NOT encrypted by getting direct from the app
        get_req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
        self.assertEqual(body, get_req.get_response(self.app).body)
Пример #11
0
    def test_to_swift_req_subrequest_proxy_access_log(self):
        container = 'bucket'
        obj = 'obj'
        method = 'GET'

        # force_swift_request_proxy_log is True
        req = Request.blank('/%s/%s' % (container, obj),
                            environ={'REQUEST_METHOD': method,
                                     'swift.proxy_access_log_made': True},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        with patch.object(Request, 'get_response') as m_swift_resp, \
                patch.object(Request, 'remote_user', 'authorized'):
            m_swift_resp.return_value = FakeSwiftResponse()
            s3_req = S3AclRequest(
                req.environ, MagicMock(), force_request_log=True)
            sw_req = s3_req.to_swift_req(method, container, obj)
            self.assertFalse(sw_req.environ['swift.proxy_access_log_made'])

        # force_swift_request_proxy_log is False
        req = Request.blank('/%s/%s' % (container, obj),
                            environ={'REQUEST_METHOD': method,
                                     'swift.proxy_access_log_made': True},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        with patch.object(Request, 'get_response') as m_swift_resp, \
                patch.object(Request, 'remote_user', 'authorized'):
            m_swift_resp.return_value = FakeSwiftResponse()
            s3_req = S3AclRequest(
                req.environ, MagicMock(), force_request_log=False)
            sw_req = s3_req.to_swift_req(method, container, obj)
            self.assertTrue(sw_req.environ['swift.proxy_access_log_made'])
Пример #12
0
    def test_handle_multipart_put_bad_data(self):
        bad_data = json.dumps([{"path": "/cont/object", "etag": "etagoftheobj", "size_bytes": "lala"}])
        req = Request.blank(
            "/test_good/AUTH_test/c/man?multipart-manifest=put", environ={"REQUEST_METHOD": "PUT"}, body=bad_data
        )
        self.assertRaises(HTTPException, self.slo.handle_multipart_put, req)

        for bad_data in [
            json.dumps([{"path": "/cont", "etag": "etagoftheobj", "size_bytes": 100}]),
            json.dumps("asdf"),
            json.dumps(None),
            json.dumps(5),
            "not json",
            "1234",
            None,
            "",
            json.dumps({"path": None}),
            json.dumps([{"path": "/c/o", "etag": None, "size_bytes": 12}]),
            json.dumps([{"path": "/c/o", "etag": "asdf", "size_bytes": "sd"}]),
            json.dumps([{"path": 12, "etag": "etagoftheobj", "size_bytes": 100}]),
            json.dumps([{"path": u"/cont/object\u2661", "etag": "etagoftheobj", "size_bytes": 100}]),
            json.dumps([{"path": 12, "size_bytes": 100}]),
            json.dumps([{"path": 12, "size_bytes": 100}]),
            json.dumps([{"path": None, "etag": "etagoftheobj", "size_bytes": 100}]),
        ]:
            req = Request.blank(
                "/test_good/AUTH_test/c/man?multipart-manifest=put", environ={"REQUEST_METHOD": "PUT"}, body=bad_data
            )
            self.assertRaises(HTTPException, self.slo.handle_multipart_put, req)
Пример #13
0
    def test_check_object_creation_copy(self):
        headers = {'Content-Length': '0',
                   'X-Copy-From': 'c/o2',
                   'Content-Type': 'text/plain'}
        self.assertEquals(constraints.check_object_creation(Request.blank(
            '/', headers=headers), 'object_name'), None)

        headers = {'Content-Length': '1',
                   'X-Copy-From': 'c/o2',
                   'Content-Type': 'text/plain'}
        self.assertEquals(constraints.check_object_creation(Request.blank(
            '/', headers=headers), 'object_name').status_int,
            HTTP_BAD_REQUEST)

        headers = {'Transfer-Encoding': 'chunked',
                   'X-Copy-From': 'c/o2',
                   'Content-Type': 'text/plain'}
        self.assertEquals(constraints.check_object_creation(Request.blank(
            '/', headers=headers), 'object_name'), None)

        # a content-length header is always required
        headers = {'X-Copy-From': 'c/o2',
                   'Content-Type': 'text/plain'}
        self.assertEquals(constraints.check_object_creation(Request.blank(
            '/', headers=headers), 'object_name').status_int,
            HTTP_LENGTH_REQUIRED)
Пример #14
0
    def test_get_account_info_cache(self):
        # The original test that we prefer to preserve
        cached = {'status': 404,
                  'bytes': 3333,
                  'total_object_count': 10}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        with patch('swift.proxy.controllers.base.'
                   '_prepare_pre_auth_info_request', FakeRequest):
            resp = get_account_info(req.environ, 'xxx')
        self.assertEquals(resp['bytes'], 3333)
        self.assertEquals(resp['total_object_count'], 10)
        self.assertEquals(resp['status'], 404)

        # Here is a more realistic test
        cached = {'status': 404,
                  'bytes': '3333',
                  'container_count': '234',
                  'total_object_count': '10',
                  'meta': {}}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        with patch('swift.proxy.controllers.base.'
                   '_prepare_pre_auth_info_request', FakeRequest):
            resp = get_account_info(req.environ, 'xxx')
        self.assertEquals(resp['status'], 404)
        self.assertEquals(resp['bytes'], '3333')
        self.assertEquals(resp['container_count'], 234)
        self.assertEquals(resp['meta'], {})
        self.assertEquals(resp['total_object_count'], '10')
Пример #15
0
    def test_GETorHEAD_base(self):
        base = Controller(self.app)
        req = Request.blank('/v1/a/c/o/with/slashes')
        with patch('swift.proxy.controllers.base.'
                   'http_connect', fake_http_connect(200)):
            resp = base.GETorHEAD_base(req, 'object', FakeRing(), 'part',
                                       '/a/c/o/with/slashes')
        self.assertTrue('swift.object/a/c/o/with/slashes' in resp.environ)
        self.assertEqual(
            resp.environ['swift.object/a/c/o/with/slashes']['status'], 200)
        req = Request.blank('/v1/a/c/o')
        with patch('swift.proxy.controllers.base.'
                   'http_connect', fake_http_connect(200)):
            resp = base.GETorHEAD_base(req, 'object', FakeRing(), 'part',
                                       '/a/c/o')
        self.assertTrue('swift.object/a/c/o' in resp.environ)
        self.assertEqual(resp.environ['swift.object/a/c/o']['status'], 200)
        req = Request.blank('/v1/a/c')
        with patch('swift.proxy.controllers.base.'
                   'http_connect', fake_http_connect(200)):
            resp = base.GETorHEAD_base(req, 'container', FakeRing(), 'part',
                                       '/a/c')
        self.assertTrue('swift.container/a/c' in resp.environ)
        self.assertEqual(resp.environ['swift.container/a/c']['status'], 200)

        req = Request.blank('/v1/a')
        with patch('swift.proxy.controllers.base.'
                   'http_connect', fake_http_connect(200)):
            resp = base.GETorHEAD_base(req, 'account', FakeRing(), 'part',
                                       '/a')
        self.assertTrue('swift.account/a' in resp.environ)
        self.assertEqual(resp.environ['swift.account/a']['status'], 200)
Пример #16
0
 def test_parse_account_that_looks_like_version(self):
     """
     Demonstrate the failure mode for accounts that looks like versions,
     if you can make _parse_path better and this is the *only* test that
     fails you can delete it ;)
     """
     bad_accounts = (
         'v3.0', 'verybaddaccountwithnoprefix',
     )
     for bad_account in bad_accounts:
         req = Request.blank('/endpoints/%s/c/o' % bad_account)
         self.assertRaises(ValueError,
                           self.list_endpoints._parse_path, req)
     even_worse_accounts = {
         'v1': 1.0,
         'v2.0': 2.0,
     }
     for bad_account, guessed_version in even_worse_accounts.items():
         req = Request.blank('/endpoints/%s/c/o' % bad_account)
         version, account, container, obj = \
             self.list_endpoints._parse_path(req)
         self.assertEqual(version, guessed_version)
         self.assertEqual(account, 'c')
         self.assertEqual(container, 'o')
         self.assertEqual(obj, None)
Пример #17
0
    def test_get_account_info_cache(self):
        # The original test that we prefer to preserve
        cached = {'status': 404,
                  'bytes': 3333,
                  'total_object_count': 10}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        resp = get_account_info(req.environ, FakeApp())
        self.assertEqual(resp['bytes'], 3333)
        self.assertEqual(resp['total_object_count'], 10)
        self.assertEqual(resp['status'], 404)

        # Here is a more realistic test
        cached = {'status': 404,
                  'bytes': '3333',
                  'container_count': '234',
                  'total_object_count': '10',
                  'meta': {}}
        req = Request.blank("/v1/account/cont",
                            environ={'swift.cache': FakeCache(cached)})
        resp = get_account_info(req.environ, FakeApp())
        self.assertEqual(resp['status'], 404)
        self.assertEqual(resp['bytes'], '3333')
        self.assertEqual(resp['container_count'], 234)
        self.assertEqual(resp['meta'], {})
        self.assertEqual(resp['total_object_count'], '10')
Пример #18
0
    def test_policy_index(self):
        # Policy index can be specified by X-Backend-Storage-Policy-Index
        # in the request header for object API
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(policy_idx="1"), {})
        app.access_logger = FakeLogger()
        req = Request.blank("/v1/a/c/o", environ={"REQUEST_METHOD": "PUT"})
        resp = app(req.environ, start_response)
        "".join(resp)
        log_parts = self._log_parts(app)
        self.assertEqual(log_parts[20], "1")

        # Policy index can be specified by X-Backend-Storage-Policy-Index
        # in the response header for container API
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {})
        app.access_logger = FakeLogger()
        req = Request.blank("/v1/a/c", environ={"REQUEST_METHOD": "GET"})

        def fake_call(app, env, start_response):
            start_response(
                app.response_str,
                [
                    ("Content-Type", "text/plain"),
                    ("Content-Length", str(sum(map(len, app.body)))),
                    ("X-Backend-Storage-Policy-Index", "1"),
                ],
            )
            while env["wsgi.input"].read(5):
                pass
            return app.body

        with mock.patch.object(FakeApp, "__call__", fake_call):
            resp = app(req.environ, start_response)
            "".join(resp)
        log_parts = self._log_parts(app)
        self.assertEqual(log_parts[20], "1")
Пример #19
0
    def test_bucket_GET_max_keys(self):
        class FakeApp(object):
            def __call__(self, env, start_response):
                self.query_string = env['QUERY_STRING']
                start_response('200 OK', [])
                return '[]'
        fake_app = FakeApp()
        local_app = swift3.filter_factory({})(fake_app)
        bucket_name = 'junk'

        req = Request.blank('/%s' % bucket_name,
                environ={'REQUEST_METHOD': 'GET',
                         'QUERY_STRING': 'max-keys=5'},
                headers={'Authorization': 'AWS test:tester:hmac'})
        resp = local_app(req.environ, lambda *args: None)
        dom = xml.dom.minidom.parseString("".join(resp))
        self.assertEquals(dom.getElementsByTagName('MaxKeys')[0].
                childNodes[0].nodeValue, '5')
        args = dict(cgi.parse_qsl(fake_app.query_string))
        self.assert_(args['limit'] == '6')

        req = Request.blank('/%s' % bucket_name,
                environ={'REQUEST_METHOD': 'GET',
                         'QUERY_STRING': 'max-keys=5000'},
                headers={'Authorization': 'AWS test:tester:hmac'})
        resp = local_app(req.environ, lambda *args: None)
        dom = xml.dom.minidom.parseString("".join(resp))
        self.assertEquals(dom.getElementsByTagName('MaxKeys')[0].
                childNodes[0].nodeValue, '1000')
        args = dict(cgi.parse_qsl(fake_app.query_string))
        self.assertEquals(args['limit'], '1001')
Пример #20
0
 def create_container(self, req, container_path):
     """
     Checks if the container exists and if not try to create it.
     :params container_path: an unquoted path to a container to be created
     :returns: True if created container, False if container exists
     :raises: CreateContainerError when unable to create container
     """
     new_env = req.environ.copy()
     new_env['PATH_INFO'] = container_path
     new_env['swift.source'] = 'EA'
     new_env['REQUEST_METHOD'] = 'HEAD'
     head_cont_req = Request.blank(container_path, environ=new_env)
     resp = head_cont_req.get_response(self.app)
     if resp.is_success:
         return False
     if resp.status_int == 404:
         new_env = req.environ.copy()
         new_env['PATH_INFO'] = container_path
         new_env['swift.source'] = 'EA'
         new_env['REQUEST_METHOD'] = 'PUT'
         create_cont_req = Request.blank(container_path, environ=new_env)
         resp = create_cont_req.get_response(self.app)
         if resp.is_success:
             return True
     raise CreateContainerError(
         "Create Container Failed: " + container_path,
         resp.status_int, resp.status)
Пример #21
0
    def test_upload_size(self):
        # Using default policy
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(), {"log_headers": "yes"})
        app.access_logger = FakeLogger()
        req = Request.blank("/v1/a/c/o/foo", environ={"REQUEST_METHOD": "PUT", "wsgi.input": BytesIO(b"some stuff")})
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEqual(log_parts[11], str(len("FAKE APP")))
        self.assertEqual(log_parts[10], str(len("some stuff")))
        self.assertUpdateStats(
            [
                ("object.PUT.200.xfer", len("some stuff") + len("FAKE APP")),
                ("object.policy.0.PUT.200.xfer", len("some stuff") + len("FAKE APP")),
            ],
            app,
        )

        # Using a non-existent policy
        app = proxy_logging.ProxyLoggingMiddleware(FakeApp(policy_idx="-1"), {"log_headers": "yes"})
        app.access_logger = FakeLogger()
        req = Request.blank("/v1/a/c/o/foo", environ={"REQUEST_METHOD": "PUT", "wsgi.input": BytesIO(b"some stuff")})
        resp = app(req.environ, start_response)
        # exhaust generator
        [x for x in resp]
        log_parts = self._log_parts(app)
        self.assertEqual(log_parts[11], str(len("FAKE APP")))
        self.assertEqual(log_parts[10], str(len("some stuff")))
        self.assertUpdateStats([("object.PUT.200.xfer", len("some stuff") + len("FAKE APP"))], app)
Пример #22
0
    def test_PUT_encryption_override(self):
        # set crypto override to disable encryption.
        # simulate another middleware wanting to set footers
        other_footers = {
            "Etag": "other etag",
            "X-Object-Sysmeta-Other": "other sysmeta",
            "X-Object-Sysmeta-Container-Update-Override-Etag": "other override",
        }
        body = "FAKE APP"
        env = {
            "REQUEST_METHOD": "PUT",
            "swift.crypto.override": True,
            "swift.callback.update_footers": lambda footers: footers.update(other_footers),
        }
        hdrs = {"content-type": "text/plain", "content-length": str(len(body))}
        req = Request.blank("/v1/a/c/o", environ=env, body=body, headers=hdrs)
        self.app.register("PUT", "/v1/a/c/o", HTTPCreated, {})
        resp = req.get_response(self.encrypter)
        self.assertEqual("201 Created", resp.status)

        # verify that other middleware's footers made it to app
        req_hdrs = self.app.headers[0]
        for k, v in other_footers.items():
            self.assertEqual(v, req_hdrs[k])

        # verify object is NOT encrypted by getting direct from the app
        get_req = Request.blank("/v1/a/c/o", environ={"REQUEST_METHOD": "GET"})
        self.assertEqual(body, get_req.get_response(self.app).body)
Пример #23
0
    def test_bucket_PUT(self):
        req = Request.blank('/bucket',
                            environ={'REQUEST_METHOD': 'PUT'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(body, '')
        self.assertEqual(status.split()[0], '200')
        self.assertEqual(headers['Location'], '/bucket')

        # Apparently some clients will include a chunked transfer-encoding
        # even with no body
        req = Request.blank('/bucket',
                            environ={'REQUEST_METHOD': 'PUT'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header(),
                                     'Transfer-Encoding': 'chunked'})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(body, '')
        self.assertEqual(status.split()[0], '200')
        self.assertEqual(headers['Location'], '/bucket')

        with UnreadableInput(self) as fake_input:
            req = Request.blank(
                '/bucket',
                environ={'REQUEST_METHOD': 'PUT',
                         'wsgi.input': fake_input},
                headers={'Authorization': 'AWS test:tester:hmac',
                         'Date': self.get_date_header()})
            status, headers, body = self.call_s3api(req)
        self.assertEqual(body, '')
        self.assertEqual(status.split()[0], '200')
        self.assertEqual(headers['Location'], '/bucket')
Пример #24
0
    def test_bucket_GET_v2_with_delimiter_max_keys(self):
        bucket_name = 'junk'
        req = Request.blank(
            '/%s?list-type=2&delimiter=a&max-keys=2' % bucket_name,
            environ={'REQUEST_METHOD': 'GET'},
            headers={'Authorization': 'AWS test:tester:hmac',
                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(status.split()[0], '200')
        elem = fromstring(body, 'ListBucketResult')
        next_token = elem.find('./NextContinuationToken')
        self.assertIsNotNone(next_token)
        self.assertEqual(elem.find('./MaxKeys').text, '2')
        self.assertEqual(elem.find('./IsTruncated').text, 'true')

        req = Request.blank(
            '/%s?list-type=2&delimiter=a&max-keys=2&continuation-token=%s' %
            (bucket_name, next_token.text),
            environ={'REQUEST_METHOD': 'GET'},
            headers={'Authorization': 'AWS test:tester:hmac',
                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(status.split()[0], '200')
        elem = fromstring(body, 'ListBucketResult')
        names = [o.find('./Key').text for o in elem.iterchildren('Contents')]
        self.assertEqual(names[0], 'lily')
Пример #25
0
    def test_bucket_GET_v2_fetch_owner(self):
        bucket_name = 'junk'
        req = Request.blank('/%s?list-type=2' % bucket_name,
                            environ={'REQUEST_METHOD': 'GET'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(status.split()[0], '200')

        elem = fromstring(body, 'ListBucketResult')
        name = elem.find('./Name').text
        self.assertEqual(name, bucket_name)

        objects = elem.iterchildren('Contents')
        for o in objects:
            self.assertIsNone(o.find('./Owner'))

        req = Request.blank('/%s?list-type=2&fetch-owner=true' % bucket_name,
                            environ={'REQUEST_METHOD': 'GET'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        self.assertEqual(status.split()[0], '200')

        elem = fromstring(body, 'ListBucketResult')
        name = elem.find('./Name').text
        self.assertEqual(name, bucket_name)

        objects = elem.iterchildren('Contents')
        for o in objects:
            self.assertIsNotNone(o.find('./Owner'))
Пример #26
0
    def test_bucket_GET_v2_is_truncated(self):
        bucket_name = 'junk'

        req = Request.blank(
            '/%s?list-type=2&max-keys=%d' % (bucket_name, len(self.objects)),
            environ={'REQUEST_METHOD': 'GET'},
            headers={'Authorization': 'AWS test:tester:hmac',
                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        elem = fromstring(body, 'ListBucketResult')
        self.assertEqual(elem.find('./KeyCount').text, str(len(self.objects)))
        self.assertEqual(elem.find('./IsTruncated').text, 'false')

        req = Request.blank(
            '/%s?list-type=2&max-keys=%d' % (bucket_name,
                                             len(self.objects) - 1),
            environ={'REQUEST_METHOD': 'GET'},
            headers={'Authorization': 'AWS test:tester:hmac',
                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        elem = fromstring(body, 'ListBucketResult')
        self.assertIsNotNone(elem.find('./NextContinuationToken'))
        self.assertEqual(elem.find('./KeyCount').text,
                         str(len(self.objects) - 1))
        self.assertEqual(elem.find('./IsTruncated').text, 'true')

        req = Request.blank('/subdirs?list-type=2&delimiter=/&max-keys=2',
                            environ={'REQUEST_METHOD': 'GET'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        elem = fromstring(body, 'ListBucketResult')
        self.assertIsNotNone(elem.find('./NextContinuationToken'))
        self.assertEqual(elem.find('./KeyCount').text, '2')
        self.assertEqual(elem.find('./IsTruncated').text, 'true')
Пример #27
0
    def test_bucket_GET_max_keys(self):
        bucket_name = 'junk'

        req = Request.blank('/%s?max-keys=5' % bucket_name,
                            environ={'REQUEST_METHOD': 'GET'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        elem = fromstring(body, 'ListBucketResult')
        self.assertEqual(elem.find('./MaxKeys').text, '5')
        _, path = self.swift.calls[-1]
        _, query_string = path.split('?')
        args = dict(cgi.parse_qsl(query_string))
        self.assertEqual(args['limit'], '6')

        req = Request.blank('/%s?max-keys=5000' % bucket_name,
                            environ={'REQUEST_METHOD': 'GET'},
                            headers={'Authorization': 'AWS test:tester:hmac',
                                     'Date': self.get_date_header()})
        status, headers, body = self.call_s3api(req)
        elem = fromstring(body, 'ListBucketResult')
        self.assertEqual(elem.find('./MaxKeys').text, '5000')
        _, path = self.swift.calls[-1]
        _, query_string = path.split('?')
        args = dict(cgi.parse_qsl(query_string))
        self.assertEqual(args['limit'], '1001')
Пример #28
0
    def test_sysmeta_replaced_by_PUT(self):
        path = '/v1/a/c/o'

        env = {'REQUEST_METHOD': 'PUT'}
        hdrs = dict(self.original_sysmeta_headers_1)
        hdrs.update(self.original_sysmeta_headers_2)
        hdrs.update(self.original_meta_headers_1)
        hdrs.update(self.original_meta_headers_2)
        req = Request.blank(path, environ=env, headers=hdrs, body='x')
        resp = req.get_response(self.app)
        self._assertStatus(resp, 201)

        env = {'REQUEST_METHOD': 'PUT'}
        hdrs = dict(self.changed_sysmeta_headers)
        hdrs.update(self.new_sysmeta_headers)
        hdrs.update(self.changed_meta_headers)
        hdrs.update(self.new_meta_headers)
        hdrs.update(self.bad_headers)
        req = Request.blank(path, environ=env, headers=hdrs, body='x')
        resp = req.get_response(self.app)
        self._assertStatus(resp, 201)

        req = Request.blank(path, environ={})
        resp = req.get_response(self.app)
        self._assertStatus(resp, 200)
        self._assertInHeaders(resp, self.changed_sysmeta_headers)
        self._assertInHeaders(resp, self.new_sysmeta_headers)
        self._assertNotInHeaders(resp, self.original_sysmeta_headers_2)
        self._assertInHeaders(resp, self.changed_meta_headers)
        self._assertInHeaders(resp, self.new_meta_headers)
        self._assertNotInHeaders(resp, self.original_meta_headers_2)
Пример #29
0
    def test_put_and_get_range(self):
        # put object
        headers = {
            'x-timestamp': Timestamp(time.time()).internal,
            'content-type': 'application/octet-stream',
        }
        body = 'test body'
        req = Request.blank(self._get_path(), method='PUT', headers=headers)
        req.body = body
        resp = req.get_response(self.app)
        self.assertEqual(resp.status_int, 201)

        # get object with range
        req = Request.blank(self._get_path())
        req.range = 'bytes=0-4'
        resp = req.get_response(self.app)
        self.assertEqual(resp.status_int, 206)
        self.assertEqual(resp.body, 'test ')

        # get object with offset
        req = Request.blank(self._get_path())
        req.range = 'bytes=4-'
        resp = req.get_response(self.app)
        self.assertEqual(resp.status_int, 206)
        self.assertEqual(resp.body, ' body')
Пример #30
0
    def test_headers_to_sign_sigv4(self):
        environ = {
            'REQUEST_METHOD': 'GET'}

        # host and x-amz-date
        x_amz_date = self.get_v4_amz_date_header()
        headers = {
            'Authorization':
                'AWS4-HMAC-SHA256 '
                'Credential=test/20130524/US/s3/aws4_request, '
                'SignedHeaders=host;x-amz-content-sha256;x-amz-date,'
                'Signature=X',
            'X-Amz-Content-SHA256': '0123456789',
            'Date': self.get_date_header(),
            'X-Amz-Date': x_amz_date}

        req = Request.blank('/', environ=environ, headers=headers)
        sigv4_req = SigV4Request(req.environ)

        headers_to_sign = sigv4_req._headers_to_sign()
        self.assertEqual(['host', 'x-amz-content-sha256', 'x-amz-date'],
                         sorted(headers_to_sign.keys()))
        self.assertEqual(headers_to_sign['host'], 'localhost:80')
        self.assertEqual(headers_to_sign['x-amz-date'], x_amz_date)
        self.assertEqual(headers_to_sign['x-amz-content-sha256'], '0123456789')

        # no x-amz-date
        headers = {
            'Authorization':
                'AWS4-HMAC-SHA256 '
                'Credential=test/20130524/US/s3/aws4_request, '
                'SignedHeaders=host;x-amz-content-sha256,'
                'Signature=X',
            'X-Amz-Content-SHA256': '0123456789',
            'Date': self.get_date_header()}

        req = Request.blank('/', environ=environ, headers=headers)
        sigv4_req = SigV4Request(req.environ)

        headers_to_sign = sigv4_req._headers_to_sign()
        self.assertEqual(['host', 'x-amz-content-sha256'],
                         sorted(headers_to_sign.keys()))
        self.assertEqual(headers_to_sign['host'], 'localhost:80')
        self.assertEqual(headers_to_sign['x-amz-content-sha256'], '0123456789')

        # SignedHeaders says, host and x-amz-date included but there is not
        # X-Amz-Date header
        headers = {
            'Authorization':
                'AWS4-HMAC-SHA256 '
                'Credential=test/20130524/US/s3/aws4_request, '
                'SignedHeaders=host;x-amz-content-sha256;x-amz-date,'
                'Signature=X',
            'X-Amz-Content-SHA256': '0123456789',
            'Date': self.get_date_header()}

        req = Request.blank('/', environ=environ, headers=headers)
        with self.assertRaises(SignatureDoesNotMatch):
            sigv4_req = SigV4Request(req.environ)
            sigv4_req._headers_to_sign()
 def test_bulk_delete_no_body(self):
     req = Request.blank('/unauth/AUTH_acc/')
     resp_body = self.handle_delete_and_iter(req)
     self.assertTrue('411 Length Required' in resp_body)
Пример #32
0
 def test_GET_not_found(self):
     req = Request.blank('/v1/a/c/o')
     self.storage.object_fetch = Mock(side_effect=exc.NoSuchObject)
     resp = req.get_response(self.app)
     self.assertEqual(resp.status_int, 404)
Пример #33
0
 def test_PUT_if_none_match_not_star(self):
     req = Request.blank('/v1/a/c/o', method='PUT')
     req.headers['if-none-match'] = 'foo'
     req.headers['content-length'] = '0'
     resp = req.get_response(self.app)
     self.assertEqual(resp.status_int, 400)
Пример #34
0
 def test_PUT_requires_length(self):
     req = Request.blank('/v1/a/c/o', method='PUT')
     resp = req.get_response(self.app)
     self.assertEqual(resp.status_int, 411)
 def test_bulk_delete_bad_file_over_twice_max_length(self):
     body = '/c/f\nc/' + ('123456' * self.bulk.max_path_length) + '\n'
     req = Request.blank('/delete_works/AUTH_Acc', body=body)
     req.method = 'POST'
     resp_body = self.handle_delete_and_iter(req)
     self.assertTrue('400 Bad Request' in resp_body)
 def test_bulk_delete_bad_path(self):
     req = Request.blank('/delete_cont_fail/')
     resp_body = self.handle_delete_and_iter(req)
     self.assertTrue('404 Not Found' in resp_body)
 def test_bulk_delete_no_files_in_body(self):
     req = Request.blank('/unauth/AUTH_acc/', body=' ')
     resp_body = self.handle_delete_and_iter(req)
     self.assertTrue('400 Bad Request' in resp_body)
 def test_bad_container(self):
     req = Request.blank('/invalid/', body='')
     resp_body = self.handle_extract_and_iter(req, '')
     self.assertTrue('404 Not Found' in resp_body)
    def test_extract_metadata(self):
        self.app.register('HEAD', '/v1/a/c?extract-archive=tar', HTTPNoContent,
                          {}, None)
        self.app.register('PUT', '/v1/a/c/obj1?extract-archive=tar',
                          HTTPCreated, {}, None)
        self.app.register('PUT', '/v1/a/c/obj2?extract-archive=tar',
                          HTTPCreated, {}, None)

        # It's a real pain to instantiate TarInfo objects directly; they
        # really want to come from a file on disk or a tarball. So, we write
        # out some files and add pax headers to them as they get placed into
        # the tarball.
        with open(os.path.join(self.testdir, "obj1"), "w") as fh1:
            fh1.write("obj1 contents\n")
        with open(os.path.join(self.testdir, "obj2"), "w") as fh2:
            fh2.write("obj2 contents\n")

        tar_ball = StringIO()
        tar_file = tarfile.TarFile.open(fileobj=tar_ball,
                                        mode="w",
                                        format=tarfile.PAX_FORMAT)

        # With GNU tar 1.27.1 or later (possibly 1.27 as well), a file with
        # extended attribute user.thingy = dingy gets put into the tarfile
        # with pax_headers containing key/value pair
        # (SCHILY.xattr.user.thingy, dingy), both unicode strings (py2: type
        # unicode, not type str).
        #
        # With BSD tar (libarchive), you get key/value pair
        # (LIBARCHIVE.xattr.user.thingy, dingy), which strikes me as
        # gratuitous incompatibility.
        #
        # Still, we'll support uploads with both. Just heap more code on the
        # problem until you can forget it's under there.
        with open(os.path.join(self.testdir, "obj1")) as fh1:
            tar_info1 = tar_file.gettarinfo(fileobj=fh1, arcname="obj1")
            tar_info1.pax_headers[u'SCHILY.xattr.user.mime_type'] = \
                u'application/food-diary'
            tar_info1.pax_headers[u'SCHILY.xattr.user.meta.lunch'] = \
                u'sopa de albóndigas'
            tar_info1.pax_headers[
                u'SCHILY.xattr.user.meta.afternoon-snack'] = \
                u'gigantic bucket of coffee'
            tar_file.addfile(tar_info1, fh1)

        with open(os.path.join(self.testdir, "obj2")) as fh2:
            tar_info2 = tar_file.gettarinfo(fileobj=fh2, arcname="obj2")
            tar_info2.pax_headers[
                u'LIBARCHIVE.xattr.user.meta.muppet'] = u'bert'
            tar_info2.pax_headers[
                u'LIBARCHIVE.xattr.user.meta.cat'] = u'fluffy'
            tar_info2.pax_headers[
                u'LIBARCHIVE.xattr.user.notmeta'] = u'skipped'
            tar_file.addfile(tar_info2, fh2)

        tar_ball.seek(0)

        req = Request.blank('/v1/a/c?extract-archive=tar')
        req.environ['REQUEST_METHOD'] = 'PUT'
        req.environ['wsgi.input'] = tar_ball
        req.headers['transfer-encoding'] = 'chunked'
        req.headers['accept'] = 'application/json;q=1.0'

        resp = req.get_response(self.bulk)
        self.assertEqual(resp.status_int, 200)

        # sanity check to make sure the upload worked
        upload_status = utils.json.loads(resp.body)
        self.assertEqual(upload_status['Number Files Created'], 2)

        put1_headers = HeaderKeyDict(self.app.calls_with_headers[1][2])
        self.assertEqual(put1_headers.get('Content-Type'),
                         'application/food-diary')
        self.assertEqual(put1_headers.get('X-Object-Meta-Lunch'),
                         'sopa de alb\xc3\xb3ndigas')
        self.assertEqual(put1_headers.get('X-Object-Meta-Afternoon-Snack'),
                         'gigantic bucket of coffee')

        put2_headers = HeaderKeyDict(self.app.calls_with_headers[2][2])
        self.assertEqual(put2_headers.get('X-Object-Meta-Muppet'), 'bert')
        self.assertEqual(put2_headers.get('X-Object-Meta-Cat'), 'fluffy')
        self.assertEqual(put2_headers.get('Content-Type'), None)
        self.assertEqual(put2_headers.get('X-Object-Meta-Blah'), None)
 def test_content_length_required(self):
     req = Request.blank('/create_cont_fail/acc/cont')
     resp_body = self.handle_extract_and_iter(req, '')
     self.assertTrue('411 Length Required' in resp_body)
Пример #41
0
 def test_cache_middleware(self):
     req = Request.blank('/something', environ={'REQUEST_METHOD': 'GET'})
     resp = self.app(req.environ, start_response)
     self.assertTrue('swift.cache' in resp)
     self.assertTrue(isinstance(resp['swift.cache'], MemcacheRing))
    def test_extract_tar_works(self):
        # On systems where $TMPDIR is long (like OS X), we need to do this
        # or else every upload will fail due to the path being too long.
        self.app.max_pathlen += len(self.testdir)
        for compress_format in ['', 'gz', 'bz2']:
            base_name = 'base_works_%s' % compress_format
            dir_tree = [{
                base_name: [
                    {
                        'sub_dir1': ['sub1_file1', 'sub1_file2']
                    },
                    {
                        'sub_dir2': ['sub2_file1', u'test obj \u2661']
                    },
                    'sub_file1',
                    {
                        'sub_dir3': [{
                            'sub4_dir1': '../sub4 file1'
                        }]
                    },
                    {
                        'sub_dir4': None
                    },
                ]
            }]

            build_dir_tree(self.testdir, dir_tree)
            mode = 'w'
            extension = ''
            if compress_format:
                mode += ':' + compress_format
                extension += '.' + compress_format
            tar = tarfile.open(name=os.path.join(self.testdir,
                                                 'tar_works.tar' + extension),
                               mode=mode)
            tar.add(os.path.join(self.testdir, base_name))
            tar.close()
            req = Request.blank('/tar_works/acc/cont/')
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'
            resp_body = self.handle_extract_and_iter(req, compress_format)
            resp_data = utils.json.loads(resp_body)
            self.assertEquals(resp_data['Number Files Created'], 6)

            # test out xml
            req = Request.blank('/tar_works/acc/cont/')
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'
            resp_body = self.handle_extract_and_iter(req, compress_format,
                                                     'application/xml')
            self.assert_(
                '<response_status>201 Created</response_status>' in resp_body)
            self.assert_(
                '<number_files_created>6</number_files_created>' in resp_body)

            # test out nonexistent format
            req = Request.blank('/tar_works/acc/cont/?extract-archive=tar',
                                headers={'Accept': 'good_xml'})
            req.environ['REQUEST_METHOD'] = 'PUT'
            req.environ['wsgi.input'] = open(
                os.path.join(self.testdir, 'tar_works.tar' + extension))
            req.headers['transfer-encoding'] = 'chunked'

            def fake_start_response(*args, **kwargs):
                pass

            app_iter = self.bulk(req.environ, fake_start_response)
            resp_body = ''.join([i for i in app_iter])

            self.assert_('Response Status: 406' in resp_body)
Пример #43
0
    def test_PUT_req(self):
        body_key = os.urandom(32)
        object_key = fetch_crypto_keys()['object']
        plaintext = b'FAKE APP'
        plaintext_etag = md5hex(plaintext)
        ciphertext = encrypt(plaintext, body_key, FAKE_IV)
        ciphertext_etag = md5hex(ciphertext)

        env = {'REQUEST_METHOD': 'PUT', CRYPTO_KEY_CALLBACK: fetch_crypto_keys}
        hdrs = {
            'etag': plaintext_etag,
            'content-type': 'text/plain',
            'content-length': str(len(plaintext)),
            'x-object-meta-etag': 'not to be confused with the Etag!',
            'x-object-meta-test': 'encrypt me',
            'x-object-sysmeta-test': 'do not encrypt me'
        }
        req = Request.blank('/v1/a/c/o',
                            environ=env,
                            body=plaintext,
                            headers=hdrs)
        self.app.register('PUT', '/v1/a/c/o', HTTPCreated, {})
        with mock.patch(
                'swift.common.middleware.crypto.crypto_utils.'
                'Crypto.create_random_key',
                return_value=body_key):
            resp = req.get_response(self.encrypter)
        self.assertEqual('201 Created', resp.status)
        self.assertEqual(plaintext_etag, resp.headers['Etag'])

        # verify metadata items
        self.assertEqual(1, len(self.app.calls), self.app.calls)
        self.assertEqual('PUT', self.app.calls[0][0])
        req_hdrs = self.app.headers[0]

        # verify body crypto meta
        actual = req_hdrs['X-Object-Sysmeta-Crypto-Body-Meta']
        actual = json.loads(urlparse.unquote_plus(actual))
        self.assertEqual(Crypto().cipher, actual['cipher'])
        self.assertEqual(FAKE_IV, base64.b64decode(actual['iv']))

        # verify wrapped body key
        expected_wrapped_key = encrypt(body_key, object_key, FAKE_IV)
        self.assertEqual(expected_wrapped_key,
                         base64.b64decode(actual['body_key']['key']))
        self.assertEqual(FAKE_IV, base64.b64decode(actual['body_key']['iv']))
        self.assertEqual(fetch_crypto_keys()['id'], actual['key_id'])

        # verify etag
        self.assertEqual(ciphertext_etag, req_hdrs['Etag'])

        encrypted_etag, _junk, etag_meta = \
            req_hdrs['X-Object-Sysmeta-Crypto-Etag'].partition('; swift_meta=')
        # verify crypto_meta was appended to this etag
        self.assertTrue(etag_meta)
        actual_meta = json.loads(urlparse.unquote_plus(etag_meta))
        self.assertEqual(Crypto().cipher, actual_meta['cipher'])

        # verify encrypted version of plaintext etag
        actual = base64.b64decode(encrypted_etag)
        etag_iv = base64.b64decode(actual_meta['iv'])
        enc_etag = encrypt(plaintext_etag.encode('ascii'), object_key, etag_iv)
        self.assertEqual(enc_etag, actual)

        # verify etag MAC for conditional requests
        actual_hmac = base64.b64decode(
            req_hdrs['X-Object-Sysmeta-Crypto-Etag-Mac'])
        exp_hmac = hmac.new(object_key, plaintext_etag.encode('ascii'),
                            hashlib.sha256).digest()
        self.assertEqual(actual_hmac, exp_hmac)

        # verify encrypted etag for container update
        self.assertIn('X-Object-Sysmeta-Container-Update-Override-Etag',
                      req_hdrs)
        parts = req_hdrs[
            'X-Object-Sysmeta-Container-Update-Override-Etag'].rsplit(';', 1)
        self.assertEqual(2, len(parts))

        # extract crypto_meta from end of etag for container update
        param = parts[1].strip()
        crypto_meta_tag = 'swift_meta='
        self.assertTrue(param.startswith(crypto_meta_tag), param)
        actual_meta = json.loads(
            urlparse.unquote_plus(param[len(crypto_meta_tag):]))
        self.assertEqual(Crypto().cipher, actual_meta['cipher'])
        self.assertEqual(fetch_crypto_keys()['id'], actual_meta['key_id'])

        cont_key = fetch_crypto_keys()['container']
        cont_etag_iv = base64.b64decode(actual_meta['iv'])
        self.assertEqual(FAKE_IV, cont_etag_iv)
        exp_etag = encrypt(plaintext_etag.encode('ascii'), cont_key,
                           cont_etag_iv)
        self.assertEqual(exp_etag, base64.b64decode(parts[0]))

        # content-type is not encrypted
        self.assertEqual('text/plain', req_hdrs['Content-Type'])

        # user meta is encrypted
        self._verify_user_metadata(req_hdrs, 'Test', 'encrypt me', object_key)
        self._verify_user_metadata(req_hdrs, 'Etag',
                                   'not to be confused with the Etag!',
                                   object_key)

        # sysmeta is not encrypted
        self.assertEqual('do not encrypt me',
                         req_hdrs['X-Object-Sysmeta-Test'])

        # verify object is encrypted by getting direct from the app
        get_req = Request.blank('/v1/a/c/o', environ={'REQUEST_METHOD': 'GET'})
        resp = get_req.get_response(self.app)
        self.assertEqual(ciphertext, resp.body)
        self.assertEqual(ciphertext_etag, resp.headers['Etag'])
Пример #44
0
 def _make_request(self, path, **kwargs):
     req = Request.blank(path, **kwargs)
     req.environ['swift.cache'] = FakeMemcache()
     return req
Пример #45
0
    def _test_PUT_with_other_footers(self, override_etag):
        # verify handling of another middleware's footer callback
        body_key = os.urandom(32)
        object_key = fetch_crypto_keys()['object']
        plaintext = b'FAKE APP'
        plaintext_etag = md5hex(plaintext)
        ciphertext = encrypt(plaintext, body_key, FAKE_IV)
        ciphertext_etag = md5hex(ciphertext)
        other_footers = {
            'Etag': plaintext_etag,
            'X-Object-Sysmeta-Other': 'other sysmeta',
            'X-Object-Sysmeta-Container-Update-Override-Size':
            'other override',
            'X-Object-Sysmeta-Container-Update-Override-Etag': override_etag
        }

        env = {
            'REQUEST_METHOD':
            'PUT',
            CRYPTO_KEY_CALLBACK:
            fetch_crypto_keys,
            'swift.callback.update_footers':
            lambda footers: footers.update(other_footers)
        }
        hdrs = {
            'content-type': 'text/plain',
            'content-length': str(len(plaintext)),
            'Etag': 'correct etag is in footers'
        }
        req = Request.blank('/v1/a/c/o',
                            environ=env,
                            body=plaintext,
                            headers=hdrs)
        self.app.register('PUT', '/v1/a/c/o', HTTPCreated, {})

        with mock.patch(
                'swift.common.middleware.crypto.crypto_utils.'
                'Crypto.create_random_key', lambda *args: body_key):
            resp = req.get_response(self.encrypter)

        self.assertEqual('201 Created', resp.status)
        self.assertEqual(plaintext_etag, resp.headers['Etag'])

        # verify metadata items
        self.assertEqual(1, len(self.app.calls), self.app.calls)
        self.assertEqual('PUT', self.app.calls[0][0])
        req_hdrs = self.app.headers[0]

        # verify that other middleware's footers made it to app, including any
        # container update overrides but nothing Etag-related
        other_footers.pop('Etag')
        other_footers.pop('X-Object-Sysmeta-Container-Update-Override-Etag')
        for k, v in other_footers.items():
            self.assertEqual(v, req_hdrs[k])

        # verify encryption footers are ok
        encrypted_etag, _junk, etag_meta = \
            req_hdrs['X-Object-Sysmeta-Crypto-Etag'].partition('; swift_meta=')
        self.assertTrue(etag_meta)
        actual_meta = json.loads(urlparse.unquote_plus(etag_meta))
        self.assertEqual(Crypto().cipher, actual_meta['cipher'])

        self.assertEqual(ciphertext_etag, req_hdrs['Etag'])
        actual = base64.b64decode(encrypted_etag)
        etag_iv = base64.b64decode(actual_meta['iv'])
        exp_etag = encrypt(plaintext_etag.encode('ascii'), object_key, etag_iv)
        self.assertEqual(exp_etag, actual)

        # verify encrypted etag for container update
        self.assertIn('X-Object-Sysmeta-Container-Update-Override-Etag',
                      req_hdrs)
        parts = req_hdrs[
            'X-Object-Sysmeta-Container-Update-Override-Etag'].rsplit(';', 1)
        self.assertEqual(2, len(parts))

        # extract crypto_meta from end of etag for container update
        param = parts[1].strip()
        crypto_meta_tag = 'swift_meta='
        self.assertTrue(param.startswith(crypto_meta_tag), param)
        actual_meta = json.loads(
            urlparse.unquote_plus(param[len(crypto_meta_tag):]))
        self.assertEqual(Crypto().cipher, actual_meta['cipher'])

        cont_key = fetch_crypto_keys()['container']
        cont_etag_iv = base64.b64decode(actual_meta['iv'])
        self.assertEqual(FAKE_IV, cont_etag_iv)
        exp_etag = encrypt(override_etag.encode('ascii'), cont_key,
                           cont_etag_iv)
        self.assertEqual(exp_etag, base64.b64decode(parts[0]))

        # verify body crypto meta
        actual = req_hdrs['X-Object-Sysmeta-Crypto-Body-Meta']
        actual = json.loads(urlparse.unquote_plus(actual))
        self.assertEqual(Crypto().cipher, actual['cipher'])
        self.assertEqual(FAKE_IV, base64.b64decode(actual['iv']))

        # verify wrapped body key
        expected_wrapped_key = encrypt(body_key, object_key, FAKE_IV)
        self.assertEqual(expected_wrapped_key,
                         base64.b64decode(actual['body_key']['key']))
        self.assertEqual(FAKE_IV, base64.b64decode(actual['body_key']['iv']))
        self.assertEqual(fetch_crypto_keys()['id'], actual['key_id'])
Пример #46
0
    def make_request(self,
                     method,
                     path,
                     headers,
                     acceptable_statuses,
                     body_file=None,
                     params=None):
        """Makes a request to Swift with retries.

        :param method: HTTP method of request.
        :param path: Path of request.
        :param headers: Headers to be sent with request.
        :param acceptable_statuses: List of acceptable statuses for request.
        :param body_file: Body file to be passed along with request,
                          defaults to None.
        :param params: A dict of params to be set in request query string,
                       defaults to None.

        :returns: Response object on success.

        :raises UnexpectedResponse: Exception raised when make_request() fails
                                    to get a response with an acceptable status
        :raises Exception: Exception is raised when code fails in an
                           unexpected way.
        """

        headers = dict(headers)
        headers['user-agent'] = self.user_agent
        headers.setdefault('x-backend-allow-reserved-names', 'true')
        for attempt in range(self.request_tries):
            resp = exc_type = exc_value = exc_traceback = None
            req = Request.blank(path,
                                environ={'REQUEST_METHOD': method},
                                headers=headers)
            if body_file is not None:
                if hasattr(body_file, 'seek'):
                    body_file.seek(0)
                req.body_file = body_file
            if params:
                req.params = params
            try:
                resp = req.get_response(self.app)
            except (Exception, Timeout):
                exc_type, exc_value, exc_traceback = exc_info()
            else:
                if resp.status_int in acceptable_statuses or \
                        resp.status_int // 100 in acceptable_statuses:
                    return resp
                elif not is_server_error(resp.status_int):
                    # No sense retrying when we expect the same result
                    break
            # sleep only between tries, not after each one
            if attempt < self.request_tries - 1:
                if resp:
                    # always close any resp.app_iter before we discard it
                    with closing_if_possible(resp.app_iter):
                        # for non 2XX requests it's safe and useful to drain
                        # the response body so we log the correct status code
                        if resp.status_int // 100 != 2:
                            for iter_body in resp.app_iter:
                                pass
                sleep(2**(attempt + 1))
        if resp:
            msg = 'Unexpected response: %s' % resp.status
            if resp.status_int // 100 != 2 and resp.body:
                # provide additional context (and drain the response body) for
                # non 2XX responses
                msg += ' (%s)' % resp.body
            raise UnexpectedResponse(msg, resp)
        if exc_type:
            # To make pep8 tool happy, in place of raise t, v, tb:
            six.reraise(exc_type, exc_value, exc_traceback)
Пример #47
0
 def do_test(host):
     req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': host})
     return app(req.environ, start_response)
Пример #48
0
    def test_PUT_nothing_read(self):
        # simulate an artificial scenario of a downstream filter/app not
        # actually reading the input stream from encrypter.
        class NonReadingApp(object):
            def __call__(self, env, start_response):
                # note: no read from wsgi.input
                req = Request(env)
                env['swift.callback.update_footers'](req.headers)
                call_headers.append(req.headers)
                resp = HTTPCreated(req=req, headers={'Etag': 'response etag'})
                return resp(env, start_response)

        env = {'REQUEST_METHOD': 'PUT', CRYPTO_KEY_CALLBACK: fetch_crypto_keys}
        hdrs = {
            'content-type': 'text/plain',
            'content-length': 0,
            'etag': 'etag from client'
        }
        req = Request.blank('/v1/a/c/o', environ=env, body='', headers=hdrs)

        call_headers = []
        resp = req.get_response(encrypter.Encrypter(NonReadingApp(), {}))
        self.assertEqual('201 Created', resp.status)
        self.assertEqual('response etag', resp.headers['Etag'])
        self.assertEqual(1, len(call_headers))
        self.assertEqual('etag from client', call_headers[0]['etag'])
        # verify no encryption footers
        for k in call_headers[0]:
            self.assertFalse(k.lower().startswith('x-object-sysmeta-crypto-'))

        # check that an upstream footer callback gets called
        other_footers = {
            'Etag': EMPTY_ETAG,
            'X-Object-Sysmeta-Other': 'other sysmeta',
            'X-Object-Sysmeta-Container-Update-Override-Etag': 'other override'
        }
        env.update({
            'swift.callback.update_footers':
            lambda footers: footers.update(other_footers)
        })
        req = Request.blank('/v1/a/c/o', environ=env, body='', headers=hdrs)

        call_headers = []
        resp = req.get_response(encrypter.Encrypter(NonReadingApp(), {}))

        self.assertEqual('201 Created', resp.status)
        self.assertEqual('response etag', resp.headers['Etag'])
        self.assertEqual(1, len(call_headers))

        # verify encrypted override etag for container update.
        self.assertIn('X-Object-Sysmeta-Container-Update-Override-Etag',
                      call_headers[0])
        parts = call_headers[0][
            'X-Object-Sysmeta-Container-Update-Override-Etag'].rsplit(';', 1)
        self.assertEqual(2, len(parts))
        cont_key = fetch_crypto_keys()['container']

        param = parts[1].strip()
        crypto_meta_tag = 'swift_meta='
        self.assertTrue(param.startswith(crypto_meta_tag), param)
        actual_meta = json.loads(
            urlparse.unquote_plus(param[len(crypto_meta_tag):]))
        self.assertEqual(Crypto().cipher, actual_meta['cipher'])
        self.assertEqual(fetch_crypto_keys()['id'], actual_meta['key_id'])

        cont_etag_iv = base64.b64decode(actual_meta['iv'])
        self.assertEqual(FAKE_IV, cont_etag_iv)
        self.assertEqual(encrypt(b'other override', cont_key, cont_etag_iv),
                         base64.b64decode(parts[0]))

        # verify that other middleware's footers made it to app
        other_footers.pop('X-Object-Sysmeta-Container-Update-Override-Etag')
        for k, v in other_footers.items():
            self.assertEqual(v, call_headers[0][k])
        # verify no encryption footers
        for k in call_headers[0]:
            self.assertFalse(k.lower().startswith('x-object-sysmeta-crypto-'))

        # if upstream footer override etag is for an empty body then check that
        # it is not encrypted
        other_footers = {
            'Etag': EMPTY_ETAG,
            'X-Object-Sysmeta-Container-Update-Override-Etag': EMPTY_ETAG
        }
        env.update({
            'swift.callback.update_footers':
            lambda footers: footers.update(other_footers)
        })
        req = Request.blank('/v1/a/c/o', environ=env, body='', headers=hdrs)

        call_headers = []
        resp = req.get_response(encrypter.Encrypter(NonReadingApp(), {}))

        self.assertEqual('201 Created', resp.status)
        self.assertEqual('response etag', resp.headers['Etag'])
        self.assertEqual(1, len(call_headers))

        # verify that other middleware's footers made it to app
        for k, v in other_footers.items():
            self.assertEqual(v, call_headers[0][k])
        # verify no encryption footers
        for k in call_headers[0]:
            self.assertFalse(k.lower().startswith('x-object-sysmeta-crypto-'))

        # if upstream footer override etag is an empty string then check that
        # it is not encrypted
        other_footers = {
            'Etag': EMPTY_ETAG,
            'X-Object-Sysmeta-Container-Update-Override-Etag': ''
        }
        env.update({
            'swift.callback.update_footers':
            lambda footers: footers.update(other_footers)
        })
        req = Request.blank('/v1/a/c/o', environ=env, body='', headers=hdrs)

        call_headers = []
        resp = req.get_response(encrypter.Encrypter(NonReadingApp(), {}))

        self.assertEqual('201 Created', resp.status)
        self.assertEqual('response etag', resp.headers['Etag'])
        self.assertEqual(1, len(call_headers))

        # verify that other middleware's footers made it to app
        for k, v in other_footers.items():
            self.assertEqual(v, call_headers[0][k])
        # verify no encryption footers
        for k in call_headers[0]:
            self.assertFalse(k.lower().startswith('x-object-sysmeta-crypto-'))
Пример #49
0
 def test_cname_matching_ending_not_domain(self):
     req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'foo.com'})
     resp = self.app(req.environ, start_response)
     self.assertEqual(resp,
                      ['CNAME lookup failed to resolve to a valid domain'])
Пример #50
0
 def test_PUT_app_exception(self):
     app = encrypter.Encrypter(FakeAppThatExcepts(HTTPException), {})
     req = Request.blank('/', environ={'REQUEST_METHOD': 'PUT'})
     with self.assertRaises(HTTPException) as catcher:
         req.get_response(app)
     self.assertEqual(FakeAppThatExcepts.MESSAGE, catcher.exception.body)
Пример #51
0
 def test_something_weird(self):
     req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'mysite.com'})
     resp = self.app(req.environ, start_response)
     self.assertEqual(resp,
                      ['CNAME lookup failed to resolve to a valid domain'])
Пример #52
0
 def do_test(lookup_back):
     req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'c.a.example.com'})
     module = 'swift.common.middleware.cname_lookup.lookup_cname'
     with mock.patch(module, lambda d, r: (0, lookup_back)):
         return app(req.environ, start_response)
Пример #53
0
 def _make_request(self, **kwargs):
     req = Request.blank("/v1/AUTH_account/cont", **kwargs)
     return req
Пример #54
0
    def test_caching(self):
        fail_to_resolve = ['CNAME lookup failed to resolve to a valid domain']

        class memcache_stub(object):
            def __init__(self):
                self.cache = {}

            def get(self, key):
                return self.cache.get(key, None)

            def set(self, key, value, *a, **kw):
                self.cache[key] = value

        module = 'swift.common.middleware.cname_lookup.lookup_cname'
        dns_module = 'dns.resolver.Resolver.query'
        memcache = memcache_stub()

        with mock.patch(module) as m:
            m.return_value = (3600, 'c.example.com')
            req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                              'swift.cache': memcache},
                                headers={'Host': 'mysite2.com'})
            resp = self.app(req.environ, start_response)
            self.assertEqual(resp, ['FAKE APP'])
            self.assertEqual(m.call_count, 1)
            self.assertEqual(memcache.cache.get('cname-mysite2.com'),
                             'c.example.com')
            req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                              'swift.cache': memcache},
                                headers={'Host': 'mysite2.com'})
            resp = self.app(req.environ, start_response)
            self.assertEqual(resp, ['FAKE APP'])
            self.assertEqual(m.call_count, 1)
            self.assertEqual(memcache.cache.get('cname-mysite2.com'),
                             'c.example.com')

        for exc, num in ((dns.resolver.NXDOMAIN(), 3),
                         (dns.resolver.NoAnswer(), 4)):
            with mock.patch(dns_module) as m:
                m.side_effect = exc
                req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                                  'swift.cache': memcache},
                                    headers={'Host': 'mysite%d.com' % num})
                resp = self.app(req.environ, start_response)
                self.assertEqual(resp, fail_to_resolve)
                self.assertEqual(m.call_count, 1)
                self.assertEqual(memcache.cache.get('cname-mysite3.com'),
                                 False)
                req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                                  'swift.cache': memcache},
                                    headers={'Host': 'mysite%d.com' % num})
                resp = self.app(req.environ, start_response)
                self.assertEqual(resp, fail_to_resolve)
                self.assertEqual(m.call_count, 1)
                self.assertEqual(
                    memcache.cache.get('cname-mysite%d.com' % num), False)

        with mock.patch(dns_module) as m:
            m.side_effect = dns.exception.DNSException()
            req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                              'swift.cache': memcache},
                                headers={'Host': 'mysite5.com'})
            resp = self.app(req.environ, start_response)
            self.assertEqual(resp, fail_to_resolve)
            self.assertEqual(m.call_count, 1)
            self.assertFalse('cname-mysite5.com' in memcache.cache)
            req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
                                              'swift.cache': memcache},
                                headers={'Host': 'mysite5.com'})
            resp = self.app(req.environ, start_response)
            self.assertEqual(resp, fail_to_resolve)
            self.assertEqual(m.call_count, 2)
            self.assertFalse('cname-mysite5.com' in memcache.cache)
Пример #55
0
 def test_domain_remap_extra_subdomains(self):
     req = Request.blank('/',
                         environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'x.y.c.AUTH_a.example.com'})
     resp = self.app(req.environ, start_response)
     self.assertEqual(resp, ['Bad domain in host header'])
Пример #56
0
    def test_object_HEAD_error(self):
        # HEAD does not return the body even an error response in the
        # specifications of the REST API.
        # So, check the response code for error test of HEAD.
        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPUnauthorized, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '403')
        self.assertEqual(body, '')  # sanity

        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPForbidden, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '403')
        self.assertEqual(body, '')  # sanity

        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPNotFound, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '404')
        self.assertEqual(body, '')  # sanity

        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPPreconditionFailed, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '412')
        self.assertEqual(body, '')  # sanity

        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPServerError, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '500')
        self.assertEqual(body, '')  # sanity

        req = Request.blank('/bucket/object',
                            environ={'REQUEST_METHOD': 'HEAD'},
                            headers={
                                'Authorization': 'AWS test:tester:hmac',
                                'Date': self.get_date_header()
                            })
        self.swift.register('HEAD', '/v1/AUTH_test/bucket/object',
                            swob.HTTPServiceUnavailable, {}, None)
        status, headers, body = self.call_swift3(req)
        self.assertEqual(status.split()[0], '500')
        self.assertEqual(body, '')  # sanity
Пример #57
0
 def test_check_metadata_empty_name(self):
     headers = {'X-Object-Meta-': 'Value'}
     resp = constraints.check_metadata(Request.blank('/', headers=headers),
                                       'object')
     self.assertEqual(resp.status_int, HTTP_BAD_REQUEST)
     self.assertIn('Metadata name cannot be empty', resp.body)
Пример #58
0
 def test_domain_remap_account_container_with_path_root(self):
     req = Request.blank('/v1',
                         environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'c.AUTH_a.example.com'})
     resp = self.app(req.environ, start_response)
     self.assertEqual(resp, '/v1/AUTH_a/c')
Пример #59
0
 def test_check_metadata_good(self):
     headers = {'X-Object-Meta-Name': 'Value'}
     self.assertIsNone(
         constraints.check_metadata(Request.blank('/', headers=headers),
                                    'object'))
Пример #60
0
 def test_domain_remap_account_matching_ending_not_domain(self):
     req = Request.blank('/dontchange',
                         environ={'REQUEST_METHOD': 'GET'},
                         headers={'Host': 'c.aexample.com'})
     resp = self.app(req.environ, start_response)
     self.assertEqual(resp, '/dontchange')