コード例 #1
0
 def PUT(self, req):
     """HTTP PUT request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     if len(self.container_name) > MAX_CONTAINER_NAME_LENGTH:
         resp = HTTPBadRequest(request=req)
         resp.body = 'Container name length of %d longer than %d' % \
                     (len(self.container_name), MAX_CONTAINER_NAME_LENGTH)
         return resp
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if self.app.max_containers_per_account > 0 and \
             container_count >= self.app.max_containers_per_account and \
             self.account_name not in self.app.max_containers_whitelist:
         resp = HTTPForbidden(request=req)
         resp.body = 'Reached container limit of %s' % \
                     self.app.max_containers_per_account
         return resp
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = self._backend_requests(req, len(containers),
                                      account_partition, accounts)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
                               container_partition, 'PUT', req.path_info,
                               headers)
     return resp
コード例 #2
0
ファイル: ratelimit.py プロジェクト: Awingu/swift
    def get_ratelimitable_key_tuples(self, req_method, account_name,
                                     container_name=None, obj_name=None):
        """
        Returns a list of key (used in memcache), ratelimit tuples. Keys
        should be checked in order.

        :param req_method: HTTP method
        :param account_name: account name from path
        :param container_name: container name from path
        :param obj_name: object name from path
        """
        keys = []
        # COPYs are not limited
        if self.account_ratelimit and \
                account_name and container_name and not obj_name and \
                req_method in ('PUT', 'DELETE'):
            keys.append(("ratelimit/%s" % account_name,
                         self.account_ratelimit))

        if account_name and container_name and obj_name and \
                req_method in ('PUT', 'DELETE', 'POST'):
            container_size = None
            memcache_key = get_container_memcache_key(account_name,
                                                      container_name)
            container_info = self.memcache_client.get(memcache_key)
            if isinstance(container_info, dict):
                container_size = container_info.get(
                    'object_count', container_info.get('container_size', 0))
                container_rate = self.get_container_maxrate(container_size)
                if container_rate:
                    keys.append(("ratelimit/%s/%s" % (account_name,
                                                      container_name),
                                 container_rate))
        return keys
コード例 #3
0
 def test_get_ratelimitable_key_tuples(self):
     current_rate = 13
     conf_dict = {
         'account_ratelimit': current_rate,
         'container_ratelimit_3': 200
     }
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'container_size': 5}
     the_app = ratelimit.RateLimitMiddleware(None,
                                             conf_dict,
                                             logger=FakeLogger())
     the_app.memcache_client = fake_memcache
     self.assertEquals(
         len(the_app.get_ratelimitable_key_tuples('DELETE', 'a', None,
                                                  None)), 0)
     self.assertEquals(
         len(the_app.get_ratelimitable_key_tuples('PUT', 'a', 'c', None)),
         1)
     self.assertEquals(
         len(the_app.get_ratelimitable_key_tuples('DELETE', 'a', 'c',
                                                  None)), 1)
     self.assertEquals(
         len(the_app.get_ratelimitable_key_tuples('GET', 'a', 'c', 'o')), 0)
     self.assertEquals(
         len(the_app.get_ratelimitable_key_tuples('PUT', 'a', 'c', 'o')), 1)
コード例 #4
0
 def POST(self, req):
     """HTTP POST request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = {'X-Timestamp': normalize_timestamp(time.time()),
                'x-trans-id': self.trans_id,
                'Connection': 'close'}
     self.transfer_headers(req.headers, headers)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
             container_partition, 'POST', req.path_info,
             [headers] * len(containers))
     return resp
コード例 #5
0
ファイル: container.py プロジェクト: lcnsir/swift
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        if not self.account_info(self.account_name)[1]:
            return HTTPNotFound(request=req)
        part, nodes = self.app.container_ring.get_nodes(
                        self.account_name, self.container_name)
        shuffle(nodes)
        resp = self.GETorHEAD_base(req, _('Container'), part, nodes,
                req.path_info, len(nodes))

        if self.app.memcache:
            # set the memcache container size for ratelimiting
            cache_key = get_container_memcache_key(self.account_name,
                                                   self.container_name)
            self.app.memcache.set(cache_key,
              {'status': resp.status_int,
               'read_acl': resp.headers.get('x-container-read'),
               'write_acl': resp.headers.get('x-container-write'),
               'sync_key': resp.headers.get('x-container-sync-key'),
               'count': resp.headers.get('x-container-object-count'),
               'bytes': resp.headers.get('x-container-bytes-used'),
               'versions': resp.headers.get('x-versions-location')},
                                  timeout=self.app.recheck_container_existence)

        if 'swift.authorize' in req.environ:
            req.acl = resp.headers.get('x-container-read')
            aresp = req.environ['swift.authorize'](req)
            if aresp:
                return aresp
        if not req.environ.get('swift_owner', False):
            for key in ('x-container-read', 'x-container-write',
                        'x-container-sync-key', 'x-container-sync-to'):
                if key in resp.headers:
                    del resp.headers[key]
        return resp
コード例 #6
0
ファイル: container.py プロジェクト: lcnsir/swift
 def DELETE(self, req):
     """HTTP DELETE request handler."""
     account_partition, accounts, container_count = \
         self.account_info(self.account_name)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = []
     for account in accounts:
         headers.append({'X-Timestamp': normalize_timestamp(time.time()),
                        'X-Trans-Id': self.trans_id,
                        'X-Account-Host': '%(ip)s:%(port)s' % account,
                        'X-Account-Partition': account_partition,
                        'X-Account-Device': account['device'],
                        'Connection': 'close'})
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
                 container_partition, 'DELETE', req.path_info, headers)
     # Indicates no server had the container
     if resp.status_int == HTTP_ACCEPTED:
         return HTTPNotFound(request=req)
     return resp
コード例 #7
0
ファイル: ratelimit.py プロジェクト: zhoubing00/swift
    def get_ratelimitable_key_tuples(self, req_method, account_name,
                                     container_name=None, obj_name=None):
        """
        Returns a list of key (used in memcache), ratelimit tuples. Keys
        should be checked in order.

        :param req_method: HTTP method
        :param account_name: account name from path
        :param container_name: container name from path
        :param obj_name: object name from path
        """
        keys = []
        # COPYs are not limited
        if self.account_ratelimit and \
                account_name and container_name and not obj_name and \
                req_method in ('PUT', 'DELETE'):
            keys.append(("ratelimit/%s" % account_name,
                         self.account_ratelimit))

        if account_name and container_name and obj_name and \
                req_method in ('PUT', 'DELETE', 'POST'):
            container_size = None
            memcache_key = get_container_memcache_key(account_name,
                                                      container_name)
            container_info = self.memcache_client.get(memcache_key)
            if isinstance(container_info, dict):
                container_size = container_info.get(
                    'count', container_info.get('container_size', 0))
                container_rate = self.get_container_maxrate(container_size)
                if container_rate:
                    keys.append(("ratelimit/%s/%s" % (account_name,
                                                      container_name),
                                 container_rate))
        return keys
コード例 #8
0
ファイル: container.py プロジェクト: Neil-Jubinville/swift
 def PUT(self, req):
     """HTTP PUT request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     if len(self.container_name) > MAX_CONTAINER_NAME_LENGTH:
         resp = HTTPBadRequest(request=req)
         resp.body = 'Container name length of %d longer than %d' % \
                     (len(self.container_name), MAX_CONTAINER_NAME_LENGTH)
         return resp
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if self.app.max_containers_per_account > 0 and \
             container_count >= self.app.max_containers_per_account and \
             self.account_name not in self.app.max_containers_whitelist:
         resp = HTTPForbidden(request=req)
         resp.body = 'Reached container limit of %s' % \
                     self.app.max_containers_per_account
         return resp
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = self._backend_requests(req, len(containers),
                                      account_partition, accounts)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(
         req, self.app.container_ring,
         container_partition, 'PUT', req.path_info, headers)
     return resp
コード例 #9
0
ファイル: container.py プロジェクト: waiterZen/swift
 def POST(self, req):
     """HTTP POST request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = {
         'X-Timestamp': normalize_timestamp(time.time()),
         'x-trans-id': self.trans_id,
         'Connection': 'close'
     }
     self.transfer_headers(req.headers, headers)
     if self.app.memcache:
         self.app.memcache.delete(
             get_container_memcache_key(self.account_name,
                                        self.container_name))
     resp = self.make_requests(req, self.app.container_ring,
                               container_partition, 'POST', req.path_info,
                               [headers] * len(containers))
     return resp
コード例 #10
0
ファイル: container.py プロジェクト: waiterZen/swift
 def DELETE(self, req):
     """HTTP DELETE request handler."""
     account_partition, accounts, container_count = \
         self.account_info(self.account_name)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = []
     for account in accounts:
         headers.append({
             'X-Timestamp': normalize_timestamp(time.time()),
             'X-Trans-Id': self.trans_id,
             'X-Account-Host': '%(ip)s:%(port)s' % account,
             'X-Account-Partition': account_partition,
             'X-Account-Device': account['device'],
             'Connection': 'close'
         })
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
                               container_partition, 'DELETE', req.path_info,
                               headers)
     # Indicates no server had the container
     if resp.status_int == HTTP_ACCEPTED:
         return HTTPNotFound(request=req)
     return resp
