Update and unify app

This commit is contained in:
2024-06-27 22:52:39 +02:00
parent 3c831d5985
commit 7b8106fd02
16 changed files with 217 additions and 902 deletions

185
backend/Cargo.lock generated
View File

@@ -42,18 +42,20 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.20"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf"
dependencies = [
"async-trait",
"axum-core",
"bitflags",
"axum-macros",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-util",
"itoa",
"matchit",
"memchr",
@@ -65,28 +67,45 @@ dependencies = [
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper",
"sync_wrapper 1.0.1",
"tokio",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-core"
version = "0.3.4"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c"
checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3"
dependencies = [
"async-trait",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"mime",
"pin-project-lite",
"rustversion",
"sync_wrapper 0.1.2",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "axum-macros"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
@@ -277,6 +296,12 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "hermit-abi"
version = "0.3.3"
@@ -285,9 +310,9 @@ checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
name = "http"
version = "0.2.9"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
dependencies = [
"bytes",
"fnv",
@@ -296,12 +321,24 @@ dependencies = [
[[package]]
name = "http-body"
version = "0.4.5"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1"
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
dependencies = [
"bytes",
"http",
]
[[package]]
name = "http-body-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"pin-project-lite",
]
@@ -319,13 +356,12 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hyper"
version = "0.14.27"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468"
checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d"
dependencies = [
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http",
"http-body",
@@ -333,11 +369,23 @@ dependencies = [
"httpdate",
"itoa",
"pin-project-lite",
"socket2 0.4.9",
"smallvec",
"tokio",
]
[[package]]
name = "hyper-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56"
dependencies = [
"bytes",
"futures-util",
"http",
"http-body",
"hyper",
"pin-project-lite",
"tokio",
"tower-service",
"tracing",
"want",
]
[[package]]
@@ -392,6 +440,30 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "maud"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df518b75016b4289cdddffa1b01f2122f4a49802c93191f3133f6dc2472ebcaa"
dependencies = [
"axum-core",
"http",
"itoa",
"maud_macros",
]
[[package]]
name = "maud_macros"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa453238ec218da0af6b11fc5978d3b5c3a45ed97b722391a2a11f3306274e18"
dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "memchr"
version = "2.6.4"
@@ -568,6 +640,29 @@ dependencies = [
"miniz_oxide 0.3.7",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro-error-attr"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
dependencies = [
"proc-macro2",
"quote",
"version_check",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
@@ -583,6 +678,7 @@ version = "0.1.0"
dependencies = [
"axum",
"image",
"maud",
"qrcode",
"tokio",
]
@@ -710,14 +806,10 @@ dependencies = [
]
[[package]]
name = "socket2"
version = "0.4.9"
name = "smallvec"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662"
dependencies = [
"libc",
"winapi",
]
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "socket2"
@@ -746,6 +838,12 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
[[package]]
name = "sync_wrapper"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
[[package]]
name = "tiff"
version = "0.6.1"
@@ -768,7 +866,7 @@ dependencies = [
"mio",
"num_cpus",
"pin-project-lite",
"socket2 0.5.4",
"socket2",
"tokio-macros",
"windows-sys",
]
@@ -833,12 +931,6 @@ dependencies = [
"once_cell",
]
[[package]]
name = "try-lock"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed"
[[package]]
name = "unicode-ident"
version = "1.0.12"
@@ -846,13 +938,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "want"
version = "0.3.1"
name = "version_check"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
[[package]]
name = "wasi"
@@ -866,28 +955,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-sys"
version = "0.48.0"

View File

@@ -5,7 +5,8 @@ edition = "2021"
[dependencies]
axum = "0.6.20"
axum = { version = "0.7.5", features = ["macros"] }
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
qrcode = "0.12.0"
image = "0.23.14"
image = "0.23.14"
maud = { version = "0.26.0", features = ["axum"] }

View File

@@ -1,9 +1,23 @@
FROM rust:1.73 as builder
WORKDIR /usr/src/app
COPY . .
RUN cargo build --release
FROM rust:1 AS chef
# We only pay the installation cost once,
# it will be cached from the second build onwards
RUN cargo install cargo-chef
WORKDIR /app
FROM alpine:latest
RUN apk add --no-cache libgcc libstdc++
COPY --from=builder /usr/src/app/target/release/qr-generator /usr/local/bin/qr-generator
CMD ["qr-generator"]
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS builder
COPY --from=planner /app/recipe.json recipe.json
# Build dependencies - this is the caching Docker layer!
RUN cargo chef cook --release --recipe-path recipe.json
# Build application
COPY . .
RUN cargo build --release --bin qr-generator
# We do not need the Rust toolchain to run the binary!
FROM debian:bookworm-slim AS runtime
WORKDIR /app
COPY --from=builder /app/target/release/qr-generator /usr/local/bin
ENTRYPOINT ["/usr/local/bin/qr-generator"]

View File

@@ -1,32 +1,69 @@
use std::collections::HashMap;
use axum::{Router, routing::get, extract::Query, response::IntoResponse, http::{header::CONTENT_TYPE, StatusCode}};
use image::{Luma, png::PngEncoder, ColorType};
use axum::{
debug_handler,
extract::Query,
http::{header::CONTENT_TYPE, StatusCode},
response::IntoResponse,
routing::get,
Router,
};
use image::{png::PngEncoder, ColorType, Luma};
use maud::{html, Markup};
#[tokio::main]
async fn main() {
let app = Router::new().route("/", get(index)).route("/qr", get(get_qr_code));
axum::Server::bind(&"127.0.0.1:8000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
let app = Router::new()
.route("/", get(index))
.route("/qr", get(get_qr_code));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
async fn index() -> &'static str {
"Hello, world!"
#[debug_handler]
async fn index() -> Markup {
html! {
html {
head {
title { "QR Code Generator" }
}
body {
h1 { "QR Code Generator" }
form action="/qr" method="get" {
label for="link" { "Value: " }
input type="text" name="link" id="link" required;
input type="submit" value="Generate QR Code";
}
}
}
}
}
async fn get_qr_code(Query(params): Query<HashMap<String, String>>) -> impl IntoResponse {
let link = match params.get("link") {
Some(l) => l,
None => {
return (StatusCode::BAD_REQUEST, [(CONTENT_TYPE, "text/plain")], "Missing link").into_response();
return (
StatusCode::BAD_REQUEST,
[(CONTENT_TYPE, "text/plain")],
"Missing link",
)
.into_response();
}
};
let qr_code = match qrcode::QrCode::new(link) {
Ok(qr) => qr,
Err(_) => return (StatusCode::BAD_REQUEST, [(CONTENT_TYPE, "text/plain")], "Invalid link").into_response(),
Err(_) => {
return (
StatusCode::BAD_REQUEST,
[(CONTENT_TYPE, "text/plain")],
"Invalid link",
)
.into_response()
}
};
let qr_image = qr_code.render::<Luma<u8>>().build();
@@ -36,7 +73,14 @@ async fn get_qr_code(Query(params): Query<HashMap<String, String>>) -> impl Into
let encoder = PngEncoder::new(&mut buffer);
match encoder.encode(&qr_image.into_raw(), width, height, ColorType::L8) {
Ok(_) => (),
Err(_) => return (StatusCode::INTERNAL_SERVER_ERROR, [(CONTENT_TYPE, "text/plain")], "Failed to encode QR code").into_response(),
Err(_) => {
return (
StatusCode::INTERNAL_SERVER_ERROR,
[(CONTENT_TYPE, "text/plain")],
"Failed to encode QR code",
)
.into_response()
}
}
(StatusCode::OK, [(CONTENT_TYPE, "image/png")], buffer).into_response()
}
}