//! response handles the incoming request parsed `HTTPRequest` //! it will check if the `HTTPRequest` is valid and build an HTTPResponse corresponding to the HTTP //! message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages //! NOTE: only few parts of the specification has been implemented use json; use crate::handlers::request::{HTTPRequest, HTTPVersion}; enum HTTPStatusCode { Http200, Http400, Http404, Http500, } impl Into for HTTPStatusCode { fn into(self) -> String { match self { Self::Http200 => "200".to_string(), Self::Http400 => "400".to_string(), Self::Http404 => "404".to_string(), Self::Http500 => "500".to_string(), } } } pub struct HTTPStatusLine { version: HTTPVersion, status_code: HTTPStatusCode, } impl Default for HTTPStatusLine { fn default() -> HTTPStatusLine { HTTPStatusLine { version: HTTPVersion::Http1_1, status_code: HTTPStatusCode::Http400, } } } impl Into for HTTPStatusLine { fn into(self) -> String { let version: String = self.version.into(); let status_code: String = self.status_code.into(); format! {"{} {}", version, status_code} } } pub struct HTTPResponse { status_line: HTTPStatusLine, body: json::JsonValue, } impl Default for HTTPResponse { fn default() -> Self { HTTPResponse { status_line: HTTPStatusLine::default(), body: json::parse(r#"{"error": "the incoming request is not valid"}"#).unwrap(), } } } impl From for HTTPResponse { fn from(request: HTTPRequest) -> Self { let mut response = HTTPResponse::default(); if !request.is_valid() { return response; } let body = json::parse( r#"{"token": "header.payload.signature", "refresh": "header.payload.signature"}"#, ) .unwrap(); response.status_line.version = request.start_line.version; response.status_line.status_code = HTTPStatusCode::Http200; response.body = body; response } } impl Into for HTTPResponse { fn into(self) -> String { // move `self.body` into a new var let b = self.body; let body: String = json::stringify(b); let status_line: String = self.status_line.into(); format!( "{}\r\nContent-Type: application/json\r\nContent-Length: {}\r\n\r\n{}", status_line, body.len(), body ) } }