コード例 #1
0
ファイル: autocontainerbase.py プロジェクト: jfsmig/oio-swift
    def _extract_path(self, path):
        account = self.account
        # Remove leading '/' to be consistent with split_path()
        obj = path[1:]
        container = None

        try:
            if self.strip_v1:
                version, tail = split_path('/' + obj, 1, 2, True)
                if version in ('v1', 'v1.0'):
                    obj = tail

            if obj is not None and self.account_first:
                account, tail = split_path('/' + obj, 1, 2, True)
                obj = tail

            if obj is not None and self.swift3_compat:
                container, tail = split_path('/' + obj, 1, 2, True)
                obj = tail

            # Do not yield an empty object name
            if not obj:
                obj = None
        except ValueError:
            raise HTTPBadRequest()

        return account, container, obj
コード例 #2
0
ファイル: request.py プロジェクト: tipabu/swift3
    def check_copy_source(self, app):
        """
        check_copy_source checks the copy source existence and if copying an
        object to itself, for illegal request parameters
        """
        if 'X-Amz-Copy-Source' in self.headers:
            src_path = unquote(self.headers['X-Amz-Copy-Source'])
            src_path = src_path if src_path.startswith('/') else \
                ('/' + src_path)
            src_bucket, src_obj = split_path(src_path, 0, 2, True)
            headers = swob.HeaderKeyDict()
            headers.update(self._copy_source_headers())

            src_resp = self.get_response(app, 'HEAD', src_bucket, src_obj,
                                         headers=headers)
            if src_resp.status_int == 304:  # pylint: disable-msg=E1101
                raise PreconditionFailed()

            self.headers['X-Amz-Copy-Source'] = \
                '/' + self.headers['X-Amz-Copy-Source'].lstrip('/')
            source_container, source_obj = \
                split_path(self.headers['X-Amz-Copy-Source'], 1, 2, True)

            if (self.container_name == source_container and
                    self.object_name == source_obj):
                if self.headers.get('x-amz-metadata-directive',
                                    'COPY') == 'COPY':
                    raise InvalidRequest("This copy request is illegal "
                                         "because it is trying to copy an "
                                         "object to itself without "
                                         "changing the object's metadata, "
                                         "storage class, website redirect "
                                         "location or encryption "
                                         "attributes.")
コード例 #3
0
ファイル: test_utils.py プロジェクト: AsylumCorp/swift
 def test_split_path(self):
     """ Test swift.common.utils.split_account_path """
     self.assertRaises(ValueError, utils.split_path, '')
     self.assertRaises(ValueError, utils.split_path, '/')
     self.assertRaises(ValueError, utils.split_path, '//')
     self.assertEquals(utils.split_path('/a'), ['a'])
     self.assertRaises(ValueError, utils.split_path, '//a')
     self.assertEquals(utils.split_path('/a/'), ['a'])
     self.assertRaises(ValueError, utils.split_path, '/a/c')
     self.assertRaises(ValueError, utils.split_path, '//c')
     self.assertRaises(ValueError, utils.split_path, '/a/c/')
     self.assertRaises(ValueError, utils.split_path, '/a//')
     self.assertRaises(ValueError, utils.split_path, '/a', 2)
     self.assertRaises(ValueError, utils.split_path, '/a', 2, 3)
     self.assertRaises(ValueError, utils.split_path, '/a', 2, 3, True)
     self.assertEquals(utils.split_path('/a/c', 2), ['a', 'c'])
     self.assertEquals(utils.split_path('/a/c/o', 3), ['a', 'c', 'o'])
     self.assertRaises(ValueError, utils.split_path, '/a/c/o/r', 3, 3)
     self.assertEquals(utils.split_path('/a/c/o/r', 3, 3, True),
                       ['a', 'c', 'o/r'])
     self.assertEquals(utils.split_path('/a/c', 2, 3, True),
                       ['a', 'c', None])
     self.assertRaises(ValueError, utils.split_path, '/a', 5, 4)
     self.assertEquals(utils.split_path('/a/c/', 2), ['a', 'c'])
     self.assertEquals(utils.split_path('/a/c/', 2, 3), ['a', 'c', ''])
     try:
         utils.split_path('o\nn e', 2)
     except ValueError, err:
         self.assertEquals(str(err), 'Invalid path: o%0An%20e')
コード例 #4
0
ファイル: account_quotas.py プロジェクト: sun7shines/Cloudfs
    def __call__(self, request):
       
        if request.method not in ("PUT","COPY"):
            return self.app

        try:
            split_path(request.path,2, 4, rest_with_last=True)
        except ValueError:
            return self.app

        new_quota = request.headers.get('X-Account-Meta-Quota-Bytes')
        if new_quota:
            if not new_quota.isdigit():
                return jresponse('-1', 'bad request', request, 400)
            return self.app

        account_info = get_account_info(request.environ, self.app)
        new_size = int(account_info['bytes']) + (request.content_length or 0)
        quota = int(account_info['meta'].get('quota-bytes', -1))

        if 0 <= quota < new_size:
            respbody='Your request is too large.'
            return jresponse('-1', respbody, request,413)

        return self.app
コード例 #5
0
ファイル: base.py プロジェクト: morucci/swift
    def GETorHEAD_base(self, req, server_type, ring, partition, path):
        """
        Base handler for HTTP GET or HEAD requests.

        :param req: swob.Request object
        :param server_type: server type
        :param ring: the ring to obtain nodes from
        :param partition: partition
        :param path: path for the request
        :returns: swob.Response object
        """
        backend_headers = self.generate_request_headers(
            req, additional=req.headers)

        handler = GetOrHeadHandler(self.app, req, server_type, ring,
                                   partition, path, backend_headers)
        res = handler.get_working_response(req)

        if not res:
            res = self.best_response(
                req, handler.statuses, handler.reasons, handler.bodies,
                '%s %s' % (server_type, req.method),
                headers=handler.source_headers)
        try:
            (account, container) = split_path(req.path_info, 1, 2)
            _set_info_cache(self.app, req.environ, account, container, res)
        except ValueError:
            pass
        try:
            (account, container, obj) = split_path(req.path_info, 3, 3, True)
            _set_object_info_cache(self.app, req.environ, account,
                                   container, obj, res)
        except ValueError:
            pass
        return res
