def _setup(self):
if self.skip: # Don't bother
return
for op, arg in list(self.funcs.items()):
try:
op(self, arg)
except ConfigurationError as err:
_txt = "Configuration error: {}".format(err)
self.conv.events.store(EV_EXCEPTION, _txt)
raise cherrypy.HTTPError(message=_txt)
except Exception as err:
_txt = "Can't do {}".format(op)
self.conv.events.store(EV_EXCEPTION, _txt)
raise cherrypy.HTTPError(message=_txt)
# self.conv.events.store(EV_OP_ARGS, self.op_args)
python类HTTPError()的实例源码
def POST(self):
""" Deploy on remote host(s). """
targets = cherrypy.request.json.pop('targets', None)
if not targets or not isinstance(targets, list):
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_NO_TARGET)
role = cherrypy.request.json.pop('role', None)
if not role or not isinstance(role, six.text_type):
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_ROLE)
extra_vars = cherrypy.request.json.pop('extra_vars', dict())
if not isinstance(extra_vars, dict):
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_EXTRAVARS)
partial = cherrypy.request.json.pop('partial', None)
if partial != None:
if not isinstance(partial, six.text_type) or partial.strip() == "":
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_PARTIAL)
jid = self.handle(targets, role, extra_vars, partial, async=True)
return response(status.CREATED, dict(jid=jid))
def handle(self, *args, **kwargs):
""" Handle api request by invoke `runner.handle()`.
All exception raised by runner will be catched here, and convert them
into cherrypy `HTTPError()` with corresponding status code and message.
"""
try:
return self._runner.handle(*args, **kwargs)
except JobDeleteError:
raise cherrypy.HTTPError(status.BAD_REQUEST, excinst().message)
except JobConflictError:
raise cherrypy.HTTPError(status.CONFLICT, excinst().message)
except JobNotSupportedError:
raise cherrypy.HTTPError(status.INTERNAL_SERVER_ERROR, excinst().message)
except (JobNotExistsError, ExecutorNoMatchError):
raise cherrypy.HTTPError(status.NOT_FOUND, excinst().message)
except:
cherrypy.log("error response 500", traceback=True)
raise cherrypy.HTTPError(status.INTERNAL_SERVER_ERROR)
def GET(self, **params):
""" Manipulate service on remote host. """
name = params.pop('name', None)
state = parse_params_int(params, 'state')
target = parse_params_target(params)
if name == None or state == None:
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_SERVPARAMS)
name = name.lower()
start, restart = _state_parse(state)
graceful = parse_params_bool(params, 'graceful')
result = self.handle(target, name, start, restart, graceful)
if not result:
raise cherrypy.HTTPError(status.NOT_FOUND, ERR_NO_MATCH)
else:
return response(status.OK, result)
def POST(self):
""" Manipulate service on remote host(s). """
targets = cherrypy.request.json.pop('targets', None)
if not targets or not isinstance(targets, list):
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_NO_TARGET)
name = cherrypy.request.json.pop('name', None)
state = cherrypy.request.json.pop('state', None)
if name == None or state == None:
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_SERVPARAMS)
name = name.lower()
start, restart = _state_parse(state)
graceful = cherrypy.request.json.pop('graceful', False)
jid = self.handle(targets, name, start, restart, graceful, async=True)
return response(status.CREATED, dict(jid=jid))
def POST(self):
message = cherrypy.request.json.get('message', None)
name = cherrypy.request.json.get('name', None)
auth_token = cherrypy.request.headers.get('Http-Auth', None)
if auth_token != token:
raise cherrypy.HTTPError(401, "Unauthorized")
elif not message:
raise cherrypy.HTTPError(422, "Message is missing")
elif not name:
raise cherrypy.HTTPError(422, "Name is missing")
elif name not in allowed_metadata:
raise cherrypy.HTTPError(422, name + " is not an allowed metadata")
else:
extractor = MetadataExtractor(message, [name])
return extractor.perform()
def index(self, **kwargs):
if cherrypy.request.process_request_body is True:
_json_doc = cherrypy.request.body.read()
else:
raise cherrypy.HTTPError(400, 'Missing Client registration body')
if _json_doc == b'':
raise cherrypy.HTTPError(400, 'Missing Client registration body')
_args = json.loads(as_unicode(_json_doc))
_mds = MetadataStatement(**_args)
try:
_mds.verify()
except (MessageException, VerificationError) as err:
raise cherrypy.CherryPyException(str(err))
else:
_jwt = self.signer.create_signed_metadata_statement(_mds,
single=True)
cherrypy.response.headers['Content-Type'] = 'application/jwt'
return as_bytes(_jwt)
def register(self, url):
if cherrypy.request.process_request_body is True:
_json_doc = cherrypy.request.body.read()
else:
raise cherrypy.HTTPError(400, 'Missing Client registration body')
if _json_doc == b'':
raise cherrypy.HTTPError(400, 'Missing Client registration body')
_args = json.loads(as_unicode(_json_doc))
_mds = MetadataStatement(**_args)
try:
_mds.verify()
except (MessageException, VerificationError) as err:
raise cherrypy.CherryPyException(str(err))
else:
res = requests.post(url, json=_mds.to_json())
if 200 <= res.status_code < 300:
self.signer.metadata_statements[url] = res.text
cherrypy.response.headers['Content-Type'] = 'application/jwt'
return as_bytes(res.text)
else:
raise cherrypy.HTTPError(message=res.text)
def index(self, resource='', rel=''):
logger.debug('webfinger request: res={}, rel={}'.format(resource, rel))
if rel != 'http://openid.net/specs/connect/1.0/issuer':
logger.error('unknown rel')
raise cherrypy.HTTPError(400, "Unknown 'rel")
cnf = cherrypy.request.config
subj = resource
_base = cnf['base_url']
if resource.startswith('http'):
assert resource.startswith(_base)
elif resource.startswith('acct:'):
loc, dom = resource[5:].split('@', 1)
r = urlparse(_base)
try:
assert dom == r.netloc
except AssertionError:
raise cherrypy.HTTPError(400, 'Not my domain')
else:
raise cherrypy.HTTPError(400, "URI type I don't support")
return as_bytes(self.srv.response(subj, _base))
def token(self, **kwargs):
if cherrypy.request.method == "OPTIONS":
cherrypy_cors.preflight(
allowed_methods=["POST"], origins='*',
allowed_headers=['Authorization', 'content-type'])
else:
logger.debug('AccessTokenRequest')
try:
authn = cherrypy.request.headers['Authorization']
except KeyError:
authn = None
logger.debug('Authorization: {}'.format(authn))
try:
resp = self.op.token_endpoint(kwargs, authn, 'dict')
except Exception as err:
raise cherrypy.HTTPError(message=str(err))
else:
return conv_response(resp)
def index(self, uid='', iss=''):
link = ''
if iss:
link = iss
elif uid:
try:
link = self.rph.find_srv_discovery_url(
resource="acct:{}".format(uid))
except requests.ConnectionError:
raise cherrypy.HTTPError(
message="Webfinger lookup failed, connection error")
else:
fname = os.path.join(self.html_home, 'opbyuid.html')
return as_bytes(open(fname, 'r').read())
if link:
resp_headers = self.rph.begin(link)
raise cherrypy.HTTPRedirect(resp_headers['Location'])
def acb(self, op_hash='', **kwargs):
try:
rp = self.rph.issuer2rp[self.rph.hash2issuer[op_hash]]
except KeyError:
raise cherrypy.HTTPError(400,
"Response to something I hadn't asked for")
res = self.rph.phaseN(rp, kwargs)
if res[0] is True:
fname = os.path.join(self.html_home, 'opresult.html')
_pre_html = open(fname, 'r').read()
_html = _pre_html.format(result=create_result_page(*res[1:]))
return as_bytes(_html)
else:
raise cherrypy.HTTPError(400, res[1])
def run(self):
request = cherrypy.serving.request
response = cherrypy.serving.response
path = request.path_info
if path.endswith('login_screen'):
self._debug_message('routing %(path)r to login_screen', locals())
response.body = self.login_screen()
return True
elif path.endswith('do_login'):
if request.method != 'POST':
response.headers['Allow'] = 'POST'
self._debug_message('do_login requires POST')
raise cherrypy.HTTPError(405)
self._debug_message('routing %(path)r to do_login', locals())
return self.do_login(**request.params)
elif path.endswith('do_logout'):
if request.method != 'POST':
response.headers['Allow'] = 'POST'
raise cherrypy.HTTPError(405)
self._debug_message('routing %(path)r to do_logout', locals())
return self.do_logout(**request.params)
else:
self._debug_message('No special path, running do_check')
return self.do_check()
def run(self, point):
"""Execute all registered Hooks (callbacks) for the given point."""
exc = None
hooks = self[point]
hooks.sort()
for hook in hooks:
# Some hooks are guaranteed to run even if others at
# the same hookpoint fail. We will still log the failure,
# but proceed on to the next hook. The only way
# to stop all processing from one of these hooks is
# to raise SystemExit and stop the whole server.
if exc is None or hook.failsafe:
try:
hook()
except (KeyboardInterrupt, SystemExit):
raise
except (cherrypy.HTTPError, cherrypy.HTTPRedirect,
cherrypy.InternalRedirect):
exc = sys.exc_info()[1]
except:
exc = sys.exc_info()[1]
cherrypy.log(traceback=True, severity=40)
if exc:
raise exc
def process_query_string(self):
"""Parse the query string into Python structures. (Core)"""
try:
p = httputil.parse_query_string(
self.query_string, encoding=self.query_string_encoding)
except UnicodeDecodeError:
raise cherrypy.HTTPError(
404, 'The given query string could not be processed. Query '
'strings for this resource must be encoded with %r.' %
self.query_string_encoding)
# Python 2 only: keyword arguments must be byte strings (type 'str').
if six.PY2:
for key, value in p.items():
if isinstance(key, six.text_type):
del p[key]
p[key.encode(self.query_string_encoding)] = value
self.params.update(p)
def decode_entity(self , value):
"""Return a given byte encoded value as a string"""
for charset in self.attempt_charsets:
try:
value = value.decode(charset)
except UnicodeDecodeError:
pass
else:
self.charset = charset
return value
else:
raise cherrypy.HTTPError(
400,
'The request entity could not be decoded. The following '
'charsets were attempted: %s' % repr(self.attempt_charsets)
)
def run(self):
request = cherrypy.serving.request
response = cherrypy.serving.response
path = request.path_info
if path.endswith('login_screen'):
self._debug_message('routing %(path)r to login_screen', locals())
response.body = self.login_screen()
return True
elif path.endswith('do_login'):
if request.method != 'POST':
response.headers['Allow'] = "POST"
self._debug_message('do_login requires POST')
raise cherrypy.HTTPError(405)
self._debug_message('routing %(path)r to do_login', locals())
return self.do_login(**request.params)
elif path.endswith('do_logout'):
if request.method != 'POST':
response.headers['Allow'] = "POST"
raise cherrypy.HTTPError(405)
self._debug_message('routing %(path)r to do_logout', locals())
return self.do_logout(**request.params)
else:
self._debug_message('No special path, running do_check')
return self.do_check()
def run(self, point):
"""Execute all registered Hooks (callbacks) for the given point."""
exc = None
hooks = self[point]
hooks.sort()
for hook in hooks:
# Some hooks are guaranteed to run even if others at
# the same hookpoint fail. We will still log the failure,
# but proceed on to the next hook. The only way
# to stop all processing from one of these hooks is
# to raise SystemExit and stop the whole server.
if exc is None or hook.failsafe:
try:
hook()
except (KeyboardInterrupt, SystemExit):
raise
except (cherrypy.HTTPError, cherrypy.HTTPRedirect,
cherrypy.InternalRedirect):
exc = sys.exc_info()[1]
except:
exc = sys.exc_info()[1]
cherrypy.log(traceback=True, severity=40)
if exc:
raise exc
def process_query_string(self):
"""Parse the query string into Python structures. (Core)"""
try:
p = httputil.parse_query_string(
self.query_string, encoding=self.query_string_encoding)
except UnicodeDecodeError:
raise cherrypy.HTTPError(
404, "The given query string could not be processed. Query "
"strings for this resource must be encoded with %r." %
self.query_string_encoding)
# Python 2 only: keyword arguments must be byte strings (type 'str').
if six.PY2:
for key, value in p.items():
if isinstance(key, six.text_type):
del p[key]
p[key.encode(self.query_string_encoding)] = value
self.params.update(p)
def setup_server():
class Root:
@cherrypy.expose
def resource(self):
return "Oh wah ta goo Siam."
@cherrypy.expose
def fail(self, code):
code = int(code)
if 300 <= code <= 399:
raise cherrypy.HTTPRedirect([], code)
else:
raise cherrypy.HTTPError(code)
@cherrypy.expose
# In Python 3, tools.encode is on by default
@cherrypy.config(**{'tools.encode.on': True})
def unicoded(self):
return ntou('I am a \u1ee4nicode string.', 'escape')
conf = {'/': {'tools.etags.on': True,
'tools.etags.autotags': True,
}}
cherrypy.tree.mount(Root(), config=conf)
def decode_entity(self , value):
"""Return a given byte encoded value as a string"""
for charset in self.attempt_charsets:
try:
value = value.decode(charset)
except UnicodeDecodeError:
pass
else:
self.charset = charset
return value
else:
raise cherrypy.HTTPError(
400,
"The request entity could not be decoded. The following "
"charsets were attempted: %s" % repr(self.attempt_charsets)
)
def catalog_1(self, *tokens):
"""Outputs the contents of the specified catalog file, using the
name in the request path, directly to the client."""
try:
name = tokens[0]
except IndexError:
raise cherrypy.HTTPError(http_client.FORBIDDEN,
_("Directory listing not allowed."))
try:
fpath = self.repo.catalog_1(name,
pub=self._get_req_pub())
except srepo.RepositoryError as e:
# Treat any remaining repository error as a 404, but
# log the error and include the real failure
# information.
cherrypy.log("Request failed: {0}".format(str(e)))
raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e))
self.__set_response_expires("catalog", 86400, 86400)
return serve_file(fpath, "text/plain; charset=utf-8")
def manifest_1(self, *tokens):
"""Outputs the contents of the manifest or uploads the
manifest."""
method = cherrypy.request.method
if method == "GET":
return self.manifest_0(*tokens)
elif method in ("POST", "PUT"):
return self.__upload_manifest(*tokens)
raise cherrypy.HTTPError(http_client.METHOD_NOT_ALLOWED,
"{0} is not allowed".format(method))
# We need to prevent cherrypy from processing the request body so that
# manifest can parse the request body itself. In addition, we also need
# to set the timeout higher since the default is five minutes; not
# really enough for a slow connection to upload content.
def file_0(self, *tokens):
"""Outputs the contents of the file, named by the SHA-1 hash
name in the request path, directly to the client."""
try:
fhash = tokens[0]
except IndexError:
fhash = None
try:
fpath = self.repo.file(fhash, pub=self._get_req_pub())
except srepo.RepositoryFileNotFoundError as e:
raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e))
except srepo.RepositoryError as e:
# Treat any remaining repository error as a 404, but
# log the error and include the real failure
# information.
cherrypy.log("Request failed: {0}".format(str(e)))
raise cherrypy.HTTPError(http_client.NOT_FOUND, str(e))
self.__set_response_expires("file", 86400*365, 86400*365)
return serve_file(fpath, "application/data")
def file_1(self, *tokens):
"""Outputs the contents of the file, named by the SHA hash
name in the request path, directly to the client."""
method = cherrypy.request.method
if method == "GET":
return self.file_0(*tokens)
elif method in ("POST", "PUT"):
return self.__upload_file(*tokens)
raise cherrypy.HTTPError(http_client.METHOD_NOT_ALLOWED,
"{0} is not allowed".format(method))
# We need to prevent cherrypy from processing the request body so that
# file can parse the request body itself. In addition, we also need to
# set the timeout higher since the default is five minutes; not really
# enough for a slow connection to upload content.
def abandon_0(self, *tokens):
"""Aborts an in-flight transaction for the Transaction ID
specified in the request path. Returns no output."""
try:
# cherrypy decoded it, but we actually need it encoded.
trans_id = quote(tokens[0], "")
except IndexError:
trans_id = None
try:
self.repo.abandon(trans_id)
except srepo.RepositoryError as e:
# Assume a bad request was made. A 404 can't be
# returned here as misc.versioned_urlopen will interpret
# that to mean that the server doesn't support this
# operation.
raise cherrypy.HTTPError(http_client.BAD_REQUEST, str(e))
def make(self, *args, **kwargs):
if not is_logged_in:
raise cherrypy.HTTPError(401)
# cd into the target directory
sesh_id = os.path.basename(cherrypy.request.cookie["sesh_id"].value)
rate_limited_long(sesh_id)
errored = False
try:
output = subprocess.check_output (["make"], cwd=HOME+sesh_id, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
output = e.output
errored = True
fl = open(HOME+sesh_id+"/build.log", "w")
fl.write(output);
fl.close()
if errored:
raise cherrypy.HTTPError(422)
return output
def _check_request(self):
method = cherrypy.request.method.upper()
headers = cherrypy.request.headers
# Fail for other methods than get or head
if method not in ("GET", "HEAD"):
raise cherrypy.HTTPError(405)
# Error if the requester is not allowed
# for now this is a simple check just checking if the useragent matches Kodi
user_agent = headers['User-Agent'].lower()
if not ("kodi" in user_agent or "osmc" in user_agent):
raise cherrypy.HTTPError(403)
return method
def GET(self, **params):
""" Work on remote host (block). """
target = parse_params_target(params)
result = self.handle(target)
if not result:
raise cherrypy.HTTPError(status.NOT_FOUND, ERR_NO_MATCH)
else:
return response(status.OK, result)
def GET(self, **params):
""" Execute command on remote host. """
target = parse_params_target(params)
cmd = params.pop('cmd', None)
if cmd == None:
raise cherrypy.HTTPError(status.BAD_REQUEST, ERR_BAD_SERVPARAMS)
cmd = unquote(cmd)
result = self.handle(target, cmd)
if not result:
raise cherrypy.HTTPError(status.NOT_FOUND, ERR_NO_MATCH)
else:
return response(status.OK, result)