Esempio n. 1
0
    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
Esempio n. 2
0
                        iter_hook=sleep)
        
        if file.is_deleted():
            return jresponse('-1', 'not found', request,404)
        try:
            file_size = file.get_data_file_size()
        except (DiskFileError, DiskFileNotExist):
            file.quarantine()
            return jresponse('-1', 'not found', request,404)

        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):