コード例 #6
0
ファイル: test_utils.py プロジェクト: colecrawford/swift
 def test_split_path(self):
     """ Test swift.common.utils.split_account_path """
     self.assertRaises(ValueError, utils.split_path, "")
     self.assertRaises(ValueError, utils.split_path, "/")
     self.assertRaises(ValueError, utils.split_path, "//")
     self.assertEquals(utils.split_path("/a"), ["a"])
     self.assertRaises(ValueError, utils.split_path, "//a")
     self.assertEquals(utils.split_path("/a/"), ["a"])
     self.assertRaises(ValueError, utils.split_path, "/a/c")
     self.assertRaises(ValueError, utils.split_path, "//c")
     self.assertRaises(ValueError, utils.split_path, "/a/c/")
     self.assertRaises(ValueError, utils.split_path, "/a//")
     self.assertRaises(ValueError, utils.split_path, "/a", 2)
     self.assertRaises(ValueError, utils.split_path, "/a", 2, 3)
     self.assertRaises(ValueError, utils.split_path, "/a", 2, 3, True)
     self.assertEquals(utils.split_path("/a/c", 2), ["a", "c"])
     self.assertEquals(utils.split_path("/a/c/o", 3), ["a", "c", "o"])
     self.assertRaises(ValueError, utils.split_path, "/a/c/o/r", 3, 3)
     self.assertEquals(utils.split_path("/a/c/o/r", 3, 3, True), ["a", "c", "o/r"])
     self.assertEquals(utils.split_path("/a/c", 2, 3, True), ["a", "c", None])
     self.assertRaises(ValueError, utils.split_path, "/a", 5, 4)
     self.assertEquals(utils.split_path("/a/c/", 2), ["a", "c"])
     self.assertEquals(utils.split_path("/a/c/", 2, 3), ["a", "c", ""])
     try:
         utils.split_path("o\nn e", 2)
     except ValueError, err:
         self.assertEquals(str(err), "Invalid path: o%0An%20e")
    def __call__(self, env, start_response):
        """
        If called with header X-Pid-Create and Method PUT become active and
        create a PID and store it with the object
        :param env: request environment
        :param start_response: function that we call when creating response
        :return:
        """
        self.start_response = start_response
        request = Request(env)
        if request.method == 'PUT':
            if 'X-Pid-Create' in list(request.headers.keys()):
                url = '{}{}'.format(request.host_url, request.path_info)
                if 'X-Pid-Parent' in list(request.headers.keys()):
                    parent = request.headers['X-Pid-Parent']
                else:
                    parent = None
                success, pid = create_pid(object_url=url,
                                          api_url=self.conf.get('api_url'),
                                          username=self.conf.get('username'),
                                          password=self.conf.get('password'),
                                          parent=parent)
                if success:
                    self.logger.info('Created a PID for {}'.format(url))
                    request.headers['X-Object-Meta-PID'] = pid
                    response = PersistentIdentifierResponse(
                        pid=pid,
                        add_checksum=self.add_checksum,
                        username=self.conf.get('username'),
                        password=self.conf.get('password'),
                        start_response=start_response,
                        logger=self.logger)
                    return self.app(env, response.finish_response)
                else:
                    self.logger.error('Unable to create  a PID for {},'
                                      'because of {}'.format(url, pid))
                    return Response(
                        status=502,
                        body='Could not contact PID API')(env, start_response)
        elif request.method in ['GET', 'HEAD']:
            # only modify response if we have a request for a object
            try:
                split_path(request.path_info, 4, 4, True)
            except ValueError:
                return self.app(env, start_response)

            object_metadata = get_object_info(
                env=request.environ,
                app=self.app,
                swift_source='PersistentIdentifierMiddleware')['meta']
            if 'pid' in object_metadata.keys():
                response = PersistentIdentifierResponse(
                    pid='',
                    add_checksum='',
                    username='',
                    password='',
                    start_response=start_response,
                    logger=self.logger)
                return self.app(env, response.finish_response_pidurl)
        return self.app(env, start_response)
コード例 #8
0
    def __call__(self, env, start_response):
        """
        Main hook into the WSGI paste.deploy filter/app pipeline.

        :param env: The WSGI environment dict.
        :param start_response: The WSGI start_response hook.
        """
        try:
            (version, account, container, obj) = \
                split_path(env['PATH_INFO'], 2, 4, True)
        except ValueError:
            return self.app(env, start_response)

        if not self._cache:
            self._cache = cache_from_env(env)

        # Don't handle non-GET requests.
        if env['REQUEST_METHOD'] not in ('HEAD', 'GET'):

            # flush cache if we expect the container metadata being changed.
            if container and not obj and self._cache:
                memcache_key = 'better_static/%s/%s' % (account, container)
                self._cache.delete(memcache_key)

            return self.app(env, start_response)

        # If non-html was explicitly requested, don't bother trying to format
        # the html
        params = urlparse.parse_qs(env.get('QUERY_STRING', ''))

        if 'format' in params and params['format'] != ['html']:
            return self.app(env, start_response)

        context = Context(self, env, account, container, obj)
        return context(env, start_response)
コード例 #9
0
ファイル: kerbauth.py プロジェクト: prashanthpai/swiftkrbauth
    def handle_get_token(self, req):
        """
        Handles the various `request for token and service end point(s)` calls.
        There are various formats to support the various auth servers in the
        past. Examples::

            GET <auth-prefix>/v1/<act>/auth
            GET <auth-prefix>/auth
            GET <auth-prefix>/v1.0

        All formats require GSS (Kerberos) authentication.

        On successful authentication, the response will have X-Auth-Token
        set to the token to use with Swift.

        :param req: The swob.Request to process.
        :returns: swob.Response, 2xx on success with data set as explained
                  above.
        """
        # Validate the request info
        try:
            pathsegs = split_path(req.path_info, 1, 3, True)
        except ValueError:
            self.logger.increment('errors')
            return HTTPNotFound(request=req)
        if not ((pathsegs[0] == 'v1' and pathsegs[2] == 'auth')
                or pathsegs[0] in ('auth', 'v1.0')):
                    return HTTPBadRequest(request=req)

        return HTTPSeeOther(location=self.ext_authentication_url)
コード例 #10
0
ファイル: staticweb.py プロジェクト: CiscoAS/swift
    def __call__(self, env, start_response):
        """
        Main hook into the WSGI paste.deploy filter/app pipeline.

        :param env: The WSGI environment dict.
        :param start_response: The WSGI start_response hook.
        """
        env['staticweb.start_time'] = time.time()
        try:
            (version, account, container, obj) = \
                split_path(env['PATH_INFO'], 2, 4, True)
        except ValueError:
            return self.app(env, start_response)
        if env['REQUEST_METHOD'] in ('PUT', 'POST') and container and not obj:
            memcache_client = cache_from_env(env)
            if memcache_client:
                memcache_key = \
                    '/staticweb/%s/%s/%s' % (version, account, container)
                memcache_client.delete(memcache_key)
            return self.app(env, start_response)
        if env['REQUEST_METHOD'] not in ('HEAD', 'GET'):
            return self.app(env, start_response)
        if env.get('REMOTE_USER') and \
                not config_true_value(env.get('HTTP_X_WEB_MODE', 'f')):
            return self.app(env, start_response)
        if not container:
            return self.app(env, start_response)
        context = _StaticWebContext(self, version, account, container, obj)
        if obj:
            return context.handle_object(env, start_response)
        return context.handle_container(env, start_response)
コード例 #11
0
ファイル: reconciler.py プロジェクト: 701/swift
def parse_raw_obj(obj_info):
    """
    Translate a reconciler container listing entry to a dictionary
    containing the parts of the misplaced object queue entry.

    :param obj_info: an entry in an a container listing with the
                     required keys: name, content_type, and hash

    :returns: a queue entry dict with the keys: q_policy_index, account,
              container, obj, q_op, q_ts, q_record, and path
    """
    raw_obj_name = obj_info['name'].encode('utf-8')

    policy_index, obj_name = raw_obj_name.split(':', 1)
    q_policy_index = int(policy_index)
    account, container, obj = split_path(obj_name, 3, 3, rest_with_last=True)
    try:
        q_op = {
            'application/x-put': 'PUT',
            'application/x-delete': 'DELETE',
        }[obj_info['content_type']]
    except KeyError:
        raise ValueError('invalid operation type %r' %
                         obj_info.get('content_type', None))
    return {
        'q_policy_index': q_policy_index,
        'account': account,
        'container': container,
        'obj': obj,
        'q_op': q_op,
        'q_ts': Timestamp(obj_info['hash']),
        'q_record': last_modified_date_to_timestamp(
            obj_info['last_modified']),
        'path': '/%s/%s/%s' % (account, container, obj)
    }
コード例 #12
0
ファイル: swift_middleware.py プロジェクト: c08007/ceilometer
    def publish_sample(self, env, bytes_received, bytes_sent):
        req = REQUEST.Request(env)
        try:
            version, account, container, obj = utils.split_path(req.path, 2,
                                                                4, True)
        except ValueError:
            return
        now = timeutils.utcnow().isoformat()

        resource_metadata = {
            "path": req.path,
            "version": version,
            "container": container,
            "object": obj,
        }

        for header in self.metadata_headers:
            if header.upper() in req.headers:
                resource_metadata['http_header_%s' % header] = req.headers.get(
                    header.upper())

        with self.pipeline_manager.publisher(
                context.get_admin_context()) as publisher:
            if bytes_received:
                publisher([sample.Sample(
                    name='storage.objects.incoming.bytes',
                    type=sample.TYPE_DELTA,
                    unit='B',
                    volume=bytes_received,
                    user_id=env.get('HTTP_X_USER_ID'),
                    project_id=env.get('HTTP_X_TENANT_ID'),
                    resource_id=account.partition('AUTH_')[2],
                    timestamp=now,
                    resource_metadata=resource_metadata)])

            if bytes_sent:
                publisher([sample.Sample(
                    name='storage.objects.outgoing.bytes',
                    type=sample.TYPE_DELTA,
                    unit='B',
                    volume=bytes_sent,
                    user_id=env.get('HTTP_X_USER_ID'),
                    project_id=env.get('HTTP_X_TENANT_ID'),
                    resource_id=account.partition('AUTH_')[2],
                    timestamp=now,
                    resource_metadata=resource_metadata)])

            # publish the event for each request
            # request method will be recorded in the metadata
            resource_metadata['method'] = req.method.lower()
            publisher([sample.Sample(
                name='storage.api.request',
                type=sample.TYPE_DELTA,
                unit='request',
                volume=1,
                user_id=env.get('HTTP_X_USER_ID'),
                project_id=env.get('HTTP_X_TENANT_ID'),
                resource_id=account.partition('AUTH_')[2],
                timestamp=now,
                resource_metadata=resource_metadata)])
コード例 #13
0
ファイル: __init__.py プロジェクト: mahak/swift
    def request_with_policy(method, url, body=None, headers={}):
        version, account, container, obj = split_path(url, 1, 4, True)
        if policy_specified and method == 'PUT' and container and not obj \
                and 'X-Storage-Policy' not in headers:
            headers['X-Storage-Policy'] = policy_specified

        return orig_request(method, url, body, headers)
コード例 #14
0
ファイル: staticweb.py プロジェクト: OpenStack-Kha/swift
    def __call__(self, env, start_response):
        """
        Main hook into the WSGI paste.deploy filter/app pipeline.

        :param env: The WSGI environment dict.
        :param start_response: The WSGI start_response hook.
        """
        env['staticweb.start_time'] = time.time()
        try:
            (self.version, self.account, self.container, self.obj) = \
                split_path(env['PATH_INFO'], 2, 4, True)
        except ValueError:
            return self.app(env, start_response)
        memcache_client = cache_from_env(env)
        if memcache_client:
            if env['REQUEST_METHOD'] in ('PUT', 'POST'):
                if not self.obj and self.container:
                    memcache_key = '/staticweb/%s/%s/%s' % \
                        (self.version, self.account, self.container)
                    memcache_client.delete(memcache_key)
                return self.app(env, start_response)
        if (env['REQUEST_METHOD'] not in ('HEAD', 'GET') or
            (env.get('REMOTE_USER') and
             env.get('HTTP_X_WEB_MODE', 'f').lower() not in TRUE_VALUES) or
            (not env.get('REMOTE_USER') and
             env.get('HTTP_X_WEB_MODE', 't').lower() not in TRUE_VALUES)):
            return self.app(env, start_response)
        if self.obj:
            return self._handle_object(env, start_response)
        elif self.container:
            return self._handle_container(env, start_response)
        return self.app(env, start_response)
コード例 #15
0
ファイル: batch.py プロジェクト: sun3shines/swift-1.7.4
    def __call__(self, req):
         
        container = split_path(req.path, 1, 4, True)[2]
        if 'batch' == container:
            return self.handle_batch(req)

        return self.app
コード例 #16
0
def check_path_header(req, name, length, error_msg):
    # FIXME: replace swift.common.constraints check_path_header
    #        when swift3 supports swift 2.2 or later
    """
    Validate that the value of path-like header is
    well formatted. We assume the caller ensures that
    specific header is present in req.headers.

    :param req: HTTP request object
    :param name: header name
    :param length: length of path segment check
    :param error_msg: error message for client
    :returns: A tuple with path parts according to length
    :raise: HTTPPreconditionFailed if header value
            is not well formatted.
    """
    src_header = unquote(req.headers.get(name))
    if not src_header.startswith('/'):
        src_header = '/' + src_header
    try:
        return utils.split_path(src_header, length, length, True)
    except ValueError:
        raise HTTPPreconditionFailed(
            request=req,
            body=error_msg)
コード例 #17
0
    def authenticate(self, app):
        """
        authenticate method will run pre-authenticate request and retrieve
        account information.
        Note that it currently supports only keystone and tempauth.
        (no support for the third party authentication middleware)
        """
        sw_req = self.to_swift_req('TEST', None, None, body='')
        # don't show log message of this request
        sw_req.environ['swift.proxy_access_log_made'] = True

        sw_resp = sw_req.get_response(app)

        if not sw_req.remote_user:
            raise SignatureDoesNotMatch()

        _, self.account, _ = split_path(sw_resp.environ['PATH_INFO'],
                                        2, 3, True)
        self.account = utf8encode(self.account)

        if 'HTTP_X_USER_NAME' in sw_resp.environ:
            # keystone
            self.user_id = "%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'],
                                      sw_resp.environ['HTTP_X_USER_NAME'])
            self.user_id = utf8encode(self.user_id)
            self.keystone_token = sw_req.environ['HTTP_X_AUTH_TOKEN']
        else:
            # tempauth
            self.user_id = self.access_key
コード例 #18
0
ファイル: server.py プロジェクト: mja054/swift_plugin
 def DELETE(self, req):
     """Handle HTTP DELETE request."""
     try:
         drive, part, account = split_path(unquote(req.path), 3)
     except ValueError, err:
         return HTTPBadRequest(body=str(err), content_type='text/plain',
                                                 request=req)
コード例 #19
0
ファイル: server.py プロジェクト: DylanYu/swift
 def POST(self, req):
     """Handle HTTP POST request."""
     try:
         drive, part, account, container = split_path(unquote(req.path), 4)
         validate_device_partition(drive, part)
     except ValueError, err:
         return HTTPBadRequest(body=str(err), content_type="text/plain", request=req)
コード例 #20
0
ファイル: bulk.py プロジェクト: xuyaoqiang/swift
    def handle_extract(self, req, compress_type):
        """
        :params req: a swob Request
        :params compress_type: specifying the compression type of the tar.
                               Accepts '', 'gz, or 'bz2'
        :raises HTTPException: on unhandled errors
        :returns: a swob response to request
        """
        success_count = 0
        failed_files = []
        existing_containers = set()
        out_content_type = req.accept.best_match(ACCEPTABLE_FORMATS)
        if not out_content_type:
            return HTTPNotAcceptable(request=req)
        if req.content_length is None and req.headers.get("transfer-encoding", "").lower() != "chunked":
            return HTTPBadRequest("Invalid request: no content sent.")
        try:
            vrs, account, extract_base = split_path(unquote(req.path), 2, 3, True)
        except ValueError:
            return HTTPNotFound(request=req)
        extract_base = extract_base or ""
        extract_base = extract_base.rstrip("/")
        try:
            tar = tarfile.open(mode="r|" + compress_type, fileobj=req.body_file)
            while True:
                tar_info = tar.next()
                if tar_info is None or len(failed_files) >= self.max_failed_extractions:
                    break
                if tar_info.isfile():
                    obj_path = tar_info.name
                    if obj_path.startswith("./"):
                        obj_path = obj_path[2:]
                    obj_path = obj_path.lstrip("/")
                    if extract_base:
                        obj_path = extract_base + "/" + obj_path
                    if "/" not in obj_path:
                        continue  # ignore base level file

                    destination = "/".join(["", vrs, account, obj_path])
                    container = obj_path.split("/", 1)[0]
                    if not check_utf8(destination):
                        failed_files.append([quote(destination[:MAX_PATH_LENGTH]), HTTPPreconditionFailed().status])
                        continue
                    if tar_info.size > MAX_FILE_SIZE:
                        failed_files.append([quote(destination[:MAX_PATH_LENGTH]), HTTPRequestEntityTooLarge().status])
                        continue
                    if container not in existing_containers:
                        try:
                            self.create_container(req, "/".join(["", vrs, account, container]))
                            existing_containers.add(container)
                        except CreateContainerError, err:
                            if err.status_int == HTTP_UNAUTHORIZED:
                                return HTTPUnauthorized(request=req)
                            failed_files.append([quote(destination[:MAX_PATH_LENGTH]), err.status])
                            continue
                        except ValueError:
                            failed_files.append([quote(destination[:MAX_PATH_LENGTH]), HTTP_BAD_REQUEST])
                            continue
                        if len(existing_containers) > self.max_containers:
                            return HTTPBadRequest("More than %d base level containers in tar." % self.max_containers)
