def respond_with_html_bytes(request: Request, code: int, html_bytes: bytes) -> None: """ Sends HTML (encoded as UTF-8 bytes) as the response to the given request. Note that this adds clickjacking protection headers and finishes the request. Args: request: The http request to respond to. code: The HTTP response code. html_bytes: The HTML bytes to use as the response body. """ # could alternatively use request.notifyFinish() and flip a flag when # the Deferred fires, but since the flag is RIGHT THERE it seems like # a waste. if request._disconnected: logger.warning( "Not sending response to request %s, already disconnected.", request ) return None request.setResponseCode(code) request.setHeader(b"Content-Type", b"text/html; charset=utf-8") request.setHeader(b"Content-Length", b"%d" % (len(html_bytes),)) # Ensure this content cannot be embedded. set_clickjacking_protection_headers(request) request.write(html_bytes) finish_request(request)
def putDone( cls, result: None, # pylint: disable=unused-argument request: TwistedRequest) -> None: request.setResponseCode(201) request.setHeader(b'Content-Type', b'text/plain; charset=UTF-8') request.write(b'Artifact stored\n') request.finish()
def putFailed(cls, fail: Failure, request: TwistedRequest) -> None: ex = fail.value if isinstance(ex, ValueError): request.setResponseCode(415) request.setHeader(b'Content-Type', b'text/plain; charset=UTF-8') request.write((f'{ex}\n').encode()) request.finish() else: request.processingFailed(fail)
def return_html_error( f: failure.Failure, request: Request, error_template: Union[str, jinja2.Template], ) -> None: """Sends an HTML error page corresponding to the given failure. Handles RedirectException and other CodeMessageExceptions (such as SynapseError) Args: f: the error to report request: the failing request error_template: the HTML template. Can be either a string (with `{code}`, `{msg}` placeholders), or a jinja2 template """ if f.check(CodeMessageException): cme = f.value code = cme.code msg = cme.msg if isinstance(cme, RedirectException): logger.info("%s redirect to %s", request, cme.location) request.setHeader(b"location", cme.location) request.cookies.extend(cme.cookies) elif isinstance(cme, SynapseError): logger.info("%s SynapseError: %s - %s", request, code, msg) else: logger.error( "Failed handle request %r", request, exc_info=(f.type, f.value, f.getTracebackObject()), ) else: code = http.HTTPStatus.INTERNAL_SERVER_ERROR msg = "Internal server error" logger.error( "Failed handle request %r", request, exc_info=(f.type, f.value, f.getTracebackObject()), ) if isinstance(error_template, str): body = error_template.format(code=code, msg=html.escape(msg)) else: body = error_template.render(code=code, msg=msg) body_bytes = body.encode("utf-8") request.setResponseCode(code) request.setHeader(b"Content-Type", b"text/html; charset=utf-8") request.setHeader(b"Content-Length", b"%i" % (len(body_bytes), )) request.write(body_bytes) finish_request(request)
def _return_html_error(code: int, msg: str, request: Request): """Sends an HTML error page""" body = HTML_ERROR_TEMPLATE.format(code=code, msg=html.escape(msg)).encode("utf-8") request.setResponseCode(code) request.setHeader(b"Content-Type", b"text/html; charset=utf-8") request.setHeader(b"Content-Length", b"%i" % (len(body), )) request.write(body) try: request.finish() except RuntimeError as e: logger.info("Connection disconnected before response was written: %r", e)
def render_GET(self, request: TwistedRequest) -> object: presenter = self.presenter depth = len(request.prepath) - 1 styleURL = '../' * depth + styleRoot.relativeURL request.write(b'<!DOCTYPE html>\n') request.write(xhtml.html[ xhtml.head[fixedHeadItems, presenter.headItems(), xhtml.title[f'Report: {self.fileName}']].present( styleURL=styleURL), xhtml.body[xhtml.div(class_='body')[presenter.presentBody()]]]. flattenXML().encode()) request.finish() return NOT_DONE_YET
def _return_json(json_obj: Any, request: Request): json_bytes = json.dumps(json_obj).encode("utf-8") request.setHeader(b"Content-Type", b"application/json") request.setHeader(b"Content-Length", b"%d" % (len(json_bytes), )) request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate") request.setHeader(b"Access-Control-Allow-Origin", b"*") request.setHeader(b"Access-Control-Allow-Methods", b"GET, POST, PUT, DELETE, OPTIONS") request.setHeader( b"Access-Control-Allow-Headers", b"Origin, X-Requested-With, Content-Type, Accept, Authorization", ) request.write(json_bytes) try: request.finish() except RuntimeError as e: logger.info("Connection disconnected before response was written: %r", e)
async def render(f: AsyncRenderer[Res], self: Res, request: Request) -> None: request.setHeader("Content-Type", "application/json") try: result = await f(self, request) request.write(dict_to_json_bytes(result)) except MatrixRestError as e: request.setResponseCode(e.httpStatus) request.write( dict_to_json_bytes({ "errcode": e.errcode, "error": e.error })) except Exception: logger.exception("Request processing failed") request.setResponseCode(500) request.write( dict_to_json_bytes({ "errcode": "M_UNKNOWN", "error": "Internal Server Error" })) request.finish()
def process_later(request: Request): print("process_later called") request.write(b"later") # $ MISSING: responseBody=b"later" request.finish()
def render(self, request: Request): # $ requestHandler request.write( b"also now" ) # $ HttpResponse mimetype=text/html responseBody=b"also now" return b"" # $ HttpResponse mimetype=text/html responseBody=b""
async def _async_render_POST(self, request: Request) -> None: try: try: # TODO: we should really validate that this gives us a dict, and # not some other json value like str, list, int etc # json.loads doesn't allow bytes in Python 3.5 body: JsonDict = json_decoder.decode( request.content.read().decode("UTF-8")) except ValueError: request.setResponseCode(HTTPStatus.BAD_REQUEST) request.write( dict_to_json_bytes({ "errcode": "M_BAD_JSON", "error": "Malformed JSON" })) request.finish() return missing = [k for k in ("threepid", "mxid") if k not in body] if len(missing) > 0: request.setResponseCode(HTTPStatus.BAD_REQUEST) msg = "Missing parameters: " + (",".join(missing)) request.write( dict_to_json_bytes({ "errcode": "M_MISSING_PARAMS", "error": msg })) request.finish() return threepid = body["threepid"] mxid = body["mxid"] if "medium" not in threepid or "address" not in threepid: request.setResponseCode(HTTPStatus.BAD_REQUEST) request.write( dict_to_json_bytes({ "errcode": "M_MISSING_PARAMS", "error": "Threepid lacks medium / address", })) request.finish() return # We now check for authentication in two different ways, depending # on the contents of the request. If the user has supplied "sid" # (the Session ID returned by Sydent during the original binding) # and "client_secret" fields, they are trying to prove that they # were the original author of the bind. We then check that what # they supply matches and if it does, allow the unbind. # # However if these fields are not supplied, we instead check # whether the request originated from a homeserver, and if so the # same homeserver that originally created the bind. We do this by # checking the signature of the request. If it all matches up, we # allow the unbind. # # Only one method of authentication is required. if "sid" in body and "client_secret" in body: sid = body["sid"] client_secret = body["client_secret"] if not is_valid_client_secret(client_secret): request.setResponseCode(HTTPStatus.BAD_REQUEST) request.write( dict_to_json_bytes({ "errcode": "M_INVALID_PARAM", "error": "Invalid client_secret provided", })) request.finish() return valSessionStore = ThreePidValSessionStore(self.sydent) try: s = valSessionStore.getValidatedSession(sid, client_secret) except (IncorrectClientSecretException, InvalidSessionIdException): request.setResponseCode(HTTPStatus.UNAUTHORIZED) request.write( dict_to_json_bytes({ "errcode": "M_NO_VALID_SESSION", "error": "No valid session was found matching that sid and client secret", })) request.finish() return except SessionNotValidatedException: request.setResponseCode(HTTPStatus.FORBIDDEN) request.write( dict_to_json_bytes({ "errcode": "M_SESSION_NOT_VALIDATED", "error": "This validation session has not yet been completed", })) return if s.medium != threepid["medium"] or s.address != threepid[ "address"]: request.setResponseCode(HTTPStatus.FORBIDDEN) request.write( dict_to_json_bytes({ "errcode": "M_FORBIDDEN", "error": "Provided session information does not match medium/address combo", })) request.finish() return else: try: origin_server_name = ( await self.sydent.sig_verifier.authenticate_request( request, body)) except SignatureVerifyException as ex: request.setResponseCode(HTTPStatus.UNAUTHORIZED) request.write( dict_to_json_bytes({ "errcode": "M_FORBIDDEN", "error": str(ex) })) request.finish() return except NoAuthenticationError as ex: request.setResponseCode(HTTPStatus.UNAUTHORIZED) request.write( dict_to_json_bytes({ "errcode": "M_FORBIDDEN", "error": str(ex) })) request.finish() return except InvalidServerName as ex: request.setResponseCode(HTTPStatus.BAD_REQUEST) request.write( dict_to_json_bytes({ "errcode": "M_INVALID_PARAM", "error": str(ex) })) request.finish() return except (DNSLookupError, ConnectError, ResponseFailed) as e: msg = (f"Unable to contact the Matrix homeserver to " f"authenticate request ({type(e).__name__})") logger.warning(msg) request.setResponseCode(HTTPStatus.INTERNAL_SERVER_ERROR) request.write( dict_to_json_bytes({ "errcode": "M_UNKNOWN", "error": msg, })) request.finish() return except Exception: logger.exception( "Exception whilst authenticating unbind request") request.setResponseCode(HTTPStatus.INTERNAL_SERVER_ERROR) request.write( dict_to_json_bytes({ "errcode": "M_UNKNOWN", "error": "Internal Server Error" })) request.finish() return if not mxid.endswith(":" + origin_server_name): request.setResponseCode(HTTPStatus.FORBIDDEN) request.write( dict_to_json_bytes({ "errcode": "M_FORBIDDEN", "error": "Origin server name does not match mxid", })) request.finish() return self.sydent.threepidBinder.removeBinding(threepid, mxid) request.write(dict_to_json_bytes({})) request.finish() except Exception as ex: logger.exception("Exception whilst handling unbind") request.setResponseCode(HTTPStatus.INTERNAL_SERVER_ERROR) request.write( dict_to_json_bytes({ "errcode": "M_UNKNOWN", "error": str(ex) })) request.finish()
def write(self, bytes): invoked.append(get_ident()) return Request.write(self, bytes)