def login(request: HTTPRequest) -> HTTPResponse: """ - login to welcome page - if it's the first visit, show login page - otherwise, keep name from cookie & redirect to /welcome """ if request.method == "GET": body = render("login.html", {}) return HTTPResponse(body=body) elif request.method == "POST": # get username from input name in POST request body post_params = urllib.parse.parse_qs(request.body.decode()) username = post_params["username"][0] email = post_params["email"][0] cookies = [ Cookie(name="username", value=username, max_age=30), Cookie(name="email", value=email, max_age=30), ] return HTTPResponse(status_code=302, headers={"Location": "/welcome"}, cookies=cookies)
def build_response_header(self, response: HTTPResponse, request: HTTPRequest) -> str: """ - build response header """ # get Content-Type from request data ## if the Content-Type is not designated if response.content_type is None: # get extension from path if "." in request.path: ext = request.path.rsplit(".", maxsplit=1)[-1] # get MIME-Type from ext # give it octet-stream if the ext is not corresponded response.content_type = self.MIME_TYPES.get( ext, "application/octet-stream") else: # treat it as html if no extension response.content_type = "text/html; charset=UTF-8" # create response header response_header = "" response_header += f"Date: {datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')}\r\n" response_header += "Host: NinjaServer/0.1\r\n" response_header += f"Content-Length: {len(response.body)}\r\n" response_header += "Connection: Close\r\n" response_header += f"Content-type: {response.content_type}\r\n" # create multiple cookie headers for cookie in response.cookies: cookie_header = f"Set-Cookie: {cookie.name}={cookie.value}" if cookie.expires is not None: cookie_header += f"; Expires={cookie.expires.strftime('%a, %d %b %Y %H:%M:%S GMT')}" if cookie.max_age is not None: cookie_header += f"; Max_Age={cookie.max_age}" if cookie.domain: cookie_header += f"; Domain={cookie.domain}" if cookie.path: cookie_header += f"; Path={cookie.path}" if cookie.secure: cookie_header += f"; Secure" if cookie.http_only: cookie_header += f"; HttpOnly" response_header += cookie_header + "\r\n" # other custom headers attributes in response object for header_name, header_value in response.headers.items(): response_header += f"{header_name}: {header_value}\r\n" return response_header
def user_profile(request: HTTPRequest) -> HTTPResponse: """ - return REST style user resource """ context = {"user_id": request.params["user_id"]} body = render("user_profile.html", context) return HTTPResponse(body=body)
def parameters(request: HTTPRequest) -> HTTPResponse: """ - show POST parameters in HTTP request """ # return 405 error if request.method == "GET": body = b"<html><body><h1>405 Method Not Allowed!</h1></body></html>" return HTTPResponse(body=body, status_code=405) elif request.method == "POST": # decode the body & parse decoded query parameters(str) context = {"params": urllib.parse.parse_qs(request.body.decode())} body = render("parameters.html", context) return HTTPResponse(body=body)
def now(request: HTTPRequest) -> HTTPResponse: """ - create dynamic HTML that shows now date """ context = {"now": datetime.now()} body = render("now.html", context) return HTTPResponse(body=body)
def welcome(request: HTTPRequest) -> HTTPResponse: """ - show welcome page to identified user who has input user name in login page """ # if not been loged in , redirect to /login if "username" not in request.cookies: return HTTPResponse(status_code=302, headers={"Location": "/login"}) username = request.cookies["username"] email = request.cookies["email"] body = render("welcome.html", context={ "username": username, "email": email }) return HTTPResponse(body=body)
def show_request(request: HTTPRequest) -> HTTPResponse: """ - create dynamic HTML that shows contents of HTTP request """ context = { "request": request, "headers": pformat(request.headers), "body": request.body.decode("utf-8", "ignore") } body = render("show_request.html", context) return HTTPResponse(body=body)
def static(request: HTTPRequest) -> HTTPResponse: """ - get response from static file """ try: static_root = getattr(settings, "STATIC_ROOT") # delete front / and make it relative path relative_path = request.path.lstrip("/") # get the file path static_file_path = os.path.join(static_root, relative_path) with open(static_file_path, "rb") as f: response_body = f.read() content_type = None return HTTPResponse( body=response_body, content_type=content_type, status_code=200 ) # TODO: distinguish more detailed sub class exception(e.g. FileNotFound, ISADirectory..) except OSError: # return 404 error in case of file not found traceback.print_exc() response_body = b"<html><body><h1>404 Not Found!</h1></body></html>" content_type = "text/html;" return HTTPResponse( body=response_body, content_type=content_type, status_code=404 )
def set_cookie(request: HTTPRequest) -> HTTPResponse: """ - set cookie in response header """ return HTTPResponse(cookies=[Cookie(name="username", value="MASA")])