コード例 #21
0
    def __call__(self, env, start_response):
        try:
            # /v1/a/c or /v1/a/c/o
            split_path(env["PATH_INFO"], 3, 4, True)
            is_container_or_object_req = True
        except ValueError:
            is_container_or_object_req = False

        headers = [("Content-Type", "text/plain"), ("Content-Length", str(sum(map(len, self.body))))]
        if is_container_or_object_req and self.policy_idx is not None:
            headers.append(("X-Backend-Storage-Policy-Index", str(self.policy_idx)))

        start_response(self.response_str, headers)
        while env["wsgi.input"].read(5):
            pass
        return self.body
コード例 #22
0
ファイル: server.py プロジェクト: afliu/swift
    def get_controller(self, path):
        """
        Get the controller to handle a request.

        :param path: path from request
        :returns: tuple of (controller class, path dictionary)

        :raises: ValueError (thrown by split_path) if given invalid path
        """
        if path == '/info':
            d = dict(version=None,
                     expose_info=self.expose_info,
                     disallowed_sections=self.disallowed_sections,
                     admin_key=self.admin_key)
            return InfoController, d

        version, account, container, obj = split_path(path, 1, 4, True)
        d = dict(version=version,
                 account_name=account,
                 container_name=container,
                 object_name=obj)
        if obj and container and account:
            return ObjectController, d
        elif container and account:
            return ContainerController, d
        elif account and not container and not obj:
            return AccountController, d
        return None, d
コード例 #23
0
ファイル: ibuck.py プロジェクト: jannatunnoor/test_swift
    def __init__(self, app, req, logger):
        """
        Constructor
        :param app:
        :param req:
        :raise: ValueError, HTTPNotFound, KeyAttribute, ImageInvalid
        """
        self.app = app
        self.req = req
        self.logger = logger
        self.resp_dict = {'Response Status': HTTPCreated().status,
                          'Response Body': '',
                          'Number Files Created': 0}
        self.env = req.environ
        self.resize_dimensions = [TYPE_IMAGE_LARGE, TYPE_IMAGE_MEDIUM]

        try:
            self.version, self.account, self.container, self.obj = split_path(self.req.path, 1, 4, True)
        except ValueError:
            raise HTTPNotFound(request=self.req)

        if not self.obj:
            raise ImageInvalid("Not an Image")

        if not str.lower(self.obj.split(".")[-1]) in IMAGE_TYPE:
            raise ImageInvalid("Not an Image")

        self.request_body = self.env['wsgi.input'].read(int(self.env['CONTENT_LENGTH']))
        flo = cStringIO.StringIO(self.request_body)
        try:
            self.orig_image = Image.open(flo)
        except IOError:
            raise ImageInvalid("Not an Image")
コード例 #24
0
ファイル: tempauth.py プロジェクト: mohitsethi/swift
    def handle_request(self, req):
        """
        Entry point for auth requests (ones that match the self.auth_prefix).
        Should return a WSGI-style callable (such as swob.Response).

        :param req: swob.Request object
        """
        req.start_time = time()
        handler = None
        try:
            version, account, user, _junk = split_path(
                req.path_info,
                minsegs=1,
                maxsegs=4,
                rest_with_last=True)
        except ValueError:
            self.logger.increment('errors')
            return HTTPNotFound(request=req)
        if version in ('v1', 'v1.0', 'auth'):
            if req.method == 'GET':
                handler = self.handle_get_token
        if not handler:
            self.logger.increment('errors')
            req.response = HTTPBadRequest(request=req)
        else:
            req.response = handler(req)
        return req.response
コード例 #25
0
    def get_controller(self, path):
        """
        Get the controller to handle a request.
        
        得到一个controller然后处理请求.
        controller的类型有account/container/object.
        实际的请求是由controller处理的.
        controller内包含PUT/POST/DELETE/GET/HEAD等HTTP方法.

        :param path: path from request
        :returns: tuple of (controller class, path dictionary)

        :raises: ValueError (thrown by split_path) if given invalid path
        """
        version, account, container, obj = split_path(path, 1, 4, True)
        d = dict(version=version,
                 account_name=account,
                 container_name=container,
                 object_name=obj)
        if obj and container and account:
            return ObjectController, d
        elif container and account:
            return ContainerController, d
        elif account and not container and not obj:
            return AccountController, d
        return None, d
コード例 #26
0
ファイル: policies.py プロジェクト: wneild/swift
    def __call__(self, env, start_response):
        try:
            req = self.update_request(Request(env))

            version, account, container, obj = split_path(req.path, 1, 4, True)

            if obj and container and account: # An object has been touched, check if any policies applied to parent account/container
                if not PoliciesMiddleware.LOCAL_CALL_HEADER in req.headers:
                    response = self.object_mod(req, obj)
            elif container and account: # A container has been touched, check if a policy is being applied to it
                if req.method == "POST":
                    if PoliciesMiddleware.EXPIRY_META in req.headers:
                        try:
                            expireType, duration = self.validate_policy(req.headers[PoliciesMiddleware.EXPIRY_META])
                            response = self.container_mod(req, duration)
                        except ValueError:
                            req.headers[PoliciesMiddleware.EXPIRY_META] = None
                            response = HTTPPreconditionFailed(request=req, body='Invalid Policy Type provided to Container')
                    elif PoliciesMiddleware.REMOVE_EXPIRY_META in req.headers:
                        response = self.container_mod(req, 0)
                        
        except UnicodeError:
            err = HTTPPreconditionFailed(
                request=req, body='Invalid UTF8 or contains NULL')
            return err(env, start_response)
        
        try:
            if response is not None:        # If there was a problem with a policy related request return the error
                return response(env, start_response)
        except NameError:
            pass
        return self.app(env, start_response)
コード例 #27
0
ファイル: base.py プロジェクト: hanxinboy/swift
def get_container_info(env, app, swift_source=None):
    """
    Get the info structure for a container, based on env and app.
    This is useful to middlewares.
    """
    cache = cache_from_env(env)
    if not cache:
        return None
    (version, account, container, obj) = \
        split_path(env['PATH_INFO'], 2, 4, True)
    cache_key = get_container_memcache_key(account, container)
    # Use a unique environment cache key per container.  If you copy this env
    # to make a new request, it won't accidentally reuse the old container info
    env_key = 'swift.%s' % cache_key
    if env_key not in env:
        container_info = cache.get(cache_key)
        if not container_info:
            resp = make_pre_authed_request(
                env, 'HEAD', '/%s/%s/%s' % (version, account, container),
                swift_source=swift_source,
            ).get_response(app)
            container_info = headers_to_container_info(
                resp.headers, resp.status_int)
        env[env_key] = container_info
    return env[env_key]
コード例 #28
0
ファイル: server.py プロジェクト: schatt/swift
 def DELETE(self, request):
     """Handle HTTP DELETE requests for the Swift Object Server."""
     try:
         device, partition, account, container, obj = split_path(unquote(request.path), 5, 5, True)
         validate_device_partition(device, partition)
     except ValueError, e:
         return HTTPBadRequest(body=str(e), request=request, content_type="text/plain")
コード例 #29
0
 def handle_ring(self, env, start_response):
     """handle requests to /ring"""
     base, ringfile = split_path(env["PATH_INFO"], minsegs=1, maxsegs=2, rest_with_last=True)
     if ringfile not in self.ring_files:
         start_response("404 Not Found", [("Content-Type", "text/plain")])
         return ["Not Found\r\n"]
     target = pathjoin(self.swiftdir, ringfile)
     try:
         self._validate_file(target)
     except LockTimeout:
         self.logger.exception("swiftdir locked for update")
         start_response("503 Service Unavailable", [("Content-Type", "application/octet-stream")])
         return ["Service Unavailable\r\n"]
     except (OSError, IOError):
         self.logger.exception("Oops")
         start_response("503 Service Unavailable", [("Content-Type", "text/plain")])
         return ["Service Unavailable\r\n"]
     if "HTTP_IF_NONE_MATCH" in env:
         if env["HTTP_IF_NONE_MATCH"] == self.current_md5[target]:
             headers = [("Content-Type", "application/octet-stream")]
             start_response("304 Not Modified", headers)
             return ["Not Modified\r\n"]
     if env["REQUEST_METHOD"] == "GET":
         headers = [("Content-Type", "application/octet-stream")]
         headers.append(("Etag", self.current_md5[target]))
         start_response("200 OK", headers)
         return FileIterable(target)
     elif env["REQUEST_METHOD"] == "HEAD":
         headers = [("Content-Type", "application/octet-stream")]
         headers.append(("Etag", self.current_md5[target]))
         start_response("200 OK", headers)
         return []
     else:
         start_response("501 Not Implemented", [("Content-Type", "text/plain")])
         return ["Not Implemented\r\n"]
コード例 #30
0
ファイル: base.py プロジェクト: CiscoAS/swift
def get_account_info(env, app, swift_source=None):
    """
    Get the info structure for an account, based on env and app.
    This is useful to middlewares.
    Note: This call bypasses auth. Success does not imply that the
          request has authorization to the account_info.
    """
    cache = cache_from_env(env)
    if not cache:
        return None
    (version, account, _junk, _junk) = \
        split_path(env['PATH_INFO'], 2, 4, True)
    cache_key = get_account_memcache_key(account)
    # Use a unique environment cache key per account.  If you copy this env
    # to make a new request, it won't accidentally reuse the old account info
    env_key = 'swift.%s' % cache_key
    if env_key not in env:
        account_info = cache.get(cache_key)
        if not account_info:
            resp = make_pre_authed_request(
                env, 'HEAD', '/%s/%s' % (version, account),
                swift_source=swift_source,
            ).get_response(app)
            account_info = headers_to_account_info(
                resp.headers, resp.status_int)
        env[env_key] = account_info
    return env[env_key]
コード例 #31
0
ファイル: request_helpers.py プロジェクト: fkilleress/swift-2
def check_path_header(req, name, length, error_msg):
    """
    Validate that the value of path-like header is
    well formatted. We assume the caller ensures that
    specific header is present in req.headers.

    :param req: HTTP request object
    :param name: header name
    :param length: length of path segment check
    :param error_msg: error message for client
    :returns: A tuple with path parts according to length
    :raise: HTTPPreconditionFailed if header value
            is not well formatted.
    """
    hdr = wsgi_unquote(req.headers.get(name))
    if not hdr.startswith('/'):
        hdr = '/' + hdr
    try:
        return split_path(hdr, length, length, True)
    except ValueError:
        raise HTTPPreconditionFailed(request=req, body=error_msg)
コード例 #32
0
    def test_pop_queue(self):
        x = expirer.ObjectExpirer({},
                                  logger=self.logger,
                                  swift=FakeInternalClient({}))
        requests = []

        def capture_requests(ipaddr, port, method, path, *args, **kwargs):
            requests.append((method, path))

        with mocked_http_conn(200, 200, 200,
                              give_connect=capture_requests) as fake_conn:
            x.pop_queue('a', 'c', 'o')
            with self.assertRaises(StopIteration):
                next(fake_conn.code_iter)
        for method, path in requests:
            self.assertEqual(method, 'DELETE')
            device, part, account, container, obj = utils.split_path(
                path, 5, 5, True)
            self.assertEqual(account, 'a')
            self.assertEqual(container, 'c')
            self.assertEqual(obj, 'o')
コード例 #33
0
ファイル: server.py プロジェクト: r0mik/swift
    def get_controller(self, path):
        """
        Get the controller to handle a request.

        :param path: path from request
        :returns: tuple of (controller class, path dictionary)

        :raises: ValueError (thrown by split_path) if given invalid path
        """
        version, account, container, obj = split_path(path, 1, 4, True)
        d = dict(version=version,
                 account_name=account,
                 container_name=container,
                 object_name=obj)
        if obj and container and account:
            return ObjectController, d
        elif container and account:
            return ContainerController, d
        elif account and not container and not obj:
            return AccountController, d
        return None, d
コード例 #34
0
 def __init__(self, env, path, swift_source=None):
     self.environ = env
     (version, account, container, obj) = split_path(path, 2, 4, True)
     self.account = account
     self.container = container
     self.obj = obj
     if obj:
         stype = 'object'
         self.headers = {
             'content-length': 5555,
             'content-type': 'text/plain'
         }
     else:
         stype = container and 'container' or 'account'
         self.headers = {
             'x-%s-object-count' % (stype): 1000,
             'x-%s-bytes-used' % (stype): 6666
         }
     if swift_source:
         meta = 'x-%s-meta-fakerequest-swift-source' % stype
         self.headers[meta] = swift_source
コード例 #35
0
def get_account_info(env, app, swift_source=None):
    """
    Get the info structure for an account, based on env and app.
    This is useful to middlewares.
    Note: This call bypasses auth. Success does not imply that the
          request has authorization to the container.
    """
    (version, account, _junk, _junk) = \
        split_path(env['PATH_INFO'], 2, 4, True)
    info = get_info(app,
                    env,
                    account,
                    ret_not_found=True,
                    swift_source=swift_source)
    if not info:
        info = headers_to_account_info({}, 0)
    if info.get('container_count') is None:
        info['container_count'] = 0
    else:
        info['container_count'] = int(info['container_count'])
    return info
コード例 #36
0
    def _is_definitive_auth(self, path):
        """
        Determine if we are the definitive auth

        Determines if we are the definitive auth for a given path.
        If the account name is prefixed with something matching one
        of the reseller_prefix items, then we are the auth (return True)
        Non-matching: we are not the auth.
        However, one of the reseller_prefix items can be blank. If
        so, we cannot always be definite so return False.

        :param path: A path (e.g., /v1/AUTH_joesaccount/c/o)
        :return:True if we are definitive auth
        """
        try:
            version, account, rest = split_path(path, 1, 3, True)
        except ValueError:
            return False
        if account:
            return bool(self._get_account_prefix(account))
        return False
コード例 #37
0
    def get_controller(self, env, path):
        container, obj = split_path(path, 0, 2, True)
        d = {
            'container_name': container,
            'object_name': unquote(obj) if obj is not None else obj
        }

        if 'QUERY_STRING' in env:
            args = dict(urlparse.parse_qsl(env['QUERY_STRING'], 1))
        else:
            args = {}

        if container and obj:
            if env['REQUEST_METHOD'] == 'POST':
                if 'uploads' or 'uploadId' in args:
                    return BucketController, d
            return ObjectController, d
        elif container:
            return BucketController, d

        return ServiceController, d
コード例 #38
0
    def PUT(self, req):
        """
        Handle PUT Object and PUT Object (Copy) request
        """
        if CONF.s3_acl:
            if 'X-Amz-Copy-Source' in req.headers:
                src_path = req.headers['X-Amz-Copy-Source']
                src_path = src_path if src_path.startswith('/') else \
                    ('/' + src_path)
                src_bucket, src_obj = split_path(src_path, 0, 2, True)
                req.get_response(self.app,
                                 'HEAD',
                                 src_bucket,
                                 src_obj,
                                 permission='READ')
            b_resp = req.get_response(self.app, 'HEAD', obj='')
            # To avoid overwriting the existing object by unauthorized user,
            # we send HEAD request first before writing the object to make
            # sure that the target object does not exist or the user that sent
            # the PUT request have write permission.
            try:
                req.get_response(self.app, 'HEAD')
            except NoSuchKey:
                pass
            req_acl = ACL.from_headers(req.headers, b_resp.bucket_acl.owner,
                                       Owner(req.user_id, req.user_id))

            req.object_acl = req_acl

        resp = req.get_response(self.app)

        if 'X-Amz-Copy-Source' in req.headers:
            elem = Element('CopyObjectResult')
            SubElement(elem, 'ETag').text = '"%s"' % resp.etag
            body = tostring(elem, use_s3ns=False)
            return HTTPOk(body=body, headers=resp.headers)

        resp.status = HTTP_OK

        return resp
コード例 #39
0
    def round_robin_order(self, task_iter):
        """
        Change order of expiration tasks to avoid deleting objects in a
        certain container continuously.

        :param task_iter: An iterator of delete-task dicts, which should each
            have a ``target_path`` key.
        """
        obj_cache = defaultdict(deque)
        cnt = 0

        def dump_obj_cache_in_round_robin():
            while obj_cache:
                for key in sorted(obj_cache):
                    if obj_cache[key]:
                        yield obj_cache[key].popleft()
                    else:
                        del obj_cache[key]

        for delete_task in task_iter:
            try:
                target_account, target_container, _junk = \
                    split_path('/' + delete_task['target_path'], 3, 3, True)
                cache_key = '%s/%s' % (target_account, target_container)
            # sanity
            except ValueError:
                self.logger.error('Unexcepted error handling task %r' %
                                  delete_task)
                continue

            obj_cache[cache_key].append(delete_task)
            cnt += 1

            if cnt > MAX_OBJECTS_TO_CACHE:
                for task in dump_obj_cache_in_round_robin():
                    yield task
                cnt = 0

        for task in dump_obj_cache_in_round_robin():
            yield task
コード例 #40
0
    def authorize_anonymous(self, req):
        """
        Authorize an anonymous request.

        :returns: None if authorization is granted, an error page otherwise.
        """
        try:
            part = swift_utils.split_path(req.path, 1, 4, True)
            version, account, container, obj = part
        except ValueError:
            return HTTPNotFound(request=req)

        is_authoritative_authz = (account
                                  and account.startswith(self.reseller_prefix))
        if not is_authoritative_authz:
            return self.denied_response(req)

        referrers, roles = swift_acl.parse_acl(getattr(req, 'acl', None))
        authorized = self._authorize_unconfirmed_identity(
            req, obj, referrers, roles)
        if not authorized:
            return self.denied_response(req)
コード例 #41
0
 def action_routine(self, req, storage_url, token):
     """ execute action """
     path = urlparse(self.del_prefix(req.url)).path
     vrs, acc, cont, obj = split_path(path, 1, 4, True)
     path_type = len([i for i in [vrs, acc, cont, obj] if i])
     params = req.params_alt()
     self.logger.debug('Received Params: %s' % params)
     action = params.get('_action')
     lines = int(params.get('_line', self.items_per_page))
     page = int(params.get('_page', 0))
     marker = str(params.get('_marker', ''))
     cont_param = params.get('cont_name', None)
     obj_prefix = params.get('obj_prefix', '')
     if cont_param:
         cont = quote(cont_param)
     obj_param = params.get('obj_name', None)
     if obj_param and len(obj_param) == 2:
         obj_name, obj_fp = obj_param
         if obj_prefix:
             obj_name = obj_prefix + obj_name
         obj = quote(obj_name)
     else:
         obj_name, obj_fp = ('', None)
     from_cont = params.get('from_container', None)
     if from_cont:
         cont = quote(from_cont)
     from_obj = params.get('from_object', None)
     if from_obj:
         obj = from_obj
     to_cont = params.get('to_container', None)
     if to_cont:
         to_cont = to_cont
     to_obj = params.get('to_object', None)
     if to_obj:
         to_obj = quote(to_obj)
     try:
         meta_headers = self.metadata_check(params)
     except ValueError, err:
         return HTTP_PRECONDITION_FAILED
コード例 #42
0
    def get_controller(self, req):
        """
        Get the controller to handle a request.

        :param req: the request
        :returns: tuple of (controller class, path dictionary)

        :raises ValueError: (thrown by split_path) if given invalid path
        """
        if req.path == '/info':
            d = dict(version=None,
                     expose_info=self.expose_info,
                     disallowed_sections=self.disallowed_sections,
                     admin_key=self.admin_key)
            return InfoController, d

        version, account, container, obj = split_path(req.path, 1, 4, True)
        d = dict(version=version,
                 account_name=account,
                 container_name=container,
                 object_name=obj)
        return ProxySatelliteController, d
コード例 #43
0
 def FakeGetInfo(self, env, app, swift_source=None):
     info = {
         'status': 0,
         'sync_key': None,
         'meta': {},
         'cors': {
             'allow_origin': None,
             'expose_headers': None,
             'max_age': None
         },
         'sysmeta': {},
         'read_acl': None,
         'object_count': None,
         'write_acl': None,
         'versions': None,
         'bytes': None
     }
     info['storage_policy'] = self.policy_to_test
     (version, account, container, unused) = \
         split_path(env['PATH_INFO'], 3, 4, True)
     self.assertEqual((version, account, container), self.expected_path[:3])
     return info
コード例 #44
0
ファイル: log_raw.py プロジェクト: zuiwufenghua/zft
 def log_line_parser(self, raw_log):
     '''given a raw access log line, return a dict of the good parts'''
     d = {}
     try:
         (unused,
         server,
         client_ip,
         lb_ip,
         timestamp,
         method,
         request,
         http_version,
         code,
         referrer,
         user_agent,
         auth_token,
         bytes_in,
         bytes_out,
         etag,
         trans_id,
         headers,
         processing_time) = (unquote(x) for x in
                             raw_log[16:].split(' ')[:18])
     except ValueError:
         self.logger.debug(_('Bad line data: %s') % repr(raw_log))
         return {}
     if server != self.server_name:
         # incorrect server name in log line
         self.logger.debug(_('Bad server name: found "%(found)s" ' \
                 'expected "%(expected)s"') %
                 {'found': server, 'expected': self.server_name})
         return {}
     try:
         (version, account, container_name, object_name) = \
             split_path(request, 2, 4, True)
     except ValueError, e:
         self.logger.debug(_('Invalid path: %(error)s from data: %(log)s') %
         {'error': e, 'log': repr(raw_log)})
         return {}
