def get_container_info(self, app): """ get_container_info will return a result dict of get_container_info from the backend Swift. :returns: a dictionary of container info from swift.controllers.base.get_container_info :raises: NoSuchBucket when the container doesn't exist :raises: InternalError when the request failed without 404 """ if self.is_authenticated: # if we have already authenticated, yes we can use the account # name like as AUTH_xxx for performance efficiency sw_req = self.to_swift_req(app, self.container_name, None) info = get_container_info(sw_req.environ, app) if is_success(info['status']): return info elif info['status'] == 404: raise NoSuchBucket(self.container_name) else: raise InternalError( 'unexpected status code %d' % info['status']) else: # otherwise we do naive HEAD request with the authentication resp = self.get_response(app, 'HEAD', self.container_name, '') return headers_to_container_info( resp.sw_headers, resp.status_int) # pylint: disable-msg=E1101
def _get_response(self, app, method, container, obj, headers=None, body=None, query=None): """ Calls the application with this request's environment. Returns a Response object that wraps up the application's result. """ sw_req = self.to_swift_req(method, container, obj, headers=headers, body=body, query=query) if CONF.s3_acl: sw_req.environ['swift_owner'] = True # needed to set ACL sw_req.environ['swift.authorize_override'] = True sw_req.environ['swift.authorize'] = lambda req: None sw_resp = sw_req.get_response(app) resp = Response.from_swift_resp(sw_resp) status = resp.status_int # pylint: disable-msg=E1101 if CONF.s3_acl: resp.bucket_acl = decode_acl('container', resp.sysmeta_headers) resp.object_acl = decode_acl('object', resp.sysmeta_headers) if not self.user_id: if 'HTTP_X_USER_NAME' in sw_resp.environ: # keystone self.user_id = \ utf8encode("%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_USER_NAME'])) else: # tempauth self.user_id = self.access_key success_codes = self._swift_success_codes(method, container, obj) error_codes = self._swift_error_codes(method, container, obj) if status in success_codes: return resp err_msg = resp.body if status in error_codes: err_resp = \ error_codes[sw_resp.status_int] # pylint: disable-msg=E1101 if isinstance(err_resp, tuple): raise err_resp[0](*err_resp[1:]) else: raise err_resp() if status == HTTP_BAD_REQUEST: raise BadSwiftRequest(err_msg) if status == HTTP_UNAUTHORIZED: raise SignatureDoesNotMatch() if status == HTTP_FORBIDDEN: raise AccessDenied() raise InternalError('unexpected status code %d' % status)
def __call__(self, env, start_response): try: req_class = get_request_class(env) req = req_class(env, self.app, self.slo_enabled) resp = self.handle_request(req) except NotS3Request: resp = self.app except ErrorResponse as err_resp: if isinstance(err_resp, InternalError): LOGGER.exception(err_resp) resp = err_resp except Exception as e: LOGGER.exception(e) resp = InternalError(reason=e) if isinstance(resp, ResponseBase) and 'swift.trans_id' in env: resp.headers['x-amz-id-2'] = env['swift.trans_id'] resp.headers['x-amz-request-id'] = env['swift.trans_id'] return resp(env, start_response)
def _get_response(self, app, method, container, obj, headers=None, body=None, query=None): """ Calls the application with this request's environment. Returns a Response object that wraps up the application's result. """ method = method or self.environ['REQUEST_METHOD'] if container is None: container = self.container_name if obj is None: obj = self.object_name sw_req = self.to_swift_req(method, container, obj, headers=headers, body=body, query=query) sw_resp = sw_req.get_response(app) resp = Response.from_swift_resp(sw_resp) status = resp.status_int # pylint: disable-msg=E1101 if not self.user_id: if 'HTTP_X_USER_NAME' in sw_resp.environ: # keystone self.user_id = \ utf8encode("%s:%s" % (sw_resp.environ['HTTP_X_TENANT_NAME'], sw_resp.environ['HTTP_X_USER_NAME'])) else: # tempauth self.user_id = self.access_key success_codes = self._swift_success_codes(method, container, obj) error_codes = self._swift_error_codes(method, container, obj) if status in success_codes: return resp err_msg = resp.body if status in error_codes: err_resp = \ error_codes[sw_resp.status_int] # pylint: disable-msg=E1101 if isinstance(err_resp, tuple): raise err_resp[0](*err_resp[1:]) else: raise err_resp() if status == HTTP_BAD_REQUEST: raise BadSwiftRequest(err_msg) if status == HTTP_UNAUTHORIZED: raise SignatureDoesNotMatch() if status == HTTP_FORBIDDEN: raise AccessDenied() raise InternalError('unexpected status code %d' % status)
def __call__(self, env, start_response): req = None tenant = None bucket_owner = 'undefined' bucket_ts = None try: s3_env = env.copy() if 'RAW_PATH_INFO' not in s3_env: # emulate raw path info for older eventlet s3_env['RAW_PATH_INFO'] = quote(s3_env['PATH_INFO']) req = S3Request(s3_env) tenant, user_id, bucket_owner, bucket_ts = \ req.get_basic_info(self.app) resp = self.handle_request(req) try: if bucket_owner == 'undefined' and req.container_name: bucket_owner = req.get_bucket_owner(self.app) if not bucket_ts and req.container_name: bucket_ts = req.get_container_ts(self.app) except Exception: pass except NotS3Request: resp = self.app except S3ErrorResponse as err_resp: if isinstance(err_resp, InternalError): self.logger.exception(err_resp) resp = err_resp except Exception as e: self.logger.exception(e) resp = InternalError(reason=e) if isinstance(resp, Response) and 'swift.trans_id' in env: resp.headers['x-amz-id-2'] = env['swift.trans_id'] resp.headers['x-amz-request-id'] = env['swift.trans_id'] # TODO: should we set loginfo in Request class? log_info = env.setdefault('swift.log_info', []) if req and tenant and bucket_owner != 'undefined' and bucket_ts: log_info.append('bucket_owner:' + bucket_owner) log_info.append('requester:' + user_id) log_info.append('bucket:' + req.container_name) log_info.append('bucket_ts:' + str(bucket_ts)) log_info.append('tenant:' + tenant) if req.object_name: log_info.append('key:' + req.object_name) if req.object_size is not None: log_info.append('object_size:' + str(req.object_size)) if isinstance(resp, S3Response) and resp.versioned: # FIXME: cleanup from swift3.request import VersionId version_id = str(VersionId(resp.object_timestamp)) log_info.append('version_id:' + version_id) log_info.append('resource_type:' + req.get_controller().get_resource_type()) if isinstance(resp, S3ErrorResponse): log_info.append('error_code:' + resp.__class__.__name__) env['swift.leave_relative_location'] = True return resp(env, start_response)