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