diff --git a/Cargo.lock b/Cargo.lock
index c3f1f28..7df2083 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -298,6 +298,12 @@ dependencies = [
"pin-project-lite",
]
+[[package]]
+name = "http-range-header"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c"
+
[[package]]
name = "httparse"
version = "1.8.0"
@@ -403,6 +409,16 @@ version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
+[[package]]
+name = "mime_guess"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
+dependencies = [
+ "mime",
+ "unicase",
+]
+
[[package]]
name = "miniz_oxide"
version = "0.7.1"
@@ -811,12 +827,21 @@ checksum = "0da193277a4e2c33e59e09b5861580c33dd0a637c3883d0fa74ba40c0374af2e"
dependencies = [
"bitflags 2.4.2",
"bytes",
+ "futures-util",
"http",
"http-body",
"http-body-util",
+ "http-range-header",
+ "httpdate",
+ "mime",
+ "mime_guess",
+ "percent-encoding",
"pin-project-lite",
+ "tokio",
+ "tokio-util",
"tower-layer",
"tower-service",
+ "tracing",
]
[[package]]
@@ -865,6 +890,12 @@ dependencies = [
"tower-http",
]
+[[package]]
+name = "unicase"
+version = "2.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
+
[[package]]
name = "unicode-ident"
version = "1.0.12"
diff --git a/Cargo.toml b/Cargo.toml
index 55e9150..eee1e5e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,7 +7,7 @@ edition = "2021"
[dependencies]
axum = { version = "0.7.4", features = ["macros"] }
-tower-http = { version = "0.5.0", features = ["cors"] }
+tower-http = { version = "0.5.1", features = ["fs", "cors"] }
rand = "0.8.5"
serde = { version = "1.0.173", features = ["derive"] }
serde_json = "1.0.103"
diff --git a/Dockerfile b/Dockerfile
index 4ceb7e3..8e61317 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,5 +1,5 @@
# Build stage
-FROM rust:1.75-alpine3.19 as builder
+FROM rust:1.75-alpine3.19 AS builder
RUN apk add musl-dev
# Copy the source code
@@ -14,6 +14,7 @@ FROM alpine:3.19
ARG REF=""
ARG COMMIT=""
ARG TIME=""
+ARG CT=""
ENV COMMIT=${COMMIT}
ENV REF=${REF}
@@ -24,6 +25,9 @@ ENV TZ="America/New_York"
# Copy the binary from the build stage
COPY --from=builder /target/release/umaring /usr/local/bin/umaring
+# Copy the public directory
+COPY --from=builder /public /usr/local/bin/public
+
# Set the command to run the binary
WORKDIR /usr/local/bin
CMD ["umaring"]
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 0000000..2f88efe
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+ UMass Amherst Web Ring
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/public/styles.css b/public/styles.css
new file mode 100644
index 0000000..2159f1a
--- /dev/null
+++ b/public/styles.css
@@ -0,0 +1,109 @@
+header {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ width: 65%;
+}
+body {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ height: 100vh;
+ flex-direction: column;
+ letter-spacing: 0.1em;
+
+ background-color: #111111;
+
+ font-family: "IBM Plex Mono", monospace;
+ font-weight: 400;
+
+ transition: all 1s ease;
+}
+
+main {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ flex-direction: column;
+
+ width: 65%;
+}
+
+footer {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+
+ flex-direction: column;
+ padding: 20px;
+}
+
+h1,
+h2 {
+ text-align: center;
+ margin-bottom: 50px;
+
+ color: #d9d9d9;
+
+ font-size: 45px;
+ font-weight: 500;
+ letter-spacing: 0.05em;
+}
+
+a {
+ color: #a3a3a3;
+
+ text-decoration: none;
+
+ transition: color 0.3s ease;
+}
+a:hover {
+ color: #d9d9d9;
+}
+
+hr {
+ width: 65%;
+ height: 1px;
+
+ background-color: #d9d9d9;
+ border: none;
+}
+
+#list {
+ margin: 0px;
+ padding: 0px;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ flex-flow: row wrap;
+
+ margin-bottom: 50px;
+
+ list-style: none;
+ gap: 40px;
+ top: 0px;
+ border-collapse: collapse;
+}
+
+#addsite {
+ padding: 10px;
+ border-radius: 10px;
+ margin-bottom: 20px;
+
+ background-color: #222222;
+ color: #d9d9d9;
+
+ text-align: center;
+ text-decoration: none;
+ font-size: 0.9em;
+
+ opacity: 0.8;
+}
+#addsite:hover {
+ background-color: #333333;
+ transition: 1s ease;
+}
diff --git a/src/get.rs b/src/get.rs
index df5bda9..ed09560 100644
--- a/src/get.rs
+++ b/src/get.rs
@@ -1,10 +1,10 @@
use axum::{
extract::{Path, Query, State},
- response::Response,
+ response::Response
};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
-use tokio::sync::RwLock;
+use tokio::{sync::RwLock};
use crate::ring::{Member, Ring};
diff --git a/src/main.rs b/src/main.rs
index 1c61311..2bec818 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,10 +1,12 @@
use axum::{
- response::{Redirect, Response},
+ response::Response,
routing, Router,
};
-use std::sync::Arc;
+use std::{sync::Arc};
use tokio::sync::RwLock;
use tower_http::cors::CorsLayer;
+use tower_http::services::ServeDir;
+
mod get;
mod ring;
@@ -25,18 +27,19 @@ async fn main() {
ring.shuffle();
}
});
+
+ // serve static files from /public
+ let landing_page = ServeDir::new("public")
+ .append_index_html_on_directories(true);
let app = Router::new()
- .route(
- "/",
- routing::get(|| async { Redirect::temporary("https://github.com/umacabal/umaring") }),
- )
.route("/health", routing::get(health))
.route("/all", routing::get(get::all))
.route("/:id", routing::get(get::one))
.route("/:id/prev", routing::get(get::prev))
.route("/:id/next", routing::get(get::next))
.route("/ring.js", routing::get(get::ring_js))
+ .fallback_service(landing_page)
.layer(CorsLayer::permissive())
.with_state(ring);