From 4ce6d64648634bd8d22e8ed0676e0e5b22947dc3 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Sat, 7 Mar 2026 04:02:48 +0100 Subject: new media path format --- server/src/main.rs | 2 +- server/src/routes/stream.rs | 32 +++++++++++++++++++------------- 2 files changed, 20 insertions(+), 14 deletions(-) (limited to 'server/src') diff --git a/server/src/main.rs b/server/src/main.rs index 0c42bb6..2837940 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -3,7 +3,7 @@ which is licensed under the GNU Affero General Public License (version 3); see /COPYING. Copyright (C) 2026 metamuffin */ -#![feature(int_roundings, str_as_str, duration_constructors)] +#![feature(int_roundings, str_as_str, duration_constructors, never_type)] #![allow(clippy::needless_borrows_for_generic_args)] #![recursion_limit = "4096"] diff --git a/server/src/routes/stream.rs b/server/src/routes/stream.rs index a72e0d9..f117070 100644 --- a/server/src/routes/stream.rs +++ b/server/src/routes/stream.rs @@ -14,28 +14,34 @@ use jellystream::SMediaInfo; use log::{info, warn}; use rocket::{ Either, Request, Response, get, head, - http::{Header, Status}, - request::{self, FromRequest}, + http::{Header, Status, uri::Segments}, + request::{self, FromRequest, FromSegments}, response::{self, Redirect, Responder}, }; -use std::{ - collections::{BTreeMap, BTreeSet}, - ops::Range, - sync::Arc, -}; +use std::{collections::BTreeSet, ops::Range, sync::Arc}; use tokio::{ io::{DuplexStream, duplex}, task::spawn_blocking, }; use tokio_util::io::SyncIoBridge; -#[head("/n/<_id>/stream?")] +pub struct StringPath<'a>(Vec<&'a str>); +impl<'r> FromSegments<'r> for StringPath<'r> { + type Error = !; + fn from_segments( + segments: Segments<'r, rocket::http::uri::fmt::Path>, + ) -> Result { + Ok(Self(segments.collect())) + } +} + +#[head("/n/<_id>/media/")] pub async fn r_stream_head( _sess: RequestInfo<'_>, _id: &str, - spec: BTreeMap, + path: StringPath<'_>, ) -> Result, MyError> { - let spec = StreamSpec::from_query_kv(&spec).map_err(|x| anyhow!("spec invalid: {x}"))?; + let spec = StreamSpec::from_path(&path.0).map_err(|x| anyhow!("media path invalid: {x}"))?; let head = jellystream::stream_head(&spec); Ok(Either::Left(StreamResponse { stream: duplex(0).0, @@ -45,14 +51,14 @@ pub async fn r_stream_head( })) } -#[get("/n//stream?")] +#[get("/n//media/")] pub async fn r_stream( ri: RequestInfo<'_>, slug: &str, range: Option, - spec: BTreeMap, + path: StringPath<'_>, ) -> Result { - let spec = StreamSpec::from_query_kv(&spec).map_err(|x| anyhow!("spec invalid: {x}"))?; + let spec = StreamSpec::from_path(&path.0).map_err(|x| anyhow!("media path invalid: {x}"))?; let mut node = None; ri.state.database.transaction(&mut |txn| { -- cgit v1.3