|
| 1 | +#[allow(unused_imports)] |
| 2 | +use http::header::HeaderName; |
| 3 | + |
| 4 | +mod sealed { |
| 5 | + #[allow(unreachable_pub, unused)] |
| 6 | + pub trait Sealed<R> {} |
| 7 | +} |
| 8 | + |
| 9 | +/// Extension trait that adds methods to any [`Service`] for adding middleware from |
| 10 | +/// tower-http. |
| 11 | +/// |
| 12 | +/// [`Service`]: tower::Service |
| 13 | +#[cfg(feature = "util")] |
| 14 | +// ^ work around rustdoc not inferring doc(cfg)s for cfg's from surrounding scopes |
| 15 | +pub trait ServiceExt<R>: sealed::Sealed<R> + tower::Service<R> + Sized { |
| 16 | + /// Propagate a header from the request to the response. |
| 17 | + /// |
| 18 | + /// See [`tower_http::propagate_header`] for more details. |
| 19 | + /// |
| 20 | + /// [`tower_http::propagate_header`]: crate::propagate_header |
| 21 | + #[cfg(feature = "propagate-header")] |
| 22 | + fn propagate_header( |
| 23 | + self, |
| 24 | + header: HeaderName, |
| 25 | + ) -> crate::propagate_header::PropagateHeader<Self> { |
| 26 | + crate::propagate_header::PropagateHeader::new(self, header) |
| 27 | + } |
| 28 | + |
| 29 | + /// Add some shareable value to [request extensions]. |
| 30 | + /// |
| 31 | + /// See [`tower_http::add_extension`] for more details. |
| 32 | + /// |
| 33 | + /// [`tower_http::add_extension`]: crate::add_extension |
| 34 | + /// [request extensions]: https://docs.rs/http/latest/http/struct.Extensions.html |
| 35 | + #[cfg(feature = "add-extension")] |
| 36 | + fn add_extension<T>(self, value: T) -> crate::add_extension::AddExtension<Self, T> { |
| 37 | + crate::add_extension::AddExtension::new(self, value) |
| 38 | + } |
| 39 | + |
| 40 | + /// Apply a transformation to the request body. |
| 41 | + /// |
| 42 | + /// See [`tower_http::map_request_body`] for more details. |
| 43 | + /// |
| 44 | + /// [`tower_http::map_request_body`]: crate::map_request_body |
| 45 | + #[cfg(feature = "map-request-body")] |
| 46 | + fn map_request_body<F>(self, f: F) -> crate::map_request_body::MapRequestBody<Self, F> { |
| 47 | + crate::map_request_body::MapRequestBody::new(self, f) |
| 48 | + } |
| 49 | + |
| 50 | + /// Apply a transformation to the response body. |
| 51 | + /// |
| 52 | + /// See [`tower_http::map_response_body`] for more details. |
| 53 | + /// |
| 54 | + /// [`tower_http::map_response_body`]: crate::map_response_body |
| 55 | + #[cfg(feature = "map-response-body")] |
| 56 | + fn map_response_body<F>(self, f: F) -> crate::map_response_body::MapResponseBody<Self, F> { |
| 57 | + crate::map_response_body::MapResponseBody::new(self, f) |
| 58 | + } |
| 59 | + |
| 60 | + /// Compresses response bodies. |
| 61 | + /// |
| 62 | + /// See [`tower_http::compression`] for more details. |
| 63 | + /// |
| 64 | + /// [`tower_http::compression`]: crate::compression |
| 65 | + #[cfg(any( |
| 66 | + feature = "compression-br", |
| 67 | + feature = "compression-deflate", |
| 68 | + feature = "compression-gzip", |
| 69 | + feature = "compression-zstd", |
| 70 | + ))] |
| 71 | + fn compression(self) -> crate::compression::Compression<Self> { |
| 72 | + crate::compression::Compression::new(self) |
| 73 | + } |
| 74 | + |
| 75 | + /// Decompress response bodies. |
| 76 | + /// |
| 77 | + /// See [`tower_http::decompression`] for more details. |
| 78 | + /// |
| 79 | + /// [`tower_http::decompression`]: crate::decompression |
| 80 | + #[cfg(any( |
| 81 | + feature = "decompression-br", |
| 82 | + feature = "decompression-deflate", |
| 83 | + feature = "decompression-gzip", |
| 84 | + feature = "decompression-zstd", |
| 85 | + ))] |
| 86 | + fn decompression(self) -> crate::decompression::Decompression<Self> { |
| 87 | + crate::decompression::Decompression::new(self) |
| 88 | + } |
| 89 | + |
| 90 | + /// High level tracing that classifies responses using HTTP status codes. |
| 91 | + /// |
| 92 | + /// This method does not support customizing the output, to do that use [`TraceLayer`] |
| 93 | + /// instead. |
| 94 | + /// |
| 95 | + /// See [`tower_http::trace`] for more details. |
| 96 | + /// |
| 97 | + /// [`tower_http::trace`]: crate::trace |
| 98 | + /// [`TraceLayer`]: crate::trace::TraceLayer |
| 99 | + #[cfg(feature = "trace")] |
| 100 | + fn trace_for_http(self) -> crate::trace::Trace<Self, crate::trace::HttpMakeClassifier> { |
| 101 | + crate::trace::Trace::new_for_http(self) |
| 102 | + } |
| 103 | + |
| 104 | + /// High level tracing that classifies responses using gRPC headers. |
| 105 | + /// |
| 106 | + /// This method does not support customizing the output, to do that use [`TraceLayer`] |
| 107 | + /// instead. |
| 108 | + /// |
| 109 | + /// See [`tower_http::trace`] for more details. |
| 110 | + /// |
| 111 | + /// [`tower_http::trace`]: crate::trace |
| 112 | + /// [`TraceLayer`]: crate::trace::TraceLayer |
| 113 | + #[cfg(feature = "trace")] |
| 114 | + fn trace_for_grpc(self) -> crate::trace::Trace<Self, crate::trace::GrpcMakeClassifier> { |
| 115 | + crate::trace::Trace::new_for_grpc(self) |
| 116 | + } |
| 117 | + |
| 118 | + /// Follow redirect resposes using the [`Standard`] policy. |
| 119 | + /// |
| 120 | + /// See [`tower_http::follow_redirect`] for more details. |
| 121 | + /// |
| 122 | + /// [`tower_http::follow_redirect`]: crate::follow_redirect |
| 123 | + /// [`Standard`]: crate::follow_redirect::policy::Standard |
| 124 | + #[cfg(feature = "follow-redirect")] |
| 125 | + fn follow_redirects( |
| 126 | + self, |
| 127 | + ) -> crate::follow_redirect::FollowRedirect<Self, crate::follow_redirect::policy::Standard> |
| 128 | + { |
| 129 | + crate::follow_redirect::FollowRedirect::new(self) |
| 130 | + } |
| 131 | + |
| 132 | + /// Mark headers as [sensitive] on both requests and responses. |
| 133 | + /// |
| 134 | + /// See [`tower_http::sensitive_headers`] for more details. |
| 135 | + /// |
| 136 | + /// [sensitive]: https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive |
| 137 | + /// [`tower_http::sensitive_headers`]: crate::sensitive_headers |
| 138 | + #[cfg(feature = "sensitive-headers")] |
| 139 | + fn sensitive_headers( |
| 140 | + self, |
| 141 | + headers: impl IntoIterator<Item = HeaderName>, |
| 142 | + ) -> crate::sensitive_headers::SetSensitiveHeaders<Self> { |
| 143 | + use tower_layer::Layer as _; |
| 144 | + crate::sensitive_headers::SetSensitiveHeadersLayer::new(headers).layer(self) |
| 145 | + } |
| 146 | + |
| 147 | + /// Mark headers as [sensitive] on requests. |
| 148 | + /// |
| 149 | + /// See [`tower_http::sensitive_headers`] for more details. |
| 150 | + /// |
| 151 | + /// [sensitive]: https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive |
| 152 | + /// [`tower_http::sensitive_headers`]: crate::sensitive_headers |
| 153 | + #[cfg(feature = "sensitive-headers")] |
| 154 | + fn sensitive_request_headers( |
| 155 | + self, |
| 156 | + headers: impl IntoIterator<Item = HeaderName>, |
| 157 | + ) -> crate::sensitive_headers::SetSensitiveRequestHeaders<Self> { |
| 158 | + crate::sensitive_headers::SetSensitiveRequestHeaders::new(self, headers) |
| 159 | + } |
| 160 | + |
| 161 | + /// Mark headers as [sensitive] on responses. |
| 162 | + /// |
| 163 | + /// See [`tower_http::sensitive_headers`] for more details. |
| 164 | + /// |
| 165 | + /// [sensitive]: https://docs.rs/http/latest/http/header/struct.HeaderValue.html#method.set_sensitive |
| 166 | + /// [`tower_http::sensitive_headers`]: crate::sensitive_headers |
| 167 | + #[cfg(feature = "sensitive-headers")] |
| 168 | + fn sensitive_response_headers( |
| 169 | + self, |
| 170 | + headers: impl IntoIterator<Item = HeaderName>, |
| 171 | + ) -> crate::sensitive_headers::SetSensitiveResponseHeaders<Self> { |
| 172 | + crate::sensitive_headers::SetSensitiveResponseHeaders::new(self, headers) |
| 173 | + } |
| 174 | + |
| 175 | + /// Insert a header into the request. |
| 176 | + /// |
| 177 | + /// If a previous value exists for the same header, it is removed and replaced with the new |
| 178 | + /// header value. |
| 179 | + /// |
| 180 | + /// See [`tower_http::set_header`] for more details. |
| 181 | + /// |
| 182 | + /// [`tower_http::set_header`]: crate::set_header |
| 183 | + #[cfg(feature = "set-header")] |
| 184 | + fn override_request_header<M>( |
| 185 | + self, |
| 186 | + header_name: HeaderName, |
| 187 | + make: M, |
| 188 | + ) -> crate::set_header::SetRequestHeader<Self, M> { |
| 189 | + crate::set_header::SetRequestHeader::overriding(self, header_name, make) |
| 190 | + } |
| 191 | + |
| 192 | + /// Append a header into the request. |
| 193 | + /// |
| 194 | + /// If previous values exist, the header will have multiple values. |
| 195 | + /// |
| 196 | + /// See [`tower_http::set_header`] for more details. |
| 197 | + /// |
| 198 | + /// [`tower_http::set_header`]: crate::set_header |
| 199 | + #[cfg(feature = "set-header")] |
| 200 | + fn append_request_header<M>( |
| 201 | + self, |
| 202 | + header_name: HeaderName, |
| 203 | + make: M, |
| 204 | + ) -> crate::set_header::SetRequestHeader<Self, M> { |
| 205 | + crate::set_header::SetRequestHeader::appending(self, header_name, make) |
| 206 | + } |
| 207 | + |
| 208 | + /// Insert a header into the request, if the header is not already present. |
| 209 | + /// |
| 210 | + /// See [`tower_http::set_header`] for more details. |
| 211 | + /// |
| 212 | + /// [`tower_http::set_header`]: crate::set_header |
| 213 | + #[cfg(feature = "set-header")] |
| 214 | + fn insert_request_header_if_not_present<M>( |
| 215 | + self, |
| 216 | + header_name: HeaderName, |
| 217 | + make: M, |
| 218 | + ) -> crate::set_header::SetRequestHeader<Self, M> { |
| 219 | + crate::set_header::SetRequestHeader::if_not_present(self, header_name, make) |
| 220 | + } |
| 221 | + |
| 222 | + /// Insert a header into the response. |
| 223 | + /// |
| 224 | + /// If a previous value exists for the same header, it is removed and replaced with the new |
| 225 | + /// header value. |
| 226 | + /// |
| 227 | + /// See [`tower_http::set_header`] for more details. |
| 228 | + /// |
| 229 | + /// [`tower_http::set_header`]: crate::set_header |
| 230 | + #[cfg(feature = "set-header")] |
| 231 | + fn override_response_header<M>( |
| 232 | + self, |
| 233 | + header_name: HeaderName, |
| 234 | + make: M, |
| 235 | + ) -> crate::set_header::SetResponseHeader<Self, M> { |
| 236 | + crate::set_header::SetResponseHeader::overriding(self, header_name, make) |
| 237 | + } |
| 238 | + |
| 239 | + /// Append a header into the response. |
| 240 | + /// |
| 241 | + /// If previous values exist, the header will have multiple values. |
| 242 | + /// |
| 243 | + /// See [`tower_http::set_header`] for more details. |
| 244 | + /// |
| 245 | + /// [`tower_http::set_header`]: crate::set_header |
| 246 | + #[cfg(feature = "set-header")] |
| 247 | + fn append_response_header<M>( |
| 248 | + self, |
| 249 | + header_name: HeaderName, |
| 250 | + make: M, |
| 251 | + ) -> crate::set_header::SetResponseHeader<Self, M> { |
| 252 | + crate::set_header::SetResponseHeader::appending(self, header_name, make) |
| 253 | + } |
| 254 | + |
| 255 | + /// Insert a header into the response, if the header is not already present. |
| 256 | + /// |
| 257 | + /// See [`tower_http::set_header`] for more details. |
| 258 | + /// |
| 259 | + /// [`tower_http::set_header`]: crate::set_header |
| 260 | + #[cfg(feature = "set-header")] |
| 261 | + fn insert_response_header_if_not_present<M>( |
| 262 | + self, |
| 263 | + header_name: HeaderName, |
| 264 | + make: M, |
| 265 | + ) -> crate::set_header::SetResponseHeader<Self, M> { |
| 266 | + crate::set_header::SetResponseHeader::if_not_present(self, header_name, make) |
| 267 | + } |
| 268 | + |
| 269 | + /// Add request id header and extension. |
| 270 | + /// |
| 271 | + /// See [`tower_http::request_id`] for more details. |
| 272 | + /// |
| 273 | + /// [`tower_http::request_id`]: crate::request_id |
| 274 | + #[cfg(feature = "request-id")] |
| 275 | + fn set_request_id<M>( |
| 276 | + self, |
| 277 | + header_name: HeaderName, |
| 278 | + make_request_id: M, |
| 279 | + ) -> crate::request_id::SetRequestId<Self, M> |
| 280 | + where |
| 281 | + M: crate::request_id::MakeRequestId, |
| 282 | + { |
| 283 | + crate::request_id::SetRequestId::new(self, header_name, make_request_id) |
| 284 | + } |
| 285 | + |
| 286 | + /// Add request id header and extension, using `x-request-id` as the header name. |
| 287 | + /// |
| 288 | + /// See [`tower_http::request_id`] for more details. |
| 289 | + /// |
| 290 | + /// [`tower_http::request_id`]: crate::request_id |
| 291 | + #[cfg(feature = "request-id")] |
| 292 | + fn set_x_request_id<M>(self, make_request_id: M) -> crate::request_id::SetRequestId<Self, M> |
| 293 | + where |
| 294 | + M: crate::request_id::MakeRequestId, |
| 295 | + { |
| 296 | + self.set_request_id(crate::request_id::X_REQUEST_ID, make_request_id) |
| 297 | + } |
| 298 | + |
| 299 | + /// Propgate request ids from requests to responses. |
| 300 | + /// |
| 301 | + /// See [`tower_http::request_id`] for more details. |
| 302 | + /// |
| 303 | + /// [`tower_http::request_id`]: crate::request_id |
| 304 | + #[cfg(feature = "request-id")] |
| 305 | + fn propagate_request_id( |
| 306 | + self, |
| 307 | + header_name: HeaderName, |
| 308 | + ) -> crate::request_id::PropagateRequestId<Self> { |
| 309 | + crate::request_id::PropagateRequestId::new(self, header_name) |
| 310 | + } |
| 311 | + |
| 312 | + /// Propgate request ids from requests to responses, using `x-request-id` as the header name. |
| 313 | + /// |
| 314 | + /// See [`tower_http::request_id`] for more details. |
| 315 | + /// |
| 316 | + /// [`tower_http::request_id`]: crate::request_id |
| 317 | + #[cfg(feature = "request-id")] |
| 318 | + fn propagate_x_request_id(self) -> crate::request_id::PropagateRequestId<Self> { |
| 319 | + self.propagate_request_id(crate::request_id::X_REQUEST_ID) |
| 320 | + } |
| 321 | + |
| 322 | + /// Catch panics and convert them into `500 Internal Server` responses. |
| 323 | + /// |
| 324 | + /// See [`tower_http::catch_panic`] for more details. |
| 325 | + /// |
| 326 | + /// [`tower_http::catch_panic`]: crate::catch_panic |
| 327 | + #[cfg(feature = "catch-panic")] |
| 328 | + fn catch_panic( |
| 329 | + self, |
| 330 | + ) -> crate::catch_panic::CatchPanic<Self, crate::catch_panic::DefaultResponseForPanic> { |
| 331 | + crate::catch_panic::CatchPanic::new(self) |
| 332 | + } |
| 333 | + |
| 334 | + /// Intercept requests with over-sized payloads and convert them into |
| 335 | + /// `413 Payload Too Large` responses. |
| 336 | + /// |
| 337 | + /// See [`tower_http::limit`] for more details. |
| 338 | + /// |
| 339 | + /// [`tower_http::limit`]: crate::limit |
| 340 | + #[cfg(feature = "limit")] |
| 341 | + fn request_body_limit(self, limit: usize) -> crate::limit::RequestBodyLimit<Self> { |
| 342 | + crate::limit::RequestBodyLimit::new(self, limit) |
| 343 | + } |
| 344 | + |
| 345 | + /// Remove trailing slashes from paths. |
| 346 | + /// |
| 347 | + /// See [`tower_http::normalize_path`] for more details. |
| 348 | + /// |
| 349 | + /// [`tower_http::normalize_path`]: crate::normalize_path |
| 350 | + #[cfg(feature = "normalize-path")] |
| 351 | + fn trim_trailing_slash(self) -> crate::normalize_path::NormalizePath<Self> { |
| 352 | + crate::normalize_path::NormalizePath::trim_trailing_slash(self) |
| 353 | + } |
| 354 | +} |
| 355 | + |
| 356 | +impl<R, T> sealed::Sealed<R> for T where T: tower::Service<R> {} |
| 357 | +impl<R, T> ServiceExt<R> for T where T: tower::Service<R> {} |
0 commit comments