コード例 #1
0
ファイル: obj.py プロジェクト: sun7shines/Cloudfs
    def GETorHEAD(self, req):
        
        """Handle HTTP GET or HEAD requests."""
        
        partition, nodes = self.app.object_ring.get_nodes(self.account_name, self.container_name, self.object_name)
        shuffle(nodes)
        resp = self.GETorHEAD_base(req, _('Object'), partition,
                self.iter_nodes(partition, nodes, self.app.object_ring),
                req.path_info, len(nodes))
        
        large_object = None
        range_flag = False
        
        if config_true_value(resp.headers.get('x-static-large-object')) and \
                req.GET.get('multipart-manifest') != 'get' and \
                self.app.allow_static_large_object:
            range_flag = True
            large_object = 'SLO'
            listing_page1 = ()
            listing = []
            lcontainer = None  # container name is included in listing
            if resp.status_int == HTTP_OK and \
                    req.method == 'GET' and not req.range:
                try:
                    listing = json.loads(resp.body)
                except ValueError:
                    listing = []
            else:
                # need to make a second request to get whole manifest
                new_req = req.copy_get()
                new_req.method = 'GET'
                new_req.range = None
                
                new_resp = self.GETorHEAD_base(
                    new_req, _('Object'), partition,
                    self.iter_nodes(partition, nodes, self.app.object_ring),
                    req.path_info, len(nodes))
                if new_resp.status_int // 100 == 2:
                    try:
                        listing = json.loads(new_resp.body)
                    except ValueError:
                        listing = []
                else:
                    return jresponse('-1',"Unable to load SLO manifest", req,503)

        if large_object:
            if len(listing_page1) >= CONTAINER_LISTING_LIMIT:
                hrange = None
                if req.headers.get('range') and range_flag:
                    hrange = Range(req.headers.get('range'))
                    
                resp = HResponse(headers=resp.headers, request=req,
                                conditional_response=True,range=hrange)
                if req.method == 'HEAD':
                    
                    def head_response(environ, start_response):
                        resp(environ, start_response)
                        return iter([])

                    head_response.status_int = resp.status_int
                    return head_response
                else:
                    resp.app_iter = SegmentedIterable(
                        self, lcontainer, listing, resp,
                        is_slo=(large_object == 'SLO'))

            else:
                
                if listing:
                    listing = list(listing)
                    try:
                        content_length = sum(o['bytes'] for o in listing)
                        
                        etag = md5(
                            ''.join(o['hash'] for o in listing)).hexdigest()
                    except KeyError:
                        return jresponse('-1', 'Invalid Manifest File', req,500)

                else:
                    content_length = 0
                    
                    etag = md5().hexdigest()
                
                hrange = None
                if req.headers.get('range') and range_flag:
                    hrange = Range(req.headers.get('range'))
                resp = HResponse(headers=resp.headers, request=req,
                                conditional_response=True,range=hrange)
                
                resp.app_iter = SegmentedIterable(
                    self, lcontainer, listing, resp,
                    is_slo=(large_object == 'SLO'))
                resp.content_length = content_length
                
                resp.etag = etag
            resp.headers['accept-ranges'] = 'bytes'
            # In case of a manifest file of nonzero length, the
            # backend may have sent back a Content-Range header for
            # the manifest. It's wrong for the client, though.
            resp.content_range = None
                     
        return resp
コード例 #2
0
ファイル: server.py プロジェクト: sun7shines/Cloudfs
        range = None
        if request.headers.get('range') and not file.metadata.get('X-Static-Large-Object'):
            # range for plain file,not slo
            range = Range(request.headers.get('range'))
            
        response = HResponse(app_iter=file,
                        request=request, conditional_response=True,range=range)
    
        for key, value in file.metadata.iteritems():
            if key.lower().startswith('x-object-meta-') or \
                    key.lower() in self.allowed_headers:
                response.headers[key] = value
    
        
        response.content_length = file_size
        response.etag = file.metadata['ETag']
        
        return request.get_response(response)

    @public
    def HEAD(self, request):
        
        try:
            device, partition, account, container, obj = \
                split_path(unquote(request.path), 5, 5, True)
            validate_device_partition(device, partition)
        except ValueError, err:
            return jresponse('-1', 'bad request', request,400)
        
        if self.mount_check and not check_mount(self.devices, device):
            return jresponse('-1', 'insufficient storage', request,507)