v0.5 Upgrade - Upgraded and modified project to support rocket.rs v0.5.1
This commit is contained in:
parent
00a6d33f4a
commit
29b509b3b4
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "request-mirror"
|
name = "request-mirror"
|
||||||
version = "0.1.0"
|
version = "0.1.1"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
@ -9,14 +9,14 @@ edition = "2021"
|
||||||
chrono = "0.4.34"
|
chrono = "0.4.34"
|
||||||
diesel = { version = "2.1.4", features = ["postgres", "chrono"] }
|
diesel = { version = "2.1.4", features = ["postgres", "chrono"] }
|
||||||
dotenvy = "0.15.7"
|
dotenvy = "0.15.7"
|
||||||
rocket = { version = "0.4.11", features = ["tls"] }
|
rocket = { version = "0.5.1", features = ["tls"] }
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0.197", features = ["derive"] }
|
||||||
serde_json = "1.0.114"
|
serde_json = "1.0.114"
|
||||||
tokio = { version = "1.36.0", features = ["full"] }
|
tokio = { version = "1.36.0", features = ["full"] }
|
||||||
|
|
||||||
[dependencies.rocket_contrib]
|
[dependencies.rocket_dyn_templates]
|
||||||
version = "0.4.11"
|
version = "0.2.0"
|
||||||
features = ["handlebars_templates", "tera_templates"]
|
features = ["handlebars"]
|
||||||
|
|
||||||
[dependencies.uuid]
|
[dependencies.uuid]
|
||||||
version = "1.7.0"
|
version = "1.7.0"
|
||||||
|
|
|
||||||
11
Dockerfile
11
Dockerfile
|
|
@ -1,6 +1,8 @@
|
||||||
FROM rustlang/rust:nightly as builder
|
FROM rustlang/rust:nightly as builder
|
||||||
WORKDIR ./app
|
WORKDIR /app
|
||||||
COPY . .
|
COPY src ./src
|
||||||
|
COPY Cargo.toml .
|
||||||
|
COPY Cargo.lock .
|
||||||
RUN cargo install --path .
|
RUN cargo install --path .
|
||||||
|
|
||||||
FROM rustlang/rust:nightly as runner
|
FROM rustlang/rust:nightly as runner
|
||||||
|
|
@ -10,8 +12,7 @@ RUN apt update && apt install -y libpq-dev libc6
|
||||||
COPY --from=builder /usr/local/cargo/bin/request-mirror /usr/local/bin/request-mirror
|
COPY --from=builder /usr/local/cargo/bin/request-mirror /usr/local/bin/request-mirror
|
||||||
COPY ./templates /templates
|
COPY ./templates /templates
|
||||||
COPY .env.docker /.env
|
COPY .env.docker /.env
|
||||||
ENV ROCKET_ADDRESS=0.0.0.0
|
COPY Rocket.toml /
|
||||||
ENV ROCKET_PORT=80
|
ENV ROCKET_PROFILE=docker
|
||||||
ENV ROCKET_ENV=production
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
ENTRYPOINT diesel migration run --database-url $DATABASE_URL --migration-dir /migrations && request-mirror
|
ENTRYPOINT diesel migration run --database-url $DATABASE_URL --migration-dir /migrations && request-mirror
|
||||||
28
Rocket.toml
28
Rocket.toml
|
|
@ -1,27 +1,21 @@
|
||||||
[development]
|
[default]
|
||||||
address = "0.0.0.0"
|
address = "0.0.0.0"
|
||||||
port = 8000
|
port = 8000
|
||||||
keep_alive = 5
|
keep_alive = 5
|
||||||
read_timeout = 5
|
log_level = "normal"
|
||||||
write_timeout = 5
|
|
||||||
log = "normal"
|
|
||||||
limits = { forms = 32768 }
|
limits = { forms = 32768 }
|
||||||
|
|
||||||
[staging]
|
[release]
|
||||||
address = "0.0.0.0"
|
|
||||||
port = 8000
|
|
||||||
keep_alive = 5
|
|
||||||
read_timeout = 5
|
|
||||||
write_timeout = 5
|
|
||||||
log = "normal"
|
|
||||||
limits = { forms = 32768 }
|
|
||||||
|
|
||||||
[production]
|
|
||||||
address = "0.0.0.0"
|
address = "0.0.0.0"
|
||||||
port = 80
|
port = 80
|
||||||
keep_alive = 5
|
keep_alive = 5
|
||||||
read_timeout = 5
|
log_level = "critical"
|
||||||
write_timeout = 5
|
limits = { forms = 32768 }
|
||||||
log = "critical"
|
|
||||||
|
[docker]
|
||||||
|
address = "0.0.0.0"
|
||||||
|
port = 80
|
||||||
|
keep_alive = 5
|
||||||
|
log_level = "critical"
|
||||||
limits = { forms = 32768 }
|
limits = { forms = 32768 }
|
||||||
template_dir = "/templates/"
|
template_dir = "/templates/"
|
||||||
|
|
@ -27,7 +27,7 @@ pub fn establish_connection() -> PgConnection {
|
||||||
let database_url: String;
|
let database_url: String;
|
||||||
match env::var(key) {
|
match env::var(key) {
|
||||||
Ok(val) => database_url = val,
|
Ok(val) => database_url = val,
|
||||||
Err(e) => {
|
Err(_e) => {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
database_url = env::var(key).expect("DATABASE_URL must be set");
|
database_url = env::var(key).expect("DATABASE_URL must be set");
|
||||||
|
|
|
||||||
82
src/main.rs
82
src/main.rs
|
|
@ -1,17 +1,15 @@
|
||||||
#![feature(proc_macro_hygiene, decl_macro)]
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
|
|
||||||
use request_mirror::schema::{history, pair_records};
|
use request_mirror::schema::{history, pair_records};
|
||||||
use rocket::{data, request, Outcome, Request, Data};
|
use rocket::data::{FromData, ToByteUnit};
|
||||||
use rocket::data::FromDataSimple;
|
use rocket::{data, Data};
|
||||||
use rocket::request::FromRequest;
|
use rocket::request::{self, Request, FromRequest};
|
||||||
use rocket_contrib::templates::Template;
|
use rocket::outcome::Outcome;
|
||||||
|
use rocket_dyn_templates::Template;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use rocket::http::{Cookie, Cookies, Status};
|
use rocket::http::{Cookie, CookieJar, Status};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use std::io::Read;
|
|
||||||
use request_mirror::models::*;
|
use request_mirror::models::*;
|
||||||
use diesel::prelude::*;
|
use diesel::prelude::*;
|
||||||
use request_mirror::*;
|
use request_mirror::*;
|
||||||
|
|
@ -24,7 +22,9 @@ struct RequestInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum ApiError {
|
enum Error {
|
||||||
|
TooLarge,
|
||||||
|
Io(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Debug, Clone)]
|
#[derive(Serialize, Debug, Clone)]
|
||||||
|
|
@ -33,13 +33,14 @@ struct RequestBody(String);
|
||||||
// Always use a limit to prevent DoS attacks.
|
// Always use a limit to prevent DoS attacks.
|
||||||
const LIMIT: u64 = 256;
|
const LIMIT: u64 = 256;
|
||||||
|
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for RequestInfo {
|
#[rocket::async_trait]
|
||||||
type Error = ApiError;
|
impl<'r> FromRequest<'r> for RequestInfo {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
/// Used for parsing request information and making it available for request functions to access
|
/// Used for parsing request information and making it available for request functions to access
|
||||||
/// Also handles creating cookies when the client doesn't send one in the request
|
/// Also handles creating cookies when the client doesn't send one in the request
|
||||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
let mut req_cookies = request.cookies();
|
let req_cookies: &CookieJar = req.cookies();
|
||||||
|
|
||||||
// Initially set cookie
|
// Initially set cookie
|
||||||
if req_cookies.get(&"mirror-id").is_none() {
|
if req_cookies.get(&"mirror-id").is_none() {
|
||||||
|
|
@ -47,13 +48,12 @@ impl<'a, 'r> FromRequest<'a, 'r> for RequestInfo {
|
||||||
// When the client doesn't send the mirror-id cookie, from_request will create
|
// When the client doesn't send the mirror-id cookie, from_request will create
|
||||||
// one in the database and send it back to the client.
|
// one in the database and send it back to the client.
|
||||||
let new_uuid = Uuid::new_v4().to_string();
|
let new_uuid = Uuid::new_v4().to_string();
|
||||||
|
|
||||||
println!("Creating new cookie");
|
println!("Creating new cookie");
|
||||||
|
|
||||||
req_cookies.add(Cookie::new("mirror-id", new_uuid.clone()));
|
req_cookies.add(Cookie::new("mirror-id", new_uuid.clone()));
|
||||||
|
|
||||||
let address = if request.client_ip().is_some() {
|
let address = if req.client_ip().is_some() {
|
||||||
request.client_ip().unwrap().to_string()
|
req.client_ip().unwrap().to_string()
|
||||||
} else {
|
} else {
|
||||||
"Unknown".to_string()
|
"Unknown".to_string()
|
||||||
};
|
};
|
||||||
|
|
@ -71,7 +71,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for RequestInfo {
|
||||||
let mut query: Vec<Pair> = vec![];
|
let mut query: Vec<Pair> = vec![];
|
||||||
|
|
||||||
// Compile header
|
// Compile header
|
||||||
for row in request.headers().clone().into_iter() {
|
for row in req.headers().clone().into_iter() {
|
||||||
let key: String = row.name().to_string();
|
let key: String = row.name().to_string();
|
||||||
let value: String = row.value().to_string();
|
let value: String = row.value().to_string();
|
||||||
|
|
||||||
|
|
@ -87,14 +87,13 @@ impl<'a, 'r> FromRequest<'a, 'r> for RequestInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compile query
|
// Compile query
|
||||||
let request_query = request.raw_query_items();
|
let request_query = req.query_fields();
|
||||||
if request_query.is_some() {
|
for field in request_query {
|
||||||
for row in request_query.unwrap() {
|
|
||||||
let (key, value) = row.key_value_decoded();
|
|
||||||
|
|
||||||
query.push(Pair{key:key, value:value});
|
query.push(Pair{key:field.name.to_string(), value:field.value.to_string()});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Send the Request Info as successful outcome
|
// Send the Request Info as successful outcome
|
||||||
Outcome::Success(RequestInfo {
|
Outcome::Success(RequestInfo {
|
||||||
|
|
@ -105,19 +104,24 @@ impl<'a, 'r> FromRequest<'a, 'r> for RequestInfo {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromDataSimple for RequestBody {
|
#[rocket::async_trait]
|
||||||
type Error = String;
|
impl<'r> FromData<'r> for RequestBody {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
/// Used to extract the body of a request and make it available to request functions
|
/// Used to extract the body of a request and make it available to request functions
|
||||||
fn from_data(_req: &Request, data: Data) -> data::Outcome<Self, String> {
|
async fn from_data(_req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> {
|
||||||
|
|
||||||
// Read the data into a String.
|
// Read the data into a String.
|
||||||
let mut string = String::new();
|
let string = match data.open(LIMIT.mebibytes()).into_string().await {
|
||||||
if let Err(e) = data.open().take(LIMIT).read_to_string(&mut string) {
|
Ok(string) if string.is_complete() => string.into_inner(),
|
||||||
return Outcome::Failure((Status::InternalServerError, format!("{:?}", e)));
|
Ok(_) => return Outcome::Error((Status::PayloadTooLarge, crate::Error::TooLarge)),
|
||||||
}
|
Err(e) => return Outcome::Error((Status::InternalServerError, crate::Error::Io(e))),
|
||||||
|
};
|
||||||
|
|
||||||
// Return successfully.
|
// Return successfully.
|
||||||
Outcome::Success(RequestBody(string))
|
Outcome::Success(
|
||||||
|
RequestBody(string)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,7 +139,7 @@ fn index(_info: RequestInfo) -> Template {
|
||||||
/// Processes /test get request and responds with some of the contents of the request
|
/// Processes /test get request and responds with some of the contents of the request
|
||||||
/// This function also stores information from the request in the database
|
/// This function also stores information from the request in the database
|
||||||
#[get("/test")]
|
#[get("/test")]
|
||||||
fn test_get(request: RequestInfo, cookies: Cookies) -> Template {
|
fn test_get(request: RequestInfo, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
let client_id = cookies.get("mirror-id");
|
let client_id = cookies.get("mirror-id");
|
||||||
|
|
||||||
|
|
@ -187,7 +191,7 @@ fn test_get(request: RequestInfo, cookies: Cookies) -> Template {
|
||||||
/// Processes /test post request and responds with some of the contents of the request
|
/// Processes /test post request and responds with some of the contents of the request
|
||||||
/// This function also stores information from the request in the database
|
/// This function also stores information from the request in the database
|
||||||
#[post("/test", data = "<body>")]
|
#[post("/test", data = "<body>")]
|
||||||
fn test_post(body: RequestBody, request: RequestInfo, cookies: Cookies) -> Template {
|
fn test_post(body: RequestBody, request: RequestInfo, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
let client_id = cookies.get("mirror-id");
|
let client_id = cookies.get("mirror-id");
|
||||||
|
|
||||||
|
|
@ -245,7 +249,7 @@ fn test_post(body: RequestBody, request: RequestInfo, cookies: Cookies) -> Templ
|
||||||
/// Request function that returns a history of requests that the current client has made
|
/// Request function that returns a history of requests that the current client has made
|
||||||
/// The user can click a history_id and view the request itself
|
/// The user can click a history_id and view the request itself
|
||||||
#[get("/history")]
|
#[get("/history")]
|
||||||
fn history_req(cookies: Cookies) -> Template {
|
fn history_req(cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
// Get the client_id from the cookies
|
// Get the client_id from the cookies
|
||||||
let client_id = cookies.get("mirror-id").unwrap().value();
|
let client_id = cookies.get("mirror-id").unwrap().value();
|
||||||
|
|
@ -294,7 +298,7 @@ fn history_req(cookies: Cookies) -> Template {
|
||||||
/// request that was recorded to the database.
|
/// request that was recorded to the database.
|
||||||
/// This includes the body of a post request, headers, cookies and query parameters.
|
/// This includes the body of a post request, headers, cookies and query parameters.
|
||||||
#[get("/history/<history_id>")]
|
#[get("/history/<history_id>")]
|
||||||
fn history_details(history_id: i64, cookies: Cookies) -> Template {
|
fn history_details(history_id: i64, cookies: &CookieJar<'_>) -> Template {
|
||||||
|
|
||||||
let client_id = cookies.get("mirror-id").unwrap().value();
|
let client_id = cookies.get("mirror-id").unwrap().value();
|
||||||
|
|
||||||
|
|
@ -388,9 +392,9 @@ fn not_found(req: &Request) -> Template {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[launch]
|
||||||
rocket::ignite()
|
fn rocket() -> _ {
|
||||||
.register(catchers![not_found])
|
rocket::build()
|
||||||
.mount(
|
.mount(
|
||||||
"/",
|
"/",
|
||||||
routes![
|
routes![
|
||||||
|
|
@ -401,6 +405,6 @@ fn main() {
|
||||||
history_details
|
history_details
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
.register("/", catchers![not_found])
|
||||||
.attach(Template::fairing())
|
.attach(Template::fairing())
|
||||||
.launch();
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue