Example #1
0
    def origin_db_get(self, env, req):
        '''
        Handles GETs to the Origin database
        The only part of the path this pays attention to is the account.
        '''
        #TODO: this does not return transfer-encoding: chunked
        try:
            account = req.path.split('/')[2]
        except IndexError:
            return HTTPBadRequest('Invalid request. '
                                  'URI format: /<api version>/<account>')
        #TODO: make sure to test with unicode container names
        marker = get_param(req, 'marker', default='')
        list_format = get_param(req, 'format')
        enabled_only = get_param(req, 'enabled',
                                 default='false') in TRUE_VALUES
        limit = get_param(req, 'limit')
        if limit:
            try:
                limit = int(limit)
            except ValueError:
                return HTTPBadRequest('Invalid limit, must be an integer')
        listing_path = '/v1/%s/%s?format=json&marker=%s' % \
                       (self.origin_account, account, marker)
        # no limit in request because may have to filter on cdn_enabled
        resp = make_pre_authed_request(env, 'GET',
            listing_path, agent='SwiftOrigin').get_response(self.app)
        resp_headers = {}
        # {'Transfer-Encoding': 'chunked'}
        #TODO is this right? was chunked in old one
        if resp.status_int // 100 == 2:
            cont_listing = json.loads(resp.body)
            # TODO: is it ok to load the whole thing? do i have a choice?
            listing_formatted = []
            for listing_dict in cont_listing:
                if limit is None or len(listing_formatted) < limit:
                    try:
                        formatted_data = self._parse_container_listing(
                            account, listing_dict, list_format,
                            only_cdn_enabled=enabled_only)
                        if formatted_data:
                            listing_formatted.append(formatted_data)
                    except InvalidContentType, e:
                        self.logger.exception(e)
                        continue
                else:
                    break
            if list_format == 'xml':
                resp_headers['Content-Type'] = 'application/xml'
                response_body = ('<?xml version="1.0" encoding="UTF-8"?>\n'
                    '<account name="%s">\n%s\n</account>') % (account,
                        '\n'.join(listing_formatted))

            elif list_format == 'json':
                resp_headers['Content-Type'] = 'application/json'
                response_body = json.dumps(listing_formatted)
            else:
                resp_headers['Content-Type'] = 'text/plain; charset=UTF-8'
                response_body = '\n'.join(listing_formatted)
            return Response(body=response_body, headers=resp_headers)
Example #2
0
def account_listing_content_type(req):
    """
    Figure out the content type of an account-listing response.

    Returns a 2-tuple: (content_type, error). Only one of them will be set;
    the other will be None.
    """
    try:
        query_format = get_param(req, 'format')
    except UnicodeDecodeError:
        return (None, HTTPBadRequest(body='parameters not utf8',
                                     content_type='text/plain', request=req))
    if query_format:
        req.accept = FORMAT2CONTENT_TYPE.get(query_format.lower(),
                                             FORMAT2CONTENT_TYPE['plain'])
    content_type = req.accept.best_match(
        ['text/plain', 'application/json', 'application/xml', 'text/xml'])
    if not content_type:
        return (None, HTTPNotAcceptable(request=req))
    else:
        return (content_type, None)
Example #3
0
 if broker.is_deleted():
     return HTTPNotFound(request=req)
 info = broker.get_info()
 resp_headers = {
     'X-Account-Container-Count': info['container_count'],
     'X-Account-Object-Count': info['object_count'],
     'X-Account-Bytes-Used': info['bytes_used'],
     'X-Timestamp': info['created_at'],
     'X-PUT-Timestamp': info['put_timestamp']
 }
 resp_headers.update(
     (key, value)
     for key, (value, timestamp) in broker.metadata.iteritems()
     if value != '')
 try:
     prefix = get_param(req, 'prefix')
     delimiter = get_param(req, 'delimiter')
     if delimiter and (len(delimiter) > 1 or ord(delimiter) > 254):
         # delimiters can be made more flexible later
         return HTTPPreconditionFailed(body='Bad delimiter')
     limit = ACCOUNT_LISTING_LIMIT
     given_limit = get_param(req, 'limit')
     if given_limit and given_limit.isdigit():
         limit = int(given_limit)
         if limit > ACCOUNT_LISTING_LIMIT:
             return HTTPPreconditionFailed(request=req,
                                           body='Maximum limit is %d' %
                                           ACCOUNT_LISTING_LIMIT)
     marker = get_param(req, 'marker', '')
     end_marker = get_param(req, 'end_marker')
     query_format = get_param(req, 'format')