コード例 #11
0
    def test_ratelimit_max_rate_double_container(self):
        global time_ticker
        global time_override
        current_rate = 2
        conf_dict = {
            'container_ratelimit_0': current_rate,
            'clock_accuracy': 100,
            'max_sleep_time_seconds': 1
        }
        self.test_ratelimit = ratelimit.filter_factory(conf_dict)(FakeApp())
        ratelimit.http_connect = mock_http_connect(204)
        self.test_ratelimit.log_sleep_time_seconds = .00001
        req = Request.blank('/v/a/c/o')
        req.method = 'PUT'
        req.environ['swift.cache'] = FakeMemcache()
        req.environ['swift.cache'].set(get_container_memcache_key('a', 'c'),
                                       {'container_size': 1})

        time_override = [0, 0, 0, 0, None]
        # simulates 4 requests coming in at same time, then sleeping
        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        lambda *args, **kwargs: {}):
            r = self.test_ratelimit(req.environ, start_response)
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], 'Slow down')
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], 'Slow down')
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], '204 No Content')
コード例 #12
0
ファイル: quota.py プロジェクト: NewpTone/StackLab-swift
    def handle_delete(self, env, start_response, version, account, container,
                      obj):
        """ Handle delete request. """
        memcache_client = cache_from_env(env)
        if not memcache_client:
            return self.app(env, start_response)

        res = [None, None, None]
        result_code = None

        def _start_response(response_status, response_headers, exc_info=None):
            res[0] = response_status
            res[1] = response_headers
            res[2] = exc_info

        resp = self.app(env, _start_response)
        result_code = self._get_status_int(res[0])
        try:
            if is_success(result_code):
                if obj:
                    memcache_client.delete(
                        get_container_memcache_key(account, container))
                else:
                    memcache_client.delete(get_account_memcache_key(account))
        except Exception, err:
            self.logger.error(
                'Error in [Quota] delete cache: %s' % (err.message))
コード例 #13
0
ファイル: test_ratelimit.py プロジェクト: bouncestorage/swift
    def test_ratelimit_max_rate_double_container(self):
        global time_ticker
        global time_override
        current_rate = 2
        conf_dict = {'container_ratelimit_0': current_rate,
                     'clock_accuracy': 100,
                     'max_sleep_time_seconds': 1}
        self.test_ratelimit = ratelimit.filter_factory(conf_dict)(FakeApp())
        ratelimit.http_connect = mock_http_connect(204)
        self.test_ratelimit.log_sleep_time_seconds = .00001
        req = Request.blank('/v/a/c/o')
        req.method = 'PUT'
        req.environ['swift.cache'] = FakeMemcache()
        req.environ['swift.cache'].set(
            get_container_memcache_key('a', 'c'),
            {'container_size': 1})

        time_override = [0, 0, 0, 0, None]
        # simulates 4 requests coming in at same time, then sleeping
        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        lambda *args, **kwargs: {}):
            r = self.test_ratelimit(req.environ, start_response)
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], 'Slow down')
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], 'Slow down')
            mock_sleep(.1)
            r = self.test_ratelimit(req.environ, start_response)
            self.assertEquals(r[0], '204 No Content')
コード例 #14
0
ファイル: quota.py プロジェクト: NewpTone/StackLab-swift
    def handle_quota_object(self, env, start_response, version, account,
                            container, obj):
        """ Handle quota of container usage and object count. """
        memcache_client = cache_from_env(env)
        object_size = int(env.get('CONTENT_LENGTH') or 0)
        container_count, quota_level = self._get_account_meta(
            env, version, account, memcache_client)
        try:
            container_usage_quota = self.container_usage[quota_level]
            object_count_quota = self.object_count[quota_level]
        except Exception:
            self.logger.warn('Invalid quota_leve %s/%s quota_level[%s].' % (
                account, container, quota_level))
            container_usage_quota = None
            object_count_quota = None
        container_usage, object_count = self._get_container_meta(
            env, version, account, container, memcache_client)
        if container_usage_quota and container_usage >= container_usage_quota:
            self.logger.notice("Container usage over quota, "
                               "request[PUT %s/%s/%s], container_usage[%s] "
                               "object_size[%s] quota[%s]" % (
                                   account, container, obj, container_usage,
                                   object_size, container_usage_quota))
            return HTTPForbidden(body="The usage of container is over quota")(
                env, start_response)
        elif container_usage_quota and (container_usage + object_size >
                                        container_usage_quota):
            self.logger.notice("Container usage over quota, "
                               "request[PUT %s/%s/%s], container_usage[%s] "
                               "object_size[%s] quota[%s]" % (
                                   account, container, obj, container_usage,
                                   object_size, container_usage_quota))
            return HTTPForbidden(body="The usage of container is over quota")(
                env, start_response)
        elif object_count_quota and object_count + 1 > object_count_quota:
            self.logger.notice("Object count over quota, request[PUT %s/%s/%s],"
                               "object_count[%s] quota[%s]" % (
                                   account, container, obj, object_count + 1,
                                   object_count_quota))
            return HTTPForbidden(body="The count of object is over quota")(
                env, start_response)
        elif self.precise_mode and memcache_client:
            res = [None, None, None]
            result_code = None

            def _start_response(response_status, response_headers,
                                exc_info=None):
                res[0] = response_status
                res[1] = response_headers
                res[2] = exc_info

            resp = self.app(env, _start_response)
            result_code = self._get_status_int(res[0])
            if is_success(result_code):
                memcache_client.delete(
                    get_container_memcache_key(account, container))
            start_response(res[0], res[1], res[2])
            return resp
        else:
            return self.app(env, start_response)
