request_handler.rs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. use crate::{negative_report::EncryptedNegativeReport, positive_report::PositiveReport, *};
  2. use hyper::{body, header::HeaderValue, Body, Method, Request, Response, StatusCode};
  3. use serde_json::json;
  4. use sled::Db;
  5. use std::convert::Infallible;
  6. // Handle submitted reports
  7. pub async fn handle(db: &Db, req: Request<Body>) -> Result<Response<Body>, Infallible> {
  8. match req.method() {
  9. &Method::OPTIONS => Ok(Response::builder()
  10. .header("Access-Control-Allow-Origin", HeaderValue::from_static("*"))
  11. .header("Access-Control-Allow-Headers", "accept, content-type")
  12. .header("Access-Control-Allow-Methods", "POST")
  13. .status(200)
  14. .body(Body::from("Allow POST"))
  15. .unwrap()),
  16. _ => match (req.method(), req.uri().path()) {
  17. (&Method::POST, "/negativereport") => Ok::<_, Infallible>({
  18. let bytes = body::to_bytes(req.into_body()).await.unwrap();
  19. // We cannot depend on the transport layer providing E2EE, so
  20. // positive reports should be separately encrypted.
  21. let enr: EncryptedNegativeReport = match bincode::deserialize(&bytes) {
  22. Ok(enr) => enr,
  23. Err(e) => {
  24. let response = json!({"error": e.to_string()});
  25. let val = serde_json::to_string(&response).unwrap();
  26. return Ok(prepare_header(val));
  27. }
  28. };
  29. handle_encrypted_negative_report(&db, enr);
  30. prepare_header("OK".to_string())
  31. }),
  32. (&Method::POST, "/positivereport") => Ok::<_, Infallible>({
  33. let bytes = body::to_bytes(req.into_body()).await.unwrap();
  34. let pr = match PositiveReport::from_slice(&bytes) {
  35. Ok(pr) => pr,
  36. Err(e) => {
  37. let response = json!({"error": e});
  38. let val = serde_json::to_string(&response).unwrap();
  39. return Ok(prepare_header(val));
  40. }
  41. };
  42. save_positive_report_to_process(&db, pr);
  43. prepare_header("OK".to_string())
  44. }),
  45. _ => {
  46. // Return 404 not found response.
  47. Ok(Response::builder()
  48. .status(StatusCode::NOT_FOUND)
  49. .body(Body::from("Not found"))
  50. .unwrap())
  51. }
  52. },
  53. }
  54. }
  55. // Prepare HTTP Response for successful Server Request
  56. fn prepare_header(response: String) -> Response<Body> {
  57. let mut resp = Response::new(Body::from(response));
  58. resp.headers_mut()
  59. .insert("Access-Control-Allow-Origin", HeaderValue::from_static("*"));
  60. resp
  61. }