diff --git a/src/globals.rs b/src/globals.rs index d5253e0..b1f5ab5 100644 --- a/src/globals.rs +++ b/src/globals.rs @@ -9,6 +9,7 @@ pub struct Globals { pub config: RwLock, pub store: OnceLock, pub http_server: Http, + pub rid: OnceLock, } lazy_static! { @@ -21,6 +22,7 @@ lazy_static! { config: RwLock::new(Config::default()), store: OnceLock::new(), http_server, + rid: OnceLock::new(), } }; } diff --git a/src/main.rs b/src/main.rs index 5723ca2..d02dd28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -109,6 +109,15 @@ async fn serve(stream: MaybeTlsStream, peer_addr: SocketAddr) -> Resu Ok(()) } -async fn handle_request(_request: Request) -> Result, Error> { +async fn handle_request(request: Request) -> Result, Error> { + // check for Accept header of application/nostr+json + if let Some(accept) = request.headers().get("Accept") { + if let Ok(s) = accept.to_str() { + if s == "application/nostr+json" { + return web::serve_nip11().await; + } + } + } + web::serve_http().await } diff --git a/src/web.rs b/src/web.rs index 7bc11f3..f98339d 100644 --- a/src/web.rs +++ b/src/web.rs @@ -1,4 +1,6 @@ +use crate::config::Config; use crate::error::Error; +use crate::globals::GLOBALS; use hyper::{Body, Response, StatusCode}; pub async fn serve_http() -> Result, Error> { @@ -10,3 +12,57 @@ pub async fn serve_http() -> Result, Error> { .body("This is a nostr relay. Please use a nostr client to connect.".into())?; Ok(response) } + +pub async fn serve_nip11() -> Result, Error> { + let rid = { + let config = GLOBALS.config.read().await; + GLOBALS.rid.get_or_init(|| build_rid(&config)) + }; + + let response = Response::builder() + .header("Access-Control-Allow-Origin", "*") + .header("Access-Control-Allow-Headers", "*") + .header("Access-Control-Allow-Methods", "*") + .header("Content-Type", "application/nostr+json") + .status(StatusCode::OK) + .body(rid.clone().into())?; + Ok(response) +} + +fn build_rid(config: &Config) -> String { + let mut rid: String = String::with_capacity(255); + rid.push_str("{\"supported_nips\":[11],"); + + let software = env!("CARGO_PKG_NAME"); + rid.push_str("\"software\":\""); + rid.push_str(software); + rid.push('\"'); + + let version = env!("CARGO_PKG_VERSION"); + rid.push(','); + rid.push_str("\"version\":\""); + rid.push_str(version); + rid.push('\"'); + + if let Some(name) = &config.name { + rid.push(','); + rid.push_str("\"name\":\""); + rid.push_str(name); + rid.push('\"'); + } + if let Some(description) = &config.description { + rid.push(','); + rid.push_str("\"description\":\""); + rid.push_str(description); + rid.push('\"'); + } + if let Some(pubkeyhex) = &config.public_key_hex { + rid.push(','); + rid.push_str("\"pubkey\":\""); + rid.push_str(pubkeyhex); + rid.push('\"'); + } + rid.push('}'); + + rid +}