コード例 #45
0
    def handle_request(self, req):
        """
        Entry point for auth requests (ones that match the self.auth_prefix).
        Should return a WSGI-style callable (such as webob.Response).

        :param req: webob.Request object
        """
        req.start_time = time()
        handler = None
        try:
            version, account, user, _junk = split_path(req.path_info,
                minsegs=1, maxsegs=4, rest_with_last=True)
        except ValueError:
            return HTTPNotFound(request=req)
        if version in ('v1', 'v1.0', 'auth'):
            if req.method == 'GET':
                handler = self.handle_get_token
        if not handler:
            req.response = HTTPBadRequest(request=req)
        else:
            req.response = handler(req)
        return req.response
コード例 #46
0
def parse_raw_obj(obj_info):
    """
    Translate a reconciler container listing entry to a dictionary
    containing the parts of the misplaced object queue entry.

    :param obj_info: an entry in an a container listing with the
                     required keys: name, content_type, and hash

    :returns: a queue entry dict with the keys: q_policy_index, account,
              container, obj, q_op, q_ts, q_record, and path
    """
    if six.PY2:
        raw_obj_name = obj_info['name'].encode('utf-8')
    else:
        raw_obj_name = obj_info['name']

    policy_index, obj_name = raw_obj_name.split(':', 1)
    q_policy_index = int(policy_index)
    account, container, obj = split_path(obj_name, 3, 3, rest_with_last=True)
    try:
        q_op = {
            'application/x-put': 'PUT',
            'application/x-delete': 'DELETE',
        }[obj_info['content_type']]
    except KeyError:
        raise ValueError('invalid operation type %r' %
                         obj_info.get('content_type', None))
    return {
        'q_policy_index': q_policy_index,
        'account': account,
        'container': container,
        'obj': obj,
        'q_op': q_op,
        'q_ts': decode_timestamps((obj_info['hash']))[0],
        'q_record': last_modified_date_to_timestamp(
            obj_info['last_modified']),
        'path': '/%s/%s/%s' % (account, container, obj)
    }
コード例 #47
0
    def __call__(self, env, start_response):
        content_type = env.get('CONTENT_TYPE', '')

        path = env['PATH_INFO']
        version, account, container, object = swift_utils.split_path(
            path, minsegs=2, maxsegs=4, rest_with_last=True)

        self.logger.debug('generatethumb: %s, %s, %s' %
                          (env['REQUEST_METHOD'], content_type, object))

        req = Request(env)

        #self.logger.debug('generatethumb: class of req %s' % req.__class__)

        # don't generate the thumbnail for a thumbnailed image
        if 'X-Object-Transient-Sysmeta-Thumbnail' in req.headers:
            self.logger.debug(
                'generatethumb: image already a thumbnail, skipping')
            return self.app(env, start_response)

        if object is not None and env['REQUEST_METHOD'] in [
                "PUT", "POST"
        ] and content_type in self.content_types:

            #self.logger.debug('generatethumb: dir of wsgi.input: %s, class: %s' % (dir(env['wsgi.input']), env['wsgi.input'].__class__))

            req.make_body_seekable()

            # currently I have a problem if executing the thumbnail generation code in the posthook, I cannot properly do a make_body_seekable
            # in the posthook, getting a client disconnected error, maybe this is due to the body stream not being avail anymore in the hook.
            #env['eventlet.posthooks'].append(
            #    (self.generate_thumbnail, (req,), {})
            #)

            # debug: direct call
            self.generate_thumbnail(env, req)

        return self.app(env, start_response)
コード例 #48
0
ファイル: swob.py プロジェクト: atulshridhar/swift
    def split_path(self, minsegs=1, maxsegs=None, rest_with_last=False):
        """
        Validate and split the Request's path.

        **Examples**::

            ['a'] = split_path('/a')
            ['a', None] = split_path('/a', 1, 2)
            ['a', 'c'] = split_path('/a/c', 1, 2)
            ['a', 'c', 'o/r'] = split_path('/a/c/o/r', 1, 3, True)

        :param minsegs: Minimum number of segments to be extracted
        :param maxsegs: Maximum number of segments to be extracted
        :param rest_with_last: If True, trailing data will be returned as part
                               of last segment.  If False, and there is
                               trailing data, raises ValueError.
        :returns: list of segments with a length of maxsegs (non-existant
                  segments will return as None)
        :raises: ValueError if given an invalid path
        """
        return split_path(
            self.environ.get('SCRIPT_NAME', '') + self.environ['PATH_INFO'],
            minsegs, maxsegs, rest_with_last)
コード例 #49
0
    def authorize_via_acl(self, req):
        """Anon request handling.

        For now this only allows anon read of objects.  Container and account
        actions are prohibited.
        """

        self.log.debug('authorizing anonymous request')
        try:
            version, account, container, obj = split_path(req.path, 1, 4, True)
        except ValueError:
            return HTTPNotFound(request=req)

        if obj:
            return self._authorize_anon_object(req, account, container, obj)

        if container:
            return self._authorize_anon_container(req, account, container)

        if account:
            return self._authorize_anon_account(req, account)

        return self._authorize_anon_toplevel(req)
コード例 #50
0
def check_path_header(req, name, length, error_msg):
    # FIXME: replace swift.common.constraints check_path_header
    #        when swift3 supports swift 2.2 or later
    """
    Validate that the value of path-like header is
    well formatted. We assume the caller ensures that
    specific header is present in req.headers.

    :param req: HTTP request object
    :param name: header name
    :param length: length of path segment check
    :param error_msg: error message for client
    :returns: A tuple with path parts according to length
    :raise: HTTPPreconditionFailed if header value
            is not well formatted.
    """
    src_header = unquote(req.headers.get(name))
    if not src_header.startswith('/'):
        src_header = '/' + src_header
    try:
        return utils.split_path(src_header, length, length, True)
    except ValueError:
        raise HTTPPreconditionFailed(request=req, body=error_msg)
コード例 #51
0
    def __call__(self, req):
        print(req)
        print(req.headers)
        print(req.path_info)
        obj = None
        try:
            (version, account, container, obj) = \
                split_path(req.path_info, 4, 4, True)
            if req.method == 'PUT':
                print(obj)
                payload = {
                    "conf": {
                        "swift_id": obj,
                        "swift_container": container,
                        "swift_user": account,
                        "swift_version": version
                    }
                }
                rep = requests.post(URL + ENDPOINT_PATH + "/dags/" + DAG_NAME +
                                    "/dag_runs",
                                    data=json.dumps(payload))
                print(rep.text)
                self.logger.info(rep.headers)
                self.logger.info(rep.text)
                # No response return = bug
                resp = req.get_response(self.app)
                return resp

        except ValueError:
            # not an object request
            resp = req.get_response(self.app)

            return resp

        resp = req.get_response(self.app)

        return resp
コード例 #52
0
    def __call__(self, env, start_response):
        request = Request(env)

        url_prefix = '/object_endpoint/'

        if request.path.startswith(url_prefix):

            if request.method != 'GET':
                raise HTTPMethodNotAllowed()

            aco = split_path(request.path[len(url_prefix) - 1:], 1, 3, True)
            account = aco[0]
            container = aco[1]
            obj = aco[2]
            if obj.endswith('/'):
                obj = obj[:-1]

            object_partition, objects = self.object_ring.get_nodes(
                account, container, obj)

            endpoint_template = 'http://{ip}:{port}/{device}/{partition}/' + \
                                '{account}/{container}/{obj}'
            endpoints = []
            for element in objects:
                endpoint = endpoint_template.format(ip=element['ip'],
                                                    port=element['port'],
                                                    device=element['device'],
                                                    partition=object_partition,
                                                    account=account,
                                                    container=container,
                                                    obj=obj)
                endpoints.append(endpoint)

            start_response('200 OK', {})
            return json.dumps(endpoints)

        return self.app(env, start_response)
