diff --git a/bobbin/crates/xrpc/src/lib.rs b/bobbin/crates/xrpc/src/lib.rs index 370859eb..23ffaa5b 100644 --- a/bobbin/crates/xrpc/src/lib.rs +++ b/bobbin/crates/xrpc/src/lib.rs @@ -11,7 +11,7 @@ use axum::{ body::Body, extract::{FromRequestParts, Query, RawQuery, State, rejection::QueryRejection}, http::{ - HeaderMap, HeaderName, StatusCode, + HeaderMap, HeaderName, StatusCode, Uri, header::{ ACCEPT_RANGES, CACHE_CONTROL, CONTENT_DISPOSITION, CONTENT_ENCODING, CONTENT_LENGTH, CONTENT_RANGE, CONTENT_TYPE, ETAG, IF_MODIFIED_SINCE, IF_NONE_MATCH, IF_RANGE, @@ -389,6 +389,8 @@ pub fn router(state: AppState) -> Router { get(resolve_mini_doc), ) .merge(knot_proxied_routes()) + .fallback(fallback) + .method_not_allowed_fallback(method_not_allowed) .layer( TraceLayer::new_for_http() .make_span_with(DefaultMakeSpan::new().level(Level::INFO)) @@ -399,6 +401,26 @@ pub fn router(state: AppState) -> Router { .with_state(state) } +async fn fallback(uri: Uri) -> Response { + if uri.path().starts_with("/xrpc/") { + let body = ErrorBody { + error: "MethodNotImplemented", + message: "method not implemented".into(), + }; + (StatusCode::NOT_IMPLEMENTED, Json(body)).into_response() + } else { + StatusCode::NOT_FOUND.into_response() + } +} + +async fn method_not_allowed() -> Response { + let body = ErrorBody { + error: "MethodNotAllowed", + message: "method not allowed".into(), + }; + (StatusCode::METHOD_NOT_ALLOWED, Json(body)).into_response() +} + #[derive(Clone, Copy, Debug)] struct LatencyFreeTrace;