diff --git a/.new b/.new new file mode 100644 index 0000000..169dcfb --- /dev/null +++ b/.new @@ -0,0 +1,3 @@ + +[Default Applications] +x-scheme-handler/claude-cli=claude-code-url-handler.desktop diff --git a/Cargo.lock b/Cargo.lock index a501cea..ea1c361 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,12 +35,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "ascii" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" - [[package]] name = "asn1-rs" version = "0.7.2" @@ -92,6 +86,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" version = "1.5.1" @@ -127,6 +127,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.8.3" @@ -210,12 +216,6 @@ dependencies = [ "rand_core 0.10.1", ] -[[package]] -name = "chunked_transfer" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4de3bc4ea267985becf712dc6d9eed8b04c953b3fcfb339ebc87acd9804901" - [[package]] name = "cipher" version = "0.4.4" @@ -260,6 +260,22 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -501,6 +517,12 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foldhash" version = "0.1.5" @@ -513,12 +535,44 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + [[package]] name = "futures-core" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -566,6 +620,25 @@ dependencies = [ "wasip3", ] +[[package]] +name = "h2" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.14.5" @@ -603,12 +676,99 @@ dependencies = [ "digest", ] +[[package]] +name = "http" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6970f50e31d6fc17d3fa27329444bfa74e196cf62e95052a3f6fee181dba6425" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + [[package]] name = "httpdate" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-layer", + "tower-service", + "tracing", + "windows-registry", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -636,6 +796,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + [[package]] name = "is" version = "0.9.1" @@ -833,6 +999,12 @@ dependencies = [ "base64ct", ] +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -1034,10 +1206,14 @@ dependencies = [ "async-broadcast", "bytes", "dashmap", + "http-body-util", + "hyper", + "hyper-util", "rand 0.10.1", "rml_rtmp", + "serde", + "serde_json", "str0m", - "tiny_http", "tokio", ] @@ -1289,6 +1465,27 @@ dependencies = [ "syn", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -1360,18 +1557,6 @@ dependencies = [ "time-core", ] -[[package]] -name = "tiny_http" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389915df6413a2e74fb181895f933386023c71110878cd0825588928e64cdc82" -dependencies = [ - "ascii", - "chunked_transfer", - "httpdate", - "log", -] - [[package]] name = "tokio" version = "1.52.3" @@ -1400,6 +1585,31 @@ dependencies = [ "syn", ] +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + [[package]] name = "tracing" version = "0.1.44" @@ -1431,6 +1641,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "typenum" version = "1.20.1" @@ -1461,6 +1677,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.1+wasi-snapshot-preview1" @@ -1525,6 +1750,35 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-registry" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.61.2" diff --git a/Cargo.toml b/Cargo.toml index b7e8940..6c19197 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,5 +10,9 @@ dashmap = "6.2.1" rand = "0.10.1" rml_rtmp = "0.8.0" str0m = "0.20.0" -tiny_http = "0.12.0" tokio = { version = "1", features = ["full"] } +hyper = { version = "1", features = ["full"] } +http-body-util = "0.1" +hyper-util = { version = "0.1", features = ["full"] } +serde = { version = "1.0.228", features = ["serde_derive"] } +serde_json = "1.0.150" diff --git a/flake.lock b/flake.lock index ea872df..162bb82 100644 --- a/flake.lock +++ b/flake.lock @@ -35,11 +35,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1780747962, - "narHash": "sha256-IX7G1dlKrOqPOImfbo7ADDfV5yU1+j+MRChI3TL4tAA=", + "lastModified": 1781454065, + "narHash": "sha256-d2xfDjnfRuf/xYGdu9VVRHiav/2w5hDL/5cw2TuVAXw=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "cbb5cf358f50aa6acc9efd6113b7bcfbc352cd73", + "rev": "9eac87a12312b8f60dd52e1c6e1a265f6fc7f5fc", "type": "github" }, "original": { diff --git a/src/http.rs b/src/http.rs index 8989deb..59f7f1c 100644 --- a/src/http.rs +++ b/src/http.rs @@ -1,61 +1,69 @@ -use std::error::Error; +use std::{convert::Infallible, error::Error, net::SocketAddr}; -use tokio::sync::mpsc::{Receiver, Sender}; -use tiny_http::{Header, Response, Server, StatusCode}; +use bytes::Bytes; +use http_body_util::Full; +use hyper::{Request, Response, server::conn::http2, service::service_fn}; +use hyper_util::rt::{TokioExecutor, TokioIo}; +use serde::Serialize; +use std::sync::Arc; +use tokio::{ + net::TcpListener, + sync::{ + Mutex, + mpsc::{Receiver, Sender}, + }, +}; + +use crate::AppState; pub struct HttpServer { pub offer_tx: Sender<(String, String)>, pub accept_rx: Receiver<(String, String)>, + pub appstate: Arc>, } impl HttpServer { - pub fn start(mut self) -> Result<(), Box> { - let handle = tokio::runtime::Handle::current(); - std::thread::spawn(move || { - let server = Server::http("0.0.0.0:5000").unwrap(); - for mut request in server.incoming_requests() { - let cors = - Header::from_bytes(&b"Access-Control-Allow-Origin"[..], &b"*"[..]).unwrap(); - let cors_methods = - Header::from_bytes(&b"Access-Control-Allow-Methods"[..], &b"POST, OPTIONS"[..]) - .unwrap(); - let cors_headers = - Header::from_bytes(&b"Access-Control-Allow-Headers"[..], &b"Content-Type"[..]) - .unwrap(); - - if *request.method() == tiny_http::Method::Options { - let reply = Response::from_data("") - .with_status_code(StatusCode(204)) - .with_header(cors) - .with_header(cors_methods) - .with_header(cors_headers); - request.respond(reply).unwrap(); - continue; - } - - if request.url().contains("whep") && *request.method() == tiny_http::Method::Post { - let mut body = String::new(); - request.as_reader().read_to_string(&mut body).unwrap(); - println!("HTTP: received offer, body length={}", body.len()); - handle.block_on(self.offer_tx.send(("".to_string(), body))).unwrap(); - let content_type = - Header::from_bytes(&b"Content-Type"[..], &b"application/sdp"[..]).unwrap(); - - let reply = match handle.block_on(self.accept_rx.recv()) { - Some(accept) => Response::from_data(accept.1) - .with_status_code(StatusCode(201)) - .with_header(content_type) - .with_header(cors) - .with_header(cors_methods) - .with_header(cors_headers), - None => Response::from_data("") - .with_status_code(StatusCode(500)) - .with_header(content_type), - }; - request.respond(reply).unwrap(); - } + pub fn start(&mut self) -> Result<(), Box> { + let state = self.appstate.clone(); + tokio::spawn(async move { + let socket = SocketAddr::from(([127, 0, 0, 1], 3000)); + let listener = TcpListener::bind(socket).await.unwrap(); + loop { + let (stream, _) = listener.accept().await.unwrap(); + let tokio_io = TokioIo::new(stream); + let state = state.clone(); + tokio::spawn(async move { + let service = service_fn(move |req| { + let state = state.clone(); + async move { handle_request(req, &state).await } + }); + let hyper = http2::Builder::new(TokioExecutor::new()); + hyper.serve_connection(tokio_io, service).await.unwrap(); + }); } }); Ok(()) } } + +async fn handle_request( + request: Request, + appstate: &Arc>, +) -> Result>, Infallible> { + return match request.uri().path() { + "/api/catalog" => {} + "/api/meow" => Ok(Response::builder() + .status(200) + .body(Full::new(Bytes::from("meow"))) + .unwrap()), + _ => Ok(Response::builder() + .status(404) + .body(Full::new(Bytes::from(""))) + .unwrap()), + }; +} + +#[derive(Serialize)] +struct StreamCatalog {} + +fn catalog_from_state(state: &Arc>) -> StreamCatalog {} diff --git a/src/main.rs b/src/main.rs index fac1bce..b606016 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,9 +40,10 @@ async fn main() -> Result<(), Box> { let (offer_tx, offer_rx) = tokio::sync::mpsc::channel::<(String, String)>(4); let (answer_tx, answer_rx) = tokio::sync::mpsc::channel::<(String, String)>(4); - let http = HttpServer { + let mut http = HttpServer { offer_tx, accept_rx: answer_rx, + appstate: appstate.clone(), }; http.start()?;