Example #4
0
            'X-Account-Container-Count': info['container_count'],
            'X-Account-Object-Count': info['object_count'],
            'X-Account-Bytes-Used': info['bytes_used'],
            'X-Timestamp': info['created_at'],
            'X-PUT-Timestamp': info['put_timestamp']}
        if not self.fs_object:
            resp_headers.update((key, value)
                for key, (value, timestamp) in broker.metadata.iteritems()
                if value != '')
        else:
            resp_headers.update((key, value)
                for key, value in broker.metadata.iteritems()
                if value != '')

        try:
            prefix = get_param(req, 'prefix')
            delimiter = get_param(req, 'delimiter')
            if delimiter and (len(delimiter) > 1 or ord(delimiter) > 254):
                # delimiters can be made more flexible later
                return HTTPPreconditionFailed(body='Bad delimiter')
            limit = ACCOUNT_LISTING_LIMIT
            given_limit = get_param(req, 'limit')
            if given_limit and given_limit.isdigit():
                limit = int(given_limit)
                if limit > ACCOUNT_LISTING_LIMIT:
                    return  HTTPPreconditionFailed(request=req,
                        body='Maximum limit is %d' % ACCOUNT_LISTING_LIMIT)
            marker = get_param(req, 'marker', '')
            end_marker = get_param(req, 'end_marker')
            query_format = get_param(req, 'format')
        except UnicodeDecodeError, err:
Example #5
0
 if broker.is_deleted():
     return HTTPNotFound(request=req)
 info = broker.get_info()
 resp_headers = {
     "X-Container-Object-Count": info["object_count"],
     "X-Container-Bytes-Used": info["bytes_used"],
     "X-Timestamp": info["created_at"],
     "X-PUT-Timestamp": info["put_timestamp"],
 }
 resp_headers.update(
     (key, value)
     for key, (value, timestamp) in broker.metadata.iteritems()
     if value != "" and (key.lower() in self.save_headers or key.lower().startswith("x-container-meta-"))
 )
 try:
     path = get_param(req, "path")
     prefix = get_param(req, "prefix")
     delimiter = get_param(req, "delimiter")
     if delimiter and (len(delimiter) > 1 or ord(delimiter) > 254):
         # delimiters can be made more flexible later
         return HTTPPreconditionFailed(body="Bad delimiter")
     marker = get_param(req, "marker", "")
     end_marker = get_param(req, "end_marker")
     limit = CONTAINER_LISTING_LIMIT
     given_limit = get_param(req, "limit")
     if given_limit and given_limit.isdigit():
         limit = int(given_limit)
         if limit > CONTAINER_LISTING_LIMIT:
             return HTTPPreconditionFailed(request=req, body="Maximum limit is %d" % CONTAINER_LISTING_LIMIT)
     query_format = get_param(req, "format")
 except UnicodeDecodeError, err:
Example #6
0
        broker.stale_reads_ok = True
        if broker.is_deleted():
            return HTTPNotFound(request=req)
        info = broker.get_info()
        headers = {
            "X-Container-Object-Count": info["object_count"],
            "X-Container-Bytes-Used": info["bytes_used"],
            "X-Timestamp": info["created_at"],
            "X-PUT-Timestamp": info["put_timestamp"],
        }
        headers.update(
            (key, value)
            for key, (value, timestamp) in broker.metadata.iteritems()
            if value != "" and (key.lower() in self.save_headers or key.lower().startswith("x-container-meta-"))
        )
        if get_param(req, "format"):
            req.accept = FORMAT2CONTENT_TYPE.get(get_param(req, "format").lower(), FORMAT2CONTENT_TYPE["plain"])
        try:
            headers["Content-Type"] = req.accept.best_match(
                ["text/plain", "application/json", "application/xml", "text/xml"], default_match="text/plain"
            )
        except AssertionError, err:
            return HTTPBadRequest(body="bad accept header: %s" % req.accept, content_type="text/plain", request=req)
        return HTTPNoContent(request=req, headers=headers, charset="utf-8")

    @public
    @timing_stats
    def GET(self, req):
        """Handle HTTP GET request."""
        try:
            drive, part, account, container, obj = split_path(unquote(req.path), 4, 5, True)
Example #7
0
File: server.py Project: UshF/swift
        broker.stale_reads_ok = True
        if broker.is_deleted():
            return HTTPNotFound(request=req)
        info = broker.get_info()
        headers = {
            'X-Container-Object-Count': info['object_count'],
            'X-Container-Bytes-Used': info['bytes_used'],
            'X-Timestamp': info['created_at'],
            'X-PUT-Timestamp': info['put_timestamp'],
        }
        headers.update(
            (key, value)
            for key, (value, timestamp) in broker.metadata.iteritems()
            if value != '' and (key.lower() in self.save_headers or
                                key.lower().startswith('x-container-meta-')))
        if get_param(req, 'format'):
            req.accept = FORMAT2CONTENT_TYPE.get(
                get_param(req, 'format').lower(), FORMAT2CONTENT_TYPE['plain'])
        headers['Content-Type'] = req.accept.best_match(
            ['text/plain', 'application/json', 'application/xml', 'text/xml'])
        if not headers['Content-Type']:
            return HTTPNotAcceptable(request=req)
        return HTTPNoContent(request=req, headers=headers, charset='utf-8')

    @public
    @timing_stats
    def GET(self, req):
        """Handle HTTP GET request."""
        try:
            drive, part, account, container, obj = split_path(
                unquote(req.path), 4, 5, True)
Example #8
0
        broker.stale_reads_ok = True
        if broker.is_deleted():
            return HTTPNotFound(request=req)
        info = broker.get_info()
        headers = {
            'X-Container-Object-Count': info['object_count'],
            'X-Container-Bytes-Used': info['bytes_used'],
            'X-Timestamp': info['created_at'],
            'X-PUT-Timestamp': info['put_timestamp'],
        }
        headers.update(
            (key, value)
            for key, (value, timestamp) in broker.metadata.iteritems()
            if value != '' and (key.lower() in self.save_headers or
                                key.lower().startswith('x-container-meta-')))
        if get_param(req, 'format'):
            req.accept = FORMAT2CONTENT_TYPE.get(
                get_param(req, 'format').lower(), FORMAT2CONTENT_TYPE['plain'])
        try:
            headers['Content-Type'] = req.accept.best_match(
                [
                    'text/plain', 'application/json', 'application/xml',
                    'text/xml'
                ],
                default_match='text/plain')
        except AssertionError, err:
            return HTTPBadRequest(body='bad accept header: %s' % req.accept,
                                  content_type='text/plain',
                                  request=req)
        return HTTPNoContent(request=req, headers=headers, charset='utf-8')
Example #9
0
    def origin_db_get(self, env, req):
        """
        Handles GETs to the Origin database
        The only part of the path this pays attention to is the account.
        """
        try:
            vsn, account, junk = split_path(req.path, 2, 3,
                                                 rest_with_last=True)
        except ValueError:
            self.logger.debug("Invalid request: %s" % req.path)
            return HTTPBadRequest('Invalid request. '
                                  'URL format: /<api version>/<account>')
        if not account:
            return HTTPBadRequest('Invalid request. '
                                  'URL format: /<api version>/<account>')
        marker = get_param(req, 'marker', default='')
        list_format = get_param(req, 'format')
        if list_format:
            list_format = list_format.lower()
        enabled_only = None
        if get_param(req, 'enabled'):
            enabled_only = get_param(req, 'enabled').lower() in TRUE_VALUES
        limit = get_param(req, 'limit')
        if limit:
            try:
                limit = int(limit)
            except ValueError:
                self.logger.debug("Invalid limit: %s" % get_param(req, 'limit'))
                return HTTPBadRequest('Invalid limit, must be an integer')

        def get_listings(marker):
            listing_path = quote('/v1/%s/%s' % (self.origin_account, account))
            listing_path += '?format=json&marker=' + quote(marker)
            # no limit in request because may have to filter on cdn_enabled
            resp = make_pre_authed_request(env, 'GET',
                listing_path, agent='SwiftOrigin').get_response(self.app)
            resp_headers = {}
            listing_formatted = []
            if resp.status_int // 100 == 2:
                cont_listing = json.loads(resp.body)
                for listing_dict in cont_listing:
                    if limit is None or len(listing_formatted) < limit:
                        try:
                            formatted_data = self._parse_container_listing(
                                account, listing_dict, list_format,
                                only_cdn_enabled=enabled_only)
                            if formatted_data:
                                listing_formatted.append(formatted_data)
                        except InvalidContentType, e:
                            self.logger.exception(e)
                            continue
                    else:
                        break
                if cont_listing and not listing_formatted:
                    # there were rows returned but none matched enabled_only-
                    # requery with new marker
                    new_marker = cont_listing[-1]['name']
                    if isinstance(new_marker, unicode):
                        new_marker = new_marker.encode('utf-8')
                    return get_listings(new_marker)
            elif resp.status_int == 404:
                raise OriginDbNotFound()
Example #10
0
 try:
     drive, part, account, container, obj = split_path(
         unquote(req.path), 4, 5, True)
     validate_device_partition(drive, part)
 except ValueError, err:
     return jresponse('-1', 'bad request', req,400)
  
 if self.mount_check and not check_mount(self.root, drive):
     return jresponse('-1', 'insufficient storage', req,507) 
 broker = self._get_container_broker(drive, part, account, container)
 
 if broker.is_deleted():
     return jresponse('-1', 'not found', req,404) 
 
 try:
     path = get_param(req, 'path')
     prefix = get_param(req, 'prefix')
     delimiter = get_param(req, 'delimiter')
     if delimiter and (len(delimiter) > 1 or ord(delimiter) > 254):
         # delimiters can be made more flexible later
         return jresponse('-1', 'bad delimiter', req,412)
      
     marker = get_param(req, 'marker', '')
     end_marker = get_param(req, 'end_marker')
     limit = CONTAINER_LISTING_LIMIT
     given_limit = get_param(req, 'limit')
     if given_limit and given_limit.isdigit():
         limit = int(given_limit)
         if limit > CONTAINER_LISTING_LIMIT:
             bodyresp='Maximum limit is %d' % CONTAINER_LISTING_LIMIT
             return jresponse('-1', bodyresp, req,412)