コード例 #53
0
    def add_file(self, env, req):
        try:
            self.logger.debug('indexelastic: start async add: %s' % (env))

            path = env['PATH_INFO']
            container, object = swift_utils.split_path(path,
                                                       minsegs=1,
                                                       maxsegs=2,
                                                       rest_with_last=True)

            connections.create_connection(hosts=self.endpoints)

            File.init()

            f = File()
            f.bucket = container
            f.path = '/' + object
            f.timestamp = int(float(env['HTTP_X_TIMESTAMP']) * 1000)
            #f.user = env['HTTP_X_USER']
            f.mimetype = env['CONTENT_TYPE']

            # adding meta data
            metaprefix = 'X-Object-Meta-Imgmeta-'
            metakeys = [k for k in req.headers if k.startswith(metaprefix)]
            for k in metakeys:
                #self.logger.debug('header %s -> %s' % (h, req.headers[h]))
                k_short = k.replace(metaprefix, '')
                f.metadata[k_short] = req.headers[k]

            f.save()
            self.logger.debug('indexelastic: object with id %s added' %
                              f.meta.id)

        except Exception:
            self.logger.exception(
                'indexelastic: encountered exception while indexing in elastic search'
            )
コード例 #54
0
def get_info_1(container_ring, obj_path, logger):

    path_comps = split_path(obj_path, 1, 3, True)
    account_name = path_comps[0]
    container_name = path_comps[1]
    obj_name = path_comps[2]

    container_part, container_nodes = \
        container_ring.get_nodes(account_name, container_name)

    if not container_nodes:
        raise ContainerError()

    # Perhaps we should do something about the way we select the container
    # nodes. For now we just shuffle. It spreads the load, but it does not
    # improve upon the the case when some nodes are down, so auditor slows
    # to a crawl (if this plugin is enabled).
    random.shuffle(container_nodes)

    err_flag = 0
    for node in container_nodes:
        try:
            headers, objs = direct_get_container(
                node, container_part, account_name, container_name,
                prefix=obj_name, limit=1)
        except (ClientException, Timeout):
            # Something is wrong with that server, treat as an error.
            err_flag += 1
            continue
        if objs and objs[0]['name'] == obj_name:
            return objs[0]

    # We only report the object as dark if all known servers agree that it is.
    if err_flag:
        raise ContainerError()
    return None
コード例 #55
0
    def __call__(self, env, start_response):
        content_type = env.get('CONTENT_TYPE', '')

        path = env['PATH_INFO']
        version, account, container, object = swift_utils.split_path(
            path, minsegs=2, maxsegs=4, rest_with_last=True)

        self.logger.debug('indexelastic: %s, %s, %s' %
                          (env['REQUEST_METHOD'], content_type, object))

        req = Request(env)

        # don't index thumbnail files (TODO: is it ok like this?)
        if 'X-Object-Transient-Sysmeta-Thumbnail' in req.headers:
            self.logger.debug('indexelastic: image is a thumbnail, skipping')
            return self.app(env, start_response)

        if object is not None and env['REQUEST_METHOD'] in ["PUT", "POST"]:
            env['eventlet.posthooks'].append((self.add_file, (req, ), {}))

        elif object is not None and env['REQUEST_METHOD'] in ["DELETE"]:
            env['eventlet.posthooks'].append((self.remove_file, (req, ), {}))

        return self.app(env, start_response)
コード例 #56
0
ファイル: server.py プロジェクト: zuiwufenghua/zft
    def handle_token(self, request):
        """
        Handles ReST requests from Swift to validate tokens

        Valid URL paths:
            * GET /token/<token>

        If the HTTP request returns with a 204, then the token is valid, the
        TTL of the token will be available in the X-Auth-Ttl header, and a
        comma separated list of the "groups" the user belongs to will be in the
        X-Auth-Groups header.

        :param request: webob.Request object
        """
        try:
            _junk, token = split_path(request.path, minsegs=2)
        except ValueError:
            return HTTPBadRequest()
        # Retrieves (TTL, account, user, cfaccount) if valid, False otherwise
        headers = {}
        if 'Authorization' in request.headers:
            validation = self.validate_s3_sign(request, token)
            if validation:
                headers['X-Auth-Account-Suffix'] = validation[3]
        else:
            validation = self.validate_token(token)
        if not validation:
            return HTTPNotFound()
        groups = ['%s:%s' % (validation[1], validation[2]), validation[1]]
        if validation[3]:
            # admin access to a cfaccount or ".reseller_admin" to access to all
            # accounts, including creating new ones.
            groups.append(validation[3])
        headers['X-Auth-TTL'] = validation[0]
        headers['X-Auth-Groups'] = ','.join(groups)
        return HTTPNoContent(headers=headers)
コード例 #57
0
    def __call__(self, request):
        try:
            (version, account, container,
             objname) = split_path(request.path_info, 4, 4, True)
        except ValueError:
            return self.app

        preview_path = '/%s/%s/%s_%s/%s' % (version, account, container,
                                            self.suffix, objname)

        if request.method == 'GET' and request.params.has_key('preview'):
            request.path_info = preview_path

        if request.method == 'PUT':
            if hasattr(request, 'body_file'):
                data = ""
                while True:
                    chunk = request.body_file.read()
                    if not chunk:
                        break
                    data += chunk
                request.body = data
                preview = create_preview(data)
            else:
                preview = create_preview(request.body)
            if preview:
                sub = wsgi.make_subrequest(request.environ,
                                           path=preview_path,
                                           body=preview)
                sub.get_response(self.app)

        if request.method == 'DELETE':
            sub = wsgi.make_subrequest(request.environ, path=preview_path)
            sub.get_response(self.app)

        return self.app
コード例 #58
0
ファイル: staticweb.py プロジェクト: r0mik/swift
    def __call__(self, env, start_response):
        """
        Main hook into the WSGI paste.deploy filter/app pipeline.

        :param env: The WSGI environment dict.
        :param start_response: The WSGI start_response hook.
        """
        env['staticweb.start_time'] = time.time()
        try:
            (version, account, container, obj) = \
                split_path(env['PATH_INFO'], 2, 4, True)
        except ValueError:
            return self.app(env, start_response)
        if env['REQUEST_METHOD'] not in ('HEAD', 'GET'):
            return self.app(env, start_response)
        if env.get('REMOTE_USER') and \
                not config_true_value(env.get('HTTP_X_WEB_MODE', 'f')):
            return self.app(env, start_response)
        if not container:
            return self.app(env, start_response)
        context = _StaticWebContext(self, version, account, container, obj)
        if obj:
            return context.handle_object(env, start_response)
        return context.handle_container(env, start_response)
コード例 #59
0
 def http_connect(ipaddr,
                  port,
                  device,
                  partition,
                  method,
                  path,
                  headers=None,
                  query_string=None):
     a, c, o = split_path(path, 1, 3, True)
     if o:
         func = object_func
     elif c:
         func = container_func
     else:
         func = account_func
     resp = func(ipaddr,
                 port,
                 device,
                 partition,
                 method,
                 path,
                 headers=headers,
                 query_string=query_string)
     return resp
コード例 #60
0
ファイル: ratelimit.py プロジェクト: zhoubing00/swift
    def __call__(self, env, start_response):
        """
        WSGI entry point.
        Wraps env in webob.Request object and passes it down.

        :param env: WSGI environment dictionary
        :param start_response: WSGI callable
        """
        req = Request(env)
        if self.memcache_client is None:
            self.memcache_client = cache_from_env(env)
        if not self.memcache_client:
            self.logger.warning(
                _('Warning: Cannot ratelimit without a memcached client'))
            return self.app(env, start_response)
        try:
            version, account, container, obj = split_path(req.path, 1, 4, True)
        except ValueError:
            return self.app(env, start_response)
        ratelimit_resp = self.handle_ratelimit(req, account, container, obj)
        if ratelimit_resp is None:
            return self.app(env, start_response)
        else:
            return ratelimit_resp(env, start_response)