コード例 #15
0
ファイル: container.py プロジェクト: zhanghua/swift
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        if not self.account_info(self.account_name, req)[1]:
            return HTTPNotFound(request=req)
        part = self.app.container_ring.get_part(
            self.account_name, self.container_name)
        resp = self.GETorHEAD_base(
            req, _('Container'), self.app.container_ring, part, req.path_info)
        if self.app.memcache:
            # set the memcache container size for ratelimiting
            cache_key = get_container_memcache_key(self.account_name,
                                                   self.container_name)
            self.app.memcache.set(
                cache_key,
                headers_to_container_info(resp.headers, resp.status_int),
                time=self.app.recheck_container_existence)

        if 'swift.authorize' in req.environ:
            req.acl = resp.headers.get('x-container-read')
            aresp = req.environ['swift.authorize'](req)
            if aresp:
                return aresp
        if not req.environ.get('swift_owner', False):
            for key in ('x-container-read', 'x-container-write',
                        'x-container-sync-key', 'x-container-sync-to'):
                if key in resp.headers:
                    del resp.headers[key]
        return resp
コード例 #16
0
ファイル: test_base.py プロジェクト: vefimova/swift
 def test_get_container_info_env(self):
     cache_key = get_container_memcache_key("account", "cont")
     env_key = 'swift.%s' % cache_key
     req = Request.blank("/v1/account/cont",
                         environ={env_key: {'bytes': 3867},
                                  'swift.cache': FakeCache({})})
     resp = get_container_info(req.environ, 'xxx')
     self.assertEquals(resp['bytes'], 3867)
コード例 #17
0
ファイル: ratelimit.py プロジェクト: TheUtils/swift
 def get_container_size(self, account_name, container_name):
     rv = 0
     memcache_key = get_container_memcache_key(account_name, container_name)
     container_info = self.memcache_client.get(memcache_key)
     if isinstance(container_info, dict):
         rv = container_info.get('object_count',
                                 container_info.get('container_size', 0))
     return rv
コード例 #18
0
ファイル: test_base.py プロジェクト: 10389030/swift
 def test_get_container_info_env(self):
     cache_key = get_container_memcache_key("account", "cont")
     env_key = 'swift.%s' % cache_key
     req = Request.blank("/v1/account/cont",
                         environ={env_key: {'bytes': 3867},
                                  'swift.cache': FakeCache({})})
     resp = get_container_info(req.environ, 'xxx')
     self.assertEquals(resp['bytes'], 3867)
コード例 #19
0
    def test_get_ratelimitable_key_tuples(self):
        current_rate = 13
        conf_dict = {
            'account_ratelimit': current_rate,
            'container_ratelimit_3': 200
        }
        fake_memcache = FakeMemcache()
        fake_memcache.store[get_container_memcache_key('a', 'c')] = \
            {'object_count': '5'}
        the_app = ratelimit.filter_factory(conf_dict)(FakeApp())
        the_app.memcache_client = fake_memcache
        req = lambda: None
        req.environ = {'swift.cache': fake_memcache, 'PATH_INFO': '/v1/a/c/o'}
        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        lambda *args, **kwargs: {}):
            req.method = 'DELETE'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', None,
                                                         None)), 0)
            req.method = 'PUT'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', None)),
                1)
            req.method = 'DELETE'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', None)),
                1)
            req.method = 'GET'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', 'o')),
                0)
            req.method = 'PUT'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', 'o')),
                1)

        def get_fake_ratelimit(*args, **kwargs):
            return {'sysmeta': {'global-write-ratelimit': 10}}

        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        get_fake_ratelimit):
            req.method = 'PUT'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', None)),
                2)
            self.assertEquals(
                the_app.get_ratelimitable_key_tuples(req, 'a', 'c', None)[1],
                ('ratelimit/global-write/a', 10))

        def get_fake_ratelimit(*args, **kwargs):
            return {'sysmeta': {'global-write-ratelimit': 'notafloat'}}

        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        get_fake_ratelimit):
            req.method = 'PUT'
            self.assertEquals(
                len(the_app.get_ratelimitable_key_tuples(req, 'a', 'c', None)),
                1)
