diff --git a/.changesets/maint_bnjjj_fix_3929.md b/.changesets/maint_bnjjj_fix_3929.md new file mode 100644 index 0000000000..a4e1d82df6 --- /dev/null +++ b/.changesets/maint_bnjjj_fix_3929.md @@ -0,0 +1,5 @@ +### Router should respond with subscription-protocol header for callback ([Issue #3929](https://github.com/apollographql/router/issues/3929)) + +Callback protocol documentation specifies that router responds with `subscription-protocol: callback/1.0` header to the initialization (check) message. Currently router does not set this header on the response. + +By [@bnjjj](https://github.com/bnjjj) in https://github.com/apollographql/router/pull/3939 \ No newline at end of file diff --git a/apollo-router/src/plugins/subscription.rs b/apollo-router/src/plugins/subscription.rs index ee8023c368..0aa2c1765e 100644 --- a/apollo-router/src/plugins/subscription.rs +++ b/apollo-router/src/plugins/subscription.rs @@ -7,6 +7,8 @@ use bytes::Buf; use futures::future::BoxFuture; use hmac::Hmac; use hmac::Mac; +use http::HeaderName; +use http::HeaderValue; use http::Method; use http::StatusCode; use multimap::MultiMap; @@ -46,6 +48,8 @@ pub(crate) const APOLLO_SUBSCRIPTION_PLUGIN_NAME: &str = "subscription"; pub(crate) static SUBSCRIPTION_CALLBACK_HMAC_KEY: OnceCell = OnceCell::new(); pub(crate) const SUBSCRIPTION_WS_CUSTOM_CONNECTION_PARAMS: &str = "apollo.subscription.custom_connection_params"; +const CALLBACK_SUBSCRIPTION_HEADER_NAME: &str = "subscription-protocol"; +const CALLBACK_SUBSCRIPTION_HEADER_VALUE: &str = "callback/1.0"; #[derive(Debug, Clone)] pub(crate) struct Subscription { @@ -464,6 +468,7 @@ impl Service for CallbackService { Ok(router::Response { response: http::Response::builder() .status(StatusCode::NO_CONTENT) + .header(HeaderName::from_static(CALLBACK_SUBSCRIPTION_HEADER_NAME), HeaderValue::from_static(CALLBACK_SUBSCRIPTION_HEADER_VALUE)) .body::("".into()) .map_err(BoxError::from)?, context: req.context, @@ -472,6 +477,7 @@ impl Service for CallbackService { Ok(router::Response { response: http::Response::builder() .status(StatusCode::NOT_FOUND) + .header(HeaderName::from_static(CALLBACK_SUBSCRIPTION_HEADER_NAME), HeaderValue::from_static(CALLBACK_SUBSCRIPTION_HEADER_VALUE)) .body("suscription doesn't exist".into()) .map_err(BoxError::from)?, context: req.context, @@ -694,6 +700,12 @@ mod tests { .unwrap(); let resp = web_endpoint.clone().oneshot(http_req).await.unwrap(); assert_eq!(resp.status(), http::StatusCode::NO_CONTENT); + assert_eq!( + resp.headers() + .get(HeaderName::from_static(CALLBACK_SUBSCRIPTION_HEADER_NAME)) + .unwrap(), + HeaderValue::from_static(CALLBACK_SUBSCRIPTION_HEADER_VALUE) + ); let http_req = http::Request::post(format!( "http://localhost:4000/subscription/callback/{new_sub_id}" @@ -912,6 +924,12 @@ mod tests { .unwrap(); let resp = web_endpoint.clone().oneshot(http_req).await.unwrap(); assert_eq!(resp.status(), http::StatusCode::NO_CONTENT); + assert_eq!( + resp.headers() + .get(HeaderName::from_static(CALLBACK_SUBSCRIPTION_HEADER_NAME)) + .unwrap(), + HeaderValue::from_static(CALLBACK_SUBSCRIPTION_HEADER_VALUE) + ); let http_req = http::Request::post(format!( "http://localhost:4000/subscription/callback/{new_sub_id}"