feat: #12 add async block in handlers (more readable) + fix tests
This commit is contained in:
parent
53b5c7a65f
commit
71e3db0857
@ -1,6 +1,5 @@
|
|||||||
//! response handles the incoming request parsed `HTTPRequest`
|
//! response handles the incoming request parsed `HTTPRequest`
|
||||||
//! it will check if the `HTTPRequest` is valid and build an HTTPResponse corresponding to the HTTP
|
//! it will build an HTTPResponse corresponding to the HTTP message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
|
||||||
//! message specs. see: https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
|
|
||||||
//! NOTE: only few parts of the specification has been implemented
|
//! NOTE: only few parts of the specification has been implemented
|
||||||
|
|
||||||
use crate::http::request::HTTPVersion;
|
use crate::http::request::HTTPVersion;
|
||||||
|
|||||||
@ -12,10 +12,11 @@ use std::pin::Pin;
|
|||||||
type FuturePinned<HTTPResponse> = Pin<Box<dyn Future<Output = HTTPResponse>>>;
|
type FuturePinned<HTTPResponse> = Pin<Box<dyn Future<Output = HTTPResponse>>>;
|
||||||
type Handler = fn(HTTPRequest) -> FuturePinned<HTTPResponse>;
|
type Handler = fn(HTTPRequest) -> FuturePinned<HTTPResponse>;
|
||||||
|
|
||||||
async fn handle_get(request: HTTPRequest) -> HTTPResponse {
|
fn handle_get(request: HTTPRequest) -> FuturePinned<HTTPResponse> {
|
||||||
|
Box::pin(async move {
|
||||||
// TODO: path to `store.txt` must not be hardcoded, should be in a config file and load at runtime
|
// TODO: path to `store.txt` must not be hardcoded, should be in a config file and load at runtime
|
||||||
let mut store = FileStore::new("tests/data/store.txt".to_string());
|
let mut store = FileStore::new("tests/data/store.txt".to_string());
|
||||||
match request.body {
|
match &request.body {
|
||||||
Some(ref b) => {
|
Some(ref b) => {
|
||||||
let is_auth = store.is_auth(&b.get_data()).await;
|
let is_auth = store.is_auth(&b.get_data()).await;
|
||||||
if !is_auth {
|
if !is_auth {
|
||||||
@ -25,15 +26,34 @@ async fn handle_get(request: HTTPRequest) -> HTTPResponse {
|
|||||||
}
|
}
|
||||||
None => HTTPResponse::as_400(),
|
None => HTTPResponse::as_400(),
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_get_pinned(request: HTTPRequest) -> FuturePinned<HTTPResponse> {
|
/// validates the token by checking:
|
||||||
Box::pin(handle_get(request))
|
/// * expiration time
|
||||||
|
fn handle_validate(request: HTTPRequest) -> FuturePinned<HTTPResponse> {
|
||||||
|
Box::pin(async move {
|
||||||
|
match &request.body {
|
||||||
|
Some(ref _b) => {
|
||||||
|
// TODO: impl the JWT validation
|
||||||
|
HTTPResponse::as_200()
|
||||||
|
}
|
||||||
|
None => HTTPResponse::as_400(),
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
/// defines the map between the URL and its associated callback
|
||||||
|
/// each authorized targets must implement a function returning `FuturePinned<HTTPResponse>`
|
||||||
|
// TODO: a macro should be implemented to mask the implementation details
|
||||||
static ref HTTP_METHODS: HashMap<&'static str, Handler> =
|
static ref HTTP_METHODS: HashMap<&'static str, Handler> =
|
||||||
HashMap::from([("/get/", handle_get_pinned as Handler),]);
|
HashMap::from(
|
||||||
|
[
|
||||||
|
("/get/", handle_get as Handler),
|
||||||
|
("/validate/", handle_validate as Handler)
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Router;
|
pub struct Router;
|
||||||
|
|||||||
@ -28,7 +28,7 @@ done
|
|||||||
for i in {0..10}
|
for i in {0..10}
|
||||||
do
|
do
|
||||||
http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/ge/ -d '{"username":"toto", "password":"tutu"}')
|
http_response=$(curl -s -o response.txt -w "%{http_code}" ${URL}/ge/ -d '{"username":"toto", "password":"tutu"}')
|
||||||
if [ $http_response != "400" ]
|
if [ $http_response != "404" ]
|
||||||
then
|
then
|
||||||
echo "bad http status code : ${http_response}, expect 400"
|
echo "bad http status code : ${http_response}, expect 400"
|
||||||
exit 1
|
exit 1
|
||||||
|
|||||||
@ -26,23 +26,26 @@ class TestResponse(TestCase):
|
|||||||
resp.json()["token"], "header.payload.signature", "bad status returned"
|
resp.json()["token"], "header.payload.signature", "bad status returned"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# TODO: must be updated after implmenting `/refresh/` url handler
|
||||||
def test_refresh_target(self):
|
def test_refresh_target(self):
|
||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
URL + "/refresh/", json={"username": "toto", "password": "tata"}
|
URL + "/refresh/", json={"username": "toto", "password": "tata"}
|
||||||
)
|
)
|
||||||
self.assertEqual(resp.status_code, 200, "bad status code returned")
|
self.assertEqual(resp.status_code, 404, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data can't be empty")
|
self.assertIsNotNone(resp.json(), "response data can't be empty")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resp.json()["token"], "header.payload.signature", "bad status returned"
|
resp.json()["error"],
|
||||||
|
"the url requested does not exist",
|
||||||
|
"bad status returned",
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_no_credentials(self):
|
def test_no_credentials(self):
|
||||||
resp = requests.post(URL + "/get/")
|
resp = requests.post(URL + "/get/")
|
||||||
self.assertEqual(resp.status_code, 403, "bad status code returned")
|
self.assertEqual(resp.status_code, 400, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resp.json()["error"],
|
resp.json()["error"],
|
||||||
"invalid credentials",
|
"the incoming request is not valid",
|
||||||
"invalid error message returned",
|
"invalid error message returned",
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -62,10 +65,10 @@ class TestResponse(TestCase):
|
|||||||
resp = requests.post(
|
resp = requests.post(
|
||||||
URL + "/token/", json={"username": "toto", "password": "tata"}
|
URL + "/token/", json={"username": "toto", "password": "tata"}
|
||||||
)
|
)
|
||||||
self.assertEqual(resp.status_code, 400, "bad status code returned")
|
self.assertEqual(resp.status_code, 404, "bad status code returned")
|
||||||
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
self.assertIsNotNone(resp.json(), "response data must not be empty")
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
resp.json()["error"],
|
resp.json()["error"],
|
||||||
"the incoming request is not valid",
|
"the url requested does not exist",
|
||||||
"invalid error message returned",
|
"invalid error message returned",
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user