コード例 #20
0
ファイル: ratelimit.py プロジェクト: 674009287/swift
 def get_container_size(self, account_name, container_name):
     rv = 0
     memcache_key = get_container_memcache_key(account_name,
                                               container_name)
     container_info = self.memcache_client.get(memcache_key)
     if isinstance(container_info, dict):
         rv = container_info.get(
             'object_count', container_info.get('container_size', 0))
     return rv
コード例 #21
0
 def test_ratelimit_old_memcache_format(self):
     current_rate = 13
     conf_dict = {'account_ratelimit': current_rate,
                  'container_ratelimit_3': 200}
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'container_size': 5}
     the_app = ratelimit.RateLimitMiddleware(None, conf_dict,
                                             logger=FakeLogger())
     the_app.memcache_client = fake_memcache
     tuples = the_app.get_ratelimitable_key_tuples('PUT', 'a', 'c', 'o')
     self.assertEquals(tuples, [('ratelimit/a/c', 200.0)])
コード例 #22
0
ファイル: test_ratelimit.py プロジェクト: 10389030/swift
    def test_get_ratelimitable_key_tuples(self):
        current_rate = 13
        conf_dict = {'account_ratelimit': current_rate,
                     'container_ratelimit_3': 200}
        fake_memcache = FakeMemcache()
        fake_memcache.store[get_container_memcache_key('a', 'c')] = \
            {'object_count': '5'}
        the_app = ratelimit.RateLimitMiddleware(None, conf_dict,
                                                logger=FakeLogger())
        the_app.memcache_client = fake_memcache
        req = lambda: None
        req.environ = {}
        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        lambda *args, **kwargs: {}):
            req.method = 'DELETE'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', None, None)), 0)
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 1)
            req.method = 'DELETE'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 1)
            req.method = 'GET'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', 'o')), 0)
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', 'o')), 1)

        def get_fake_ratelimit(*args, **kwargs):
            return {'sysmeta': {'global-write-ratelimit': 10}}

        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        get_fake_ratelimit):
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 2)
            self.assertEquals(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)[1], ('ratelimit/global-write/a', 10))

        def get_fake_ratelimit(*args, **kwargs):
            return {'sysmeta': {'global-write-ratelimit': 'notafloat'}}

        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        get_fake_ratelimit):
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 1)
コード例 #23
0
ファイル: test_ratelimit.py プロジェクト: bouncestorage/swift
 def test_ratelimit_old_memcache_format(self):
     current_rate = 13
     conf_dict = {'account_ratelimit': current_rate,
                  'container_ratelimit_3': 200}
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'container_size': 5}
     the_app = ratelimit.filter_factory(conf_dict)(FakeApp())
     the_app.memcache_client = fake_memcache
     req = lambda: None
     req.method = 'PUT'
     req.environ = {'PATH_INFO': '/v1/a/c/o', 'swift.cache': fake_memcache}
     with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                     lambda *args, **kwargs: {}):
         tuples = the_app.get_ratelimitable_key_tuples(req, 'a', 'c', 'o')
         self.assertEquals(tuples, [('ratelimit/a/c', 200.0)])
コード例 #24
0
ファイル: container.py プロジェクト: missall/swift
 def PUT(self, req):
     """HTTP PUT request handler."""
     start_time = time.time()
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         self.app.logger.increment('errors')
         return error_response
     if len(self.container_name) > MAX_CONTAINER_NAME_LENGTH:
         resp = HTTPBadRequest(request=req)
         resp.body = 'Container name length of %d longer than %d' % \
                     (len(self.container_name), MAX_CONTAINER_NAME_LENGTH)
         self.app.logger.increment('errors')
         return resp
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if self.app.max_containers_per_account > 0 and \
             container_count >= self.app.max_containers_per_account and \
             self.account_name not in self.app.max_containers_whitelist:
         resp = HTTPForbidden(request=req)
         resp.body = 'Reached container limit of %s' % \
                     self.app.max_containers_per_account
         return resp
     if not accounts:
         self.app.logger.timing_since('PUT.timing', start_time)
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = []
     for account in accounts:
         nheaders = {'X-Timestamp': normalize_timestamp(time.time()),
                     'x-trans-id': self.trans_id,
                     'X-Account-Host': '%(ip)s:%(port)s' % account,
                     'X-Account-Partition': account_partition,
                     'X-Account-Device': account['device'],
                     'Connection': 'close'}
         self.transfer_headers(req.headers, nheaders)
         headers.append(nheaders)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
             container_partition, 'PUT', req.path_info, headers)
     self.app.logger.timing_since('PUT.timing', start_time)
     return resp
