Redirect to web ui on root

This commit is contained in:
Igor Katson 2025-01-13 22:26:40 +00:00
parent 6cb4289917
commit e79b51ea1f
No known key found for this signature in database
GPG key ID: B4EC22B66D61A3F5

View file

@ -2,13 +2,14 @@ use anyhow::Context;
use axum::body::Bytes; use axum::body::Bytes;
use axum::extract::{ConnectInfo, Path, Query, Request, State}; use axum::extract::{ConnectInfo, Path, Query, Request, State};
use axum::middleware::Next; use axum::middleware::Next;
use axum::response::IntoResponse; use axum::response::{IntoResponse, Redirect};
use axum::routing::{get, post}; use axum::routing::{get, post};
use base64::Engine; use base64::Engine;
use bencode::AsDisplay; use bencode::AsDisplay;
use buffers::ByteBuf; use buffers::ByteBuf;
use futures::future::BoxFuture; use futures::future::BoxFuture;
use futures::{FutureExt, TryStreamExt}; use futures::{FutureExt, TryStreamExt};
use http::request::Parts;
use http::{HeaderMap, HeaderValue, StatusCode}; use http::{HeaderMap, HeaderValue, StatusCode};
use itertools::Itertools; use itertools::Itertools;
@ -161,35 +162,48 @@ impl HttpApi {
) -> BoxFuture<'static, anyhow::Result<()>> { ) -> BoxFuture<'static, anyhow::Result<()>> {
let state = self.inner; let state = self.inner;
async fn api_root() -> impl IntoResponse { let api_root = move |parts: Parts| async move {
axum::Json(serde_json::json!({ // If browser, and webui enabled, redirect to web
"apis": { #[cfg(feature = "webui")]
"GET /": "list all available APIs", {
"GET /dht/stats": "DHT stats", if parts.headers.get("Accept").map_or(false, |h| {
"GET /dht/table": "DHT routing table", std::str::from_utf8(h.as_bytes()).map_or(false, |s| s.contains("text/html"))
"GET /torrents": "List torrents", }) {
"GET /torrents/playlist": "Generate M3U8 playlist for all files in all torrents", return Redirect::temporary("./web/").into_response();
"GET /stats": "Global session stats", }
"POST /torrents/resolve_magnet": "Resolve a magnet to torrent file bytes", }
"GET /torrents/{id_or_infohash}": "Torrent details",
"GET /torrents/{id_or_infohash}/haves": "The bitfield of have pieces", (
"GET /torrents/{id_or_infohash}/playlist": "Generate M3U8 playlist for this torrent", [("Content-Type", "application/json")],
"GET /torrents/{id_or_infohash}/stats/v1": "Torrent stats", axum::Json(serde_json::json!({
"GET /torrents/{id_or_infohash}/peer_stats": "Per peer stats", "apis": {
"GET /torrents/{id_or_infohash}/stream/{file_idx}": "Stream a file. Accepts Range header to seek.", "GET /": "list all available APIs",
"POST /torrents/{id_or_infohash}/pause": "Pause torrent", "GET /dht/stats": "DHT stats",
"POST /torrents/{id_or_infohash}/start": "Resume torrent", "GET /dht/table": "DHT routing table",
"POST /torrents/{id_or_infohash}/forget": "Forget about the torrent, keep the files", "GET /torrents": "List torrents",
"POST /torrents/{id_or_infohash}/delete": "Forget about the torrent, remove the files", "GET /torrents/playlist": "Generate M3U8 playlist for all files in all torrents",
"POST /torrents/{id_or_infohash}/update_only_files": "Change the selection of files to download. You need to POST json of the following form {\"only_files\": [0, 1, 2]}", "GET /stats": "Global session stats",
"POST /torrents": "Add a torrent here. magnet: or http:// or a local file.", "POST /torrents/resolve_magnet": "Resolve a magnet to torrent file bytes",
"POST /rust_log": "Set RUST_LOG to this post launch (for debugging)", "GET /torrents/{id_or_infohash}": "Torrent details",
"GET /web/": "Web UI", "GET /torrents/{id_or_infohash}/haves": "The bitfield of have pieces",
}, "GET /torrents/{id_or_infohash}/playlist": "Generate M3U8 playlist for this torrent",
"server": "rqbit", "GET /torrents/{id_or_infohash}/stats/v1": "Torrent stats",
"version": env!("CARGO_PKG_VERSION"), "GET /torrents/{id_or_infohash}/peer_stats": "Per peer stats",
})) "GET /torrents/{id_or_infohash}/stream/{file_idx}": "Stream a file. Accepts Range header to seek.",
} "POST /torrents/{id_or_infohash}/pause": "Pause torrent",
"POST /torrents/{id_or_infohash}/start": "Resume torrent",
"POST /torrents/{id_or_infohash}/forget": "Forget about the torrent, keep the files",
"POST /torrents/{id_or_infohash}/delete": "Forget about the torrent, remove the files",
"POST /torrents/{id_or_infohash}/update_only_files": "Change the selection of files to download. You need to POST json of the following form {\"only_files\": [0, 1, 2]}",
"POST /torrents": "Add a torrent here. magnet: or http:// or a local file.",
"POST /rust_log": "Set RUST_LOG to this post launch (for debugging)",
"GET /web/": "Web UI",
},
"server": "rqbit",
"version": env!("CARGO_PKG_VERSION"),
})),
).into_response()
};
async fn dht_stats(State(state): State<ApiState>) -> Result<impl IntoResponse> { async fn dht_stats(State(state): State<ApiState>) -> Result<impl IntoResponse> {
state.api_dht_stats().map(axum::Json) state.api_dht_stats().map(axum::Json)