From d2ac69816567f092fe0d4661723bc43778cb481b Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Mon, 1 Dec 2025 14:31:32 +0000 Subject: fix cargo clippy and fmt warnings --- src/http/mod.rs | 125 +++++++++++++++++++++++++++++++++--------------------- src/http/nip11.rs | 34 +++++++-------- 2 files changed, 92 insertions(+), 67 deletions(-) (limited to 'src/http') diff --git a/src/http/mod.rs b/src/http/mod.rs index 07b47ee..f43cf86 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -9,20 +9,20 @@ use std::net::SocketAddr; use std::pin::Pin; use std::sync::Arc; +use base64::Engine; +use http_body_util::{BodyExt, Full}; use hyper::body::{Bytes, Incoming}; use hyper::header::{CONNECTION, SEC_WEBSOCKET_ACCEPT, UPGRADE}; use hyper::server::conn::http1; use hyper::service::Service; use hyper::{Method, Request, Response}; use hyper_util::rt::TokioIo; -use http_body_util::{BodyExt, Full}; +use nostr_relay_builder::prelude::MemoryDatabase; +use nostr_relay_builder::LocalRelay; use nostr_sdk::hashes::sha1::Hash as Sha1Hash; use nostr_sdk::hashes::{Hash, HashEngine}; use nostr_sdk::PublicKey; -use nostr_relay_builder::prelude::MemoryDatabase; -use nostr_relay_builder::LocalRelay; use tokio::net::TcpListener; -use base64::Engine; use crate::config::Config; use crate::git; @@ -50,7 +50,12 @@ struct HttpService { } impl HttpService { - fn new(relay: LocalRelay, config: Config, remote: SocketAddr, database: Arc) -> Self { + fn new( + relay: LocalRelay, + config: Config, + remote: SocketAddr, + database: Arc, + ) -> Self { Self { relay, config, @@ -77,10 +82,12 @@ impl Service> for HttpService { // GRASP-01 spec line 47: Respond to OPTIONS with 204 No Content if method == Method::OPTIONS { return Box::pin(async move { - Ok(add_cors_headers(Response::builder().header("server", "ngit-grasp")) - .status(204) - .body(Full::new(Bytes::new())) - .unwrap()) + Ok( + add_cors_headers(Response::builder().header("server", "ngit-grasp")) + .status(204) + .body(Full::new(Bytes::new())) + .unwrap(), + ) }); } @@ -89,41 +96,47 @@ impl Service> for HttpService { let npub = npub.to_string(); let identifier = identifier.to_string(); let subpath = subpath.to_string(); - - tracing::debug!("Git request: {} {} (npub={}, id={}, subpath={})", - method, path, npub, identifier, subpath); + + tracing::debug!( + "Git request: {} {} (npub={}, id={}, subpath={})", + method, + path, + npub, + identifier, + subpath + ); let repo_path = git::resolve_repo_path(&git_data_path, &npub, &identifier); return Box::pin(async move { // Collect request body once before the match statement - let body_bytes = req.collect().await + let body_bytes = req + .collect() + .await .map(|collected| collected.to_bytes()) .unwrap_or_else(|_| Bytes::new()); - + let result = match (method.as_ref(), subpath.as_str()) { // GET /info/refs?service=git-upload-pack or git-receive-pack (m, sp) if m == Method::GET && sp.starts_with("info/refs") => { // Parse query string for service parameter - let service = query.as_deref().unwrap_or("") + let service = query + .as_deref() + .unwrap_or("") .strip_prefix("service=") .and_then(git::protocol::GitService::from_query_param); match service { - Some(svc) => { - git::handlers::handle_info_refs(repo_path, svc).await - } - None => { - Err(git::handlers::GitError::RepositoryNotFound) - } + Some(svc) => git::handlers::handle_info_refs(repo_path, svc).await, + None => Err(git::handlers::GitError::RepositoryNotFound), } } - + // POST /git-upload-pack (clone/fetch) (m, "git-upload-pack") if m == Method::POST => { git::handlers::handle_upload_pack(repo_path, body_bytes).await } - + // POST /git-receive-pack (push) - with GRASP authorization via database (m, "git-receive-pack") if m == Method::POST => { // Convert npub (bech32) to hex pubkey for authorization @@ -137,33 +150,41 @@ impl Service> for HttpService { .unwrap()); } }; - + git::handlers::handle_receive_pack( repo_path, body_bytes.clone(), Some(database.clone()), &identifier, &owner_pubkey_hex, - ).await - } - - _ => { - Err(git::handlers::GitError::RepositoryNotFound) + ) + .await } + + _ => Err(git::handlers::GitError::RepositoryNotFound), }; match result { Ok(response) => { // Add CORS headers to successful Git responses let (parts, body) = response.into_parts(); - Ok(add_cors_headers(Response::builder() - .status(parts.status)) - .header("content-type", parts.headers.get("content-type") - .and_then(|v| v.to_str().ok()) - .unwrap_or("application/octet-stream")) - .header("cache-control", parts.headers.get("cache-control") - .and_then(|v| v.to_str().ok()) - .unwrap_or("no-cache")) + Ok(add_cors_headers(Response::builder().status(parts.status)) + .header( + "content-type", + parts + .headers + .get("content-type") + .and_then(|v| v.to_str().ok()) + .unwrap_or("application/octet-stream"), + ) + .header( + "cache-control", + parts + .headers + .get("cache-control") + .and_then(|v| v.to_str().ok()) + .unwrap_or("no-cache"), + ) .body(body) .unwrap()) } @@ -191,15 +212,20 @@ impl Service> for HttpService { tracing::error!("Failed to serialize NIP-11 document: {}", e); "{}".to_string() }); - - tracing::debug!("Serving NIP-11 relay information document to {}", self.remote); - + + tracing::debug!( + "Serving NIP-11 relay information document to {}", + self.remote + ); + return Box::pin(async move { - Ok(add_cors_headers(Response::builder().header("server", "ngit-grasp")) - .status(200) - .header("content-type", "application/nostr+json") - .body(Full::new(Bytes::from(json))) - .unwrap()) + Ok( + add_cors_headers(Response::builder().header("server", "ngit-grasp")) + .status(200) + .header("content-type", "application/nostr+json") + .body(Full::new(Bytes::from(json))) + .unwrap(), + ) }); } } @@ -221,12 +247,13 @@ impl Service> for HttpService { let addr = self.remote; let relay = self.relay.clone(); - + tokio::spawn(async move { match hyper::upgrade::on(req).await { Ok(upgraded) => { tracing::info!("WebSocket connection established from {}", addr); - if let Err(e) = relay.take_connection(TokioIo::new(upgraded), addr).await + if let Err(e) = + relay.take_connection(TokioIo::new(upgraded), addr).await { tracing::error!("Relay error for {}: {}", addr, e); } @@ -288,12 +315,12 @@ pub async fn run_server( tracing::info!("Domain: {}", config.domain); let listener = TcpListener::bind(&bind_addr).await?; - + loop { let (socket, addr) = listener.accept().await?; let io = TokioIo::new(socket); let service = HttpService::new(relay.clone(), config.clone(), addr, database.clone()); - + tokio::spawn(async move { if let Err(e) = http1::Builder::new() .serve_connection(io, service) diff --git a/src/http/nip11.rs b/src/http/nip11.rs index a93ee5f..593ef9a 100644 --- a/src/http/nip11.rs +++ b/src/http/nip11.rs @@ -1,10 +1,9 @@ +use crate::config::Config; /// NIP-11 Relay Information Document /// /// Implements NIP-11 relay information endpoint with GRASP-01 extensions. /// See: https://github.com/nostr-protocol/nips/blob/master/11.md - use serde::{Deserialize, Serialize}; -use crate::config::Config; /// NIP-11 Relay Information Document /// @@ -14,37 +13,36 @@ use crate::config::Config; pub struct RelayInformationDocument { /// Relay name pub name: String, - + /// Relay description pub description: String, - + /// Relay owner's public key (hex format) #[serde(skip_serializing_if = "Option::is_none")] pub pubkey: Option, - + /// Contact information for relay admin #[serde(skip_serializing_if = "Option::is_none")] pub contact: Option, - + /// List of NIPs supported by this relay pub supported_nips: Vec, - + /// Relay software identifier pub software: String, - + /// Software version pub version: String, - + // GRASP-01 Extensions (lines 11-14 of GRASP-01 spec) - /// List of supported GRASPs (e.g., ["GRASP-01"]) /// Required by GRASP-01 specification line 12 pub supported_grasps: Vec, - + /// Repository acceptance criteria description /// Required by GRASP-01 specification line 13 pub repo_acceptance_criteria: String, - + /// Curation policy (present if curated, absent otherwise) /// Optional per GRASP-01 specification line 14 #[serde(skip_serializing_if = "Option::is_none")] @@ -66,7 +64,7 @@ impl RelayInformationDocument { ], software: env!("CARGO_PKG_NAME").to_string(), version: env!("CARGO_PKG_VERSION").to_string(), - + // GRASP-01 Extensions supported_grasps: vec!["GRASP-01".to_string()], repo_acceptance_criteria: format!( @@ -77,7 +75,7 @@ impl RelayInformationDocument { curation: None, // Not a curated relay - only SPAM prevention via GRASP-01 policy } } - + /// Serialize to JSON string pub fn to_json(&self) -> Result { serde_json::to_string_pretty(self) @@ -102,7 +100,7 @@ mod tests { }; let doc = RelayInformationDocument::from_config(&config); - + assert_eq!(doc.name, "Test Relay"); assert_eq!(doc.description, "A test relay"); assert_eq!(doc.pubkey, Some("npub1test".to_string())); @@ -129,7 +127,7 @@ mod tests { let doc = RelayInformationDocument::from_config(&config); let json = doc.to_json().expect("Failed to serialize to JSON"); - + // Verify JSON contains expected fields assert!(json.contains("\"name\"")); assert!(json.contains("\"description\"")); @@ -137,10 +135,10 @@ mod tests { assert!(json.contains("\"supported_grasps\"")); assert!(json.contains("\"repo_acceptance_criteria\"")); assert!(json.contains("GRASP-01")); - + // Verify it's valid JSON by parsing let parsed: serde_json::Value = serde_json::from_str(&json).expect("Invalid JSON"); assert_eq!(parsed["name"], "Test Relay"); assert_eq!(parsed["supported_grasps"][0], "GRASP-01"); } -} \ No newline at end of file +} -- cgit v1.2.3