コード例 #25
0
 def test_ratelimit_old_memcache_format(self):
     current_rate = 13
     conf_dict = {'account_ratelimit': current_rate,
                  'container_ratelimit_3': 200}
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'container_size': 5}
     the_app = ratelimit.RateLimitMiddleware(None, conf_dict,
                                             logger=FakeLogger())
     the_app.memcache_client = fake_memcache
     req = lambda: None
     req.method = 'PUT'
     req.environ = {}
     with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                     lambda *args, **kwargs: {}):
         tuples = the_app.get_ratelimitable_key_tuples(req, 'a', 'c', 'o')
         self.assertEquals(tuples, [('ratelimit/a/c', 200.0)])
コード例 #26
0
ファイル: container.py プロジェクト: waiterZen/swift
 def PUT(self, req):
     """HTTP PUT request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     if len(self.container_name) > MAX_CONTAINER_NAME_LENGTH:
         resp = HTTPBadRequest(request=req)
         resp.body = 'Container name length of %d longer than %d' % \
                     (len(self.container_name), MAX_CONTAINER_NAME_LENGTH)
         return resp
     account_partition, accounts, container_count = \
         self.account_info(self.account_name,
                           autocreate=self.app.account_autocreate)
     if self.app.max_containers_per_account > 0 and \
             container_count >= self.app.max_containers_per_account and \
             self.account_name not in self.app.max_containers_whitelist:
         resp = HTTPForbidden(request=req)
         resp.body = 'Reached container limit of %s' % \
                     self.app.max_containers_per_account
         return resp
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = []
     for account in accounts:
         nheaders = {
             'X-Timestamp': normalize_timestamp(time.time()),
             'x-trans-id': self.trans_id,
             'X-Account-Host': '%(ip)s:%(port)s' % account,
             'X-Account-Partition': account_partition,
             'X-Account-Device': account['device'],
             'Connection': 'close'
         }
         self.transfer_headers(req.headers, nheaders)
         headers.append(nheaders)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(req, self.app.container_ring,
                               container_partition, 'PUT', req.path_info,
                               headers)
     return resp
コード例 #27
0
 def test_ratelimit_old_memcache_format(self):
     current_rate = 13
     conf_dict = {
         'account_ratelimit': current_rate,
         'container_ratelimit_3': 200
     }
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'container_size': 5}
     the_app = ratelimit.filter_factory(conf_dict)(FakeApp())
     the_app.memcache_client = fake_memcache
     req = lambda: None
     req.method = 'PUT'
     req.environ = {'PATH_INFO': '/v1/a/c/o', 'swift.cache': fake_memcache}
     with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                     lambda *args, **kwargs: {}):
         tuples = the_app.get_ratelimitable_key_tuples(req, 'a', 'c', 'o')
         self.assertEqual(tuples, [('ratelimit/a/c', 200.0)])
コード例 #28
0
 def test_get_ratelimitable_key_tuples(self):
     current_rate = 13
     conf_dict = {'account_ratelimit': current_rate,
                  'container_ratelimit_3': 200}
     fake_memcache = FakeMemcache()
     fake_memcache.store[get_container_memcache_key('a', 'c')] = \
         {'count': 5}
     the_app = ratelimit.RateLimitMiddleware(None, conf_dict,
                                             logger=FakeLogger())
     the_app.memcache_client = fake_memcache
     self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                 'DELETE', 'a', None, None)), 0)
     self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                 'PUT', 'a', 'c', None)), 1)
     self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                 'DELETE', 'a', 'c', None)), 1)
     self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                 'GET', 'a', 'c', 'o')), 0)
     self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                 'PUT', 'a', 'c', 'o')), 1)
コード例 #29
0
ファイル: container.py プロジェクト: zhanghua/swift
 def POST(self, req):
     """HTTP POST request handler."""
     error_response = \
         self.clean_acls(req) or check_metadata(req, 'container')
     if error_response:
         return error_response
     account_partition, accounts, container_count = \
         self.account_info(self.account_name)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = self.generate_request_headers(req, transfer=True)
     if self.app.memcache:
         self.app.memcache.delete(get_container_memcache_key(
             self.account_name, self.container_name))
     resp = self.make_requests(
         req, self.app.container_ring, container_partition, 'POST',
         req.path_info, [headers] * len(containers))
     return resp
コード例 #30
0
ファイル: container.py プロジェクト: zhanghua/swift
 def DELETE(self, req):
     """HTTP DELETE request handler."""
     account_partition, accounts, container_count = \
         self.account_info(self.account_name, req)
     if not accounts:
         return HTTPNotFound(request=req)
     container_partition, containers = self.app.container_ring.get_nodes(
         self.account_name, self.container_name)
     headers = self._backend_requests(req, len(containers),
                                      account_partition, accounts)
     if self.app.memcache:
         cache_key = get_container_memcache_key(self.account_name,
                                                self.container_name)
         self.app.memcache.delete(cache_key)
     resp = self.make_requests(
         req, self.app.container_ring, container_partition, 'DELETE',
         req.path_info, headers)
     # Indicates no server had the container
     if resp.status_int == HTTP_ACCEPTED:
         return HTTPNotFound(request=req)
     return resp
コード例 #31
0
    def test_ratelimit_max_rate_double_container_listing(self):
        global time_ticker
        global time_override
        current_rate = 2
        conf_dict = {
            'container_listing_ratelimit_0': current_rate,
            'clock_accuracy': 100,
            'max_sleep_time_seconds': 1
        }
        self.test_ratelimit = ratelimit.filter_factory(conf_dict)(FakeApp())
        ratelimit.http_connect = mock_http_connect(204)
        self.test_ratelimit.log_sleep_time_seconds = .00001
        req = Request.blank('/v/a/c')
        req.method = 'GET'
        req.environ['swift.cache'] = FakeMemcache()
        req.environ['swift.cache'].set(get_container_memcache_key('a', 'c'),
                                       {'container_size': 1})

        time_override = [0, 0, 0, 0, None]
        # simulates 4 requests coming in at same time, then sleeping
        r = self.test_ratelimit(req.environ, start_response)
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], 'Slow down')
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], 'Slow down')
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], '204 No Content')
        mc = self.test_ratelimit.memcache_client
        try:
            self.test_ratelimit.memcache_client = None
            self.assertEquals(
                self.test_ratelimit.handle_ratelimit(req, 'n', 'c', None),
                None)
        finally:
            self.test_ratelimit.memcache_client = mc
コード例 #32
0
    def test_ratelimit_max_rate_double_container_listing(self):
        global time_ticker
        global time_override
        current_rate = 2
        conf_dict = {'container_listing_ratelimit_0': current_rate,
                     'clock_accuracy': 100,
                     'max_sleep_time_seconds': 1}
        self.test_ratelimit = ratelimit.filter_factory(conf_dict)(FakeApp())
        ratelimit.http_connect = mock_http_connect(204)
        self.test_ratelimit.log_sleep_time_seconds = .00001
        req = Request.blank('/v/a/c')
        req.method = 'GET'
        req.environ['swift.cache'] = FakeMemcache()
        req.environ['swift.cache'].set(
            get_container_memcache_key('a', 'c'),
            {'container_size': 1})

        time_override = [0, 0, 0, 0, None]
        # simulates 4 requests coming in at same time, then sleeping
        r = self.test_ratelimit(req.environ, start_response)
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], 'Slow down')
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], 'Slow down')
        mock_sleep(.1)
        r = self.test_ratelimit(req.environ, start_response)
        self.assertEquals(r[0], '204 No Content')
        mc = self.test_ratelimit.memcache_client
        try:
            self.test_ratelimit.memcache_client = None
            self.assertEquals(
                self.test_ratelimit.handle_ratelimit(req, 'n', 'c', None),
                None)
        finally:
            self.test_ratelimit.memcache_client = mc
コード例 #33
0
ファイル: test_ratelimit.py プロジェクト: bouncestorage/swift
    def test_get_ratelimitable_key_tuples(self):
        current_rate = 13
        conf_dict = {'account_ratelimit': current_rate,
                     'container_ratelimit_3': 200}
        fake_memcache = FakeMemcache()
        fake_memcache.store[get_container_memcache_key('a', 'c')] = \
            {'object_count': '5'}
        the_app = ratelimit.filter_factory(conf_dict)(FakeApp())
        the_app.memcache_client = fake_memcache
        req = lambda: None
        req.environ = {'swift.cache': fake_memcache, 'PATH_INFO': '/v1/a/c/o'}
        with mock.patch('swift.common.middleware.ratelimit.get_account_info',
                        lambda *args, **kwargs: {}):
            req.method = 'DELETE'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', None, None)), 0)
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 1)
            req.method = 'DELETE'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', None)), 1)
            req.method = 'GET'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', 'o')), 0)
            req.method = 'PUT'
            self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
                req, 'a', 'c', 'o')), 1)

        req.method = 'PUT'
        self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
            req, 'a', 'c', None, global_ratelimit=10)), 2)
        self.assertEquals(the_app.get_ratelimitable_key_tuples(
            req, 'a', 'c', None, global_ratelimit=10)[1],
            ('ratelimit/global-write/a', 10))

        req.method = 'PUT'
        self.assertEquals(len(the_app.get_ratelimitable_key_tuples(
            req, 'a', 'c', None, global_ratelimit='notafloat')), 1)
コード例 #34
0
ファイル: container.py プロジェクト: waiterZen/swift
    def GETorHEAD(self, req):
        """Handler for HTTP GET/HEAD requests."""
        if not self.account_info(self.account_name)[1]:
            return HTTPNotFound(request=req)
        part, nodes = self.app.container_ring.get_nodes(
            self.account_name, self.container_name)
        shuffle(nodes)
        resp = self.GETorHEAD_base(req, _('Container'), part, nodes,
                                   req.path_info, len(nodes))

        if self.app.memcache:
            # set the memcache container size for ratelimiting
            cache_key = get_container_memcache_key(self.account_name,
                                                   self.container_name)
            self.app.memcache.set(
                cache_key, {
                    'status': resp.status_int,
                    'read_acl': resp.headers.get('x-container-read'),
                    'write_acl': resp.headers.get('x-container-write'),
                    'sync_key': resp.headers.get('x-container-sync-key'),
                    'count': resp.headers.get('x-container-object-count'),
                    'bytes': resp.headers.get('x-container-bytes-used'),
                    'versions': resp.headers.get('x-versions-location')
                },
                timeout=self.app.recheck_container_existence)

        if 'swift.authorize' in req.environ:
            req.acl = resp.headers.get('x-container-read')
            aresp = req.environ['swift.authorize'](req)
            if aresp:
                return aresp
        if not req.environ.get('swift_owner', False):
            for key in ('x-container-read', 'x-container-write',
                        'x-container-sync-key', 'x-container-sync-to'):
                if key in resp.headers:
                    del resp.headers[key]
        return resp
コード例 #35
0
ファイル: quota.py プロジェクト: NewpTone/StackLab-swift
    def _get_container_meta(self, env, version, account, container,
                            memcache_client):
        """
        Get metadata of account.

        :param env: The WSGI environment
        :param version: The api version in PATH_INFO
        :param account: The name of account
        :param container: The name of container
        :return: tuple of (container_usage, object_count) or (None, None)
        """
        value = None
        container_usage = None
        object_count = None
        res = [None, None, None]
        result_code = None

        def _start_response(response_status, response_headers, exc_info=None):
            res[0] = response_status
            res[1] = response_headers
            res[2] = exc_info
        # get container_usage and object_count
        container_key = get_container_memcache_key(account, container)
        if memcache_client:
            value = memcache_client.get(container_key)
        if value:
            self.logger.debug('value from mc: %s' % (value))
            if not isinstance(value, dict):
                result_code = value
            else:
                result_code = value.get('status')
        if is_success(result_code):
            # get from memcached
            container_usage = int(value.get('container_usage') or 0)
            object_count = int(value.get('container_size') or 0)
            return container_usage, object_count
        else:
            temp_env = self._get_escalated_env(env)
            temp_env['REQUEST_METHOD'] = 'HEAD'
            temp_env['PATH_INFO'] = '/%s/%s/%s' % (version, account, container)
            resp = self.app(temp_env, _start_response)
            self.logger.debug(
                'value form container-server status[%s] header[%s]' % (res[0],
                res[1]))
            result_code = self._get_status_int(res[0])
            if is_success(result_code):
                headers = dict(res[1])
                container_usage = int(
                    headers.get('x-container-bytes-used') or 0)
                object_count = int(
                    headers.get('x-container-object-count') or 0)
                read_acl = headers.get('x-container-read') or ''
                write_acl = headers.get('x-container-write') or ''
                sync_key = headers.get('x-container-sync-key') or ''
                container_version = headers.get('x-versions-location') or ''
                if memcache_client:
                    memcache_client.set(
                        container_key,
                        {
                            'status': result_code,
                            'read_acl': read_acl,
                            'write_acl': write_acl,
                            'sync_key': sync_key,
                            'container_size': object_count,
                            'versions': container_version,
                            'container_usage': container_usage
                        },
                        timeout=self.cache_timeout
                    )
                return container_usage, object_count
            else:
                return None, None
コード例 #36
0
ファイル: test_base.py プロジェクト: r0mik/swift
 def test_get_container_info_env(self):
     cache_key = get_container_memcache_key("account", "cont")
     env_key = "swift.%s" % cache_key
     req = Request.blank("/v1/account/cont", environ={env_key: {"bytes": 3867}, "swift.cache": FakeCache({})})
     resp = get_container_info(req.environ, "xxx")
     self.assertEquals(resp["bytes"], 3867)