👕 refactor: Extract functions for scraper API endpoints

main
_ 2020-12-13 01:12:56 +00:00
parent 622895f77d
commit 1e81421444
1 changed files with 82 additions and 45 deletions

View File

@ -408,22 +408,94 @@ async fn handle_server_list (
Ok (ok_reply (s)?) Ok (ok_reply (s)?)
} }
#[instrument (level = "trace", skip (req, state))]
async fn handle_scraper_api_v1 (
req: Request <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, RequestError>
{
use key_validity::KeyValidity;
let api_key = req.headers ().get ("X-ApiKey");
let api_key = match api_key {
None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run scraper without an API key")?),
Some (x) => x,
};
let bad_key = || error_reply (StatusCode::FORBIDDEN, "403 Forbidden");
{
let config = state.config.read ().await;
let dev_mode = match &config.iso.dev_mode {
None => return Ok (bad_key ()?),
Some (x) => x,
};
let expected_key = match &dev_mode.scraper_key {
None => return Ok (bad_key ()?),
Some (x) => x,
};
let now = chrono::Utc::now ();
match expected_key.is_valid (now, api_key.as_bytes ()) {
KeyValidity::Valid => (),
KeyValidity::WrongKey (bad_hash) => {
error! ("Bad scraper key with hash {:?}", bad_hash);
return Ok (bad_key ()?);
}
err => {
error! ("Bad scraper key {:?}", err);
return Ok (bad_key ()?);
},
}
}
if path_rest == "test" {
Ok (error_reply (StatusCode::OK, "You're valid!")?)
}
else {
Ok (error_reply (StatusCode::NOT_FOUND, "Unknown API endpoint")?)
}
}
#[instrument (level = "trace", skip (req, state))]
async fn handle_scraper_api (
req: Request <Body>,
state: Arc <RelayState>,
path_rest: &str
)
-> Result <Response <Body>, RequestError>
{
if let Some (rest) = prefix_match ("v1/", path_rest) {
handle_scraper_api_v1 (req, state, rest).await
}
else if let Some (rest) = prefix_match ("api/", path_rest) {
handle_scraper_api_v1 (req, state, rest).await
}
else {
Ok (error_reply (StatusCode::NOT_FOUND, "Unknown scraper API version")?)
}
}
#[instrument (level = "trace", skip (req, state))] #[instrument (level = "trace", skip (req, state))]
async fn handle_all (req: Request <Body>, state: Arc <RelayState>) async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
-> Result <Response <Body>, RequestError> -> Result <Response <Body>, RequestError>
{ {
let path = req.uri ().path (); let path = req.uri ().path ().to_string ();
//println! ("{}", path); //println! ("{}", path);
debug! ("Request path: {}", path); debug! ("Request path: {}", path);
let api_key = req.headers ().get ("X-ApiKey");
if req.method () == Method::POST { if req.method () == Method::POST {
// This is stuff the server can use. Clients can't // This is stuff the server can use. Clients can't
// POST right now // POST right now
return if let Some (request_code) = prefix_match ("/7ZSFUKGV/http_response/", path) { return if let Some (request_code) = prefix_match ("/7ZSFUKGV/http_response/", &path) {
let request_code = request_code.into (); let request_code = request_code.into ();
Ok (server_endpoint::handle_response (req, state, request_code).await?) Ok (server_endpoint::handle_response (req, state, request_code).await?)
} }
@ -432,14 +504,16 @@ async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
}; };
} }
if let Some (listen_code) = prefix_match ("/7ZSFUKGV/http_listen/", path) { if let Some (listen_code) = prefix_match ("/7ZSFUKGV/http_listen/", &path) {
let api_key = req.headers ().get ("X-ApiKey");
let api_key = match api_key { let api_key = match api_key {
None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run server without an API key")?), None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run server without an API key")?),
Some (x) => x, Some (x) => x,
}; };
server_endpoint::handle_listen (state, listen_code.into (), api_key.as_bytes ()).await server_endpoint::handle_listen (state, listen_code.into (), api_key.as_bytes ()).await
} }
else if let Some (rest) = prefix_match ("/frontend/servers/", path) { else if let Some (rest) = prefix_match ("/frontend/servers/", &path) {
if rest == "" { if rest == "" {
Ok (handle_server_list (state).await?) Ok (handle_server_list (state).await?)
} }
@ -464,45 +538,8 @@ async fn handle_all (req: Request <Body>, state: Arc <RelayState>)
else if path == "/frontend/test_mysterious_error" { else if path == "/frontend/test_mysterious_error" {
Err (RequestError::Mysterious) Err (RequestError::Mysterious)
} }
else if path == "/scraper/v1/test" || path == "/scraper/api/test" { else if let Some (rest) = prefix_match ("/scraper/", &path) {
use key_validity::KeyValidity; handle_scraper_api (req, state, rest).await
let api_key = match api_key {
None => return Ok (error_reply (StatusCode::FORBIDDEN, "Can't run scraper without an API key")?),
Some (x) => x,
};
let bad_key = || error_reply (StatusCode::FORBIDDEN, "403 Forbidden");
{
let config = state.config.read ().await;
let dev_mode = match &config.iso.dev_mode {
None => return Ok (bad_key ()?),
Some (x) => x,
};
let expected_key = match &dev_mode.scraper_key {
None => return Ok (bad_key ()?),
Some (x) => x,
};
let now = chrono::Utc::now ();
match expected_key.is_valid (now, api_key.as_bytes ()) {
KeyValidity::Valid => (),
KeyValidity::WrongKey (bad_hash) => {
error! ("Bad scraper key with hash {:?}", bad_hash);
return Ok (bad_key ()?);
}
err => {
error! ("Bad scraper key {:?}", err);
return Ok (bad_key ()?);
},
}
}
Ok (error_reply (StatusCode::OK, "You're valid!")?)
} }
else { else {
Ok (error_reply (StatusCode::OK, "Hi")?) Ok (error_reply (StatusCode::OK, "Hi")?)