1use std::{collections::VecDeque, fmt, future::Future, io, pin::Pin};
4
5use tokio::io::{AsyncRead, AsyncWrite};
6
7use crate::{
8 ConnectTarget, NoPipeline, StartupParameters,
9 pipeline::{BackendAction, FrontendAction, FrontendHandling, Pipeline, PipelinePolicy},
10};
11
12#[derive(Clone, Copy, Debug, Eq, PartialEq)]
17pub enum CancellationPolicy {
18 Reject,
20 Forward,
22}
23
24#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
26pub enum EstablishmentFailurePolicy {
27 #[default]
29 Close,
30 SafeDiagnostic,
32}
33
34fn safe_establishment_diagnostic() -> crate::codec::BackendMessage {
35 crate::codec::BackendMessage::ErrorResponse(crate::codec::DiagnosticResponse {
36 fields: vec![
37 crate::codec::DiagnosticField {
38 code: b'S',
39 value: bytes::Bytes::from_static(b"ERROR"),
40 },
41 crate::codec::DiagnosticField {
42 code: b'M',
43 value: bytes::Bytes::from_static(b"connection establishment failed"),
44 },
45 ],
46 })
47}
48
49#[derive(Clone, Debug, Eq, PartialEq)]
51pub struct CancellationRoute {
52 target: ConnectTarget,
53 upstream: crate::demux::CancelKey,
54}
55
56impl CancellationRoute {
57 #[must_use]
59 pub const fn new(target: ConnectTarget, upstream: crate::demux::CancelKey) -> Self {
60 Self { target, upstream }
61 }
62 #[must_use]
64 pub const fn target(&self) -> &ConnectTarget {
65 &self.target
66 }
67 #[must_use]
69 pub const fn upstream_key(&self) -> &crate::demux::CancelKey {
70 &self.upstream
71 }
72}
73
74pub trait IntermediaryCancellationRegistry {
80 type Error;
82 fn register(&self, route: CancellationRoute) -> Result<crate::demux::CancelKey, Self::Error>;
88 fn resolve(&self, client: &crate::demux::CancelKey) -> Option<CancellationRoute>;
90 fn detach(&self, client: &crate::demux::CancelKey) -> Option<CancellationRoute>;
92}
93
94#[derive(Clone, Copy, Debug, Default)]
96pub struct RejectCancellation;
97impl IntermediaryCancellationRegistry for RejectCancellation {
98 type Error = std::convert::Infallible;
99 fn register(&self, _: CancellationRoute) -> Result<crate::demux::CancelKey, Self::Error> {
100 unreachable!()
101 }
102 fn resolve(&self, _: &crate::demux::CancelKey) -> Option<CancellationRoute> {
103 None
104 }
105 fn detach(&self, _: &crate::demux::CancelKey) -> Option<CancellationRoute> {
106 None
107 }
108}
109
110#[derive(Clone, Copy, Debug, Eq, PartialEq)]
112pub enum IntermediaryBuildError {
113 MissingServer,
115 MissingClient,
117 MissingStartupResolver,
119 MissingCancellationPolicy,
121}
122
123impl fmt::Display for IntermediaryBuildError {
124 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
125 formatter.write_str(match self {
126 Self::MissingServer => "an intermediary server component is required",
127 Self::MissingClient => "an intermediary client component is required",
128 Self::MissingStartupResolver => "an asynchronous startup resolver is required",
129 Self::MissingCancellationPolicy => "an explicit cancellation policy is required",
130 })
131 }
132}
133
134impl std::error::Error for IntermediaryBuildError {}
135
136#[derive(Clone, Copy, Debug)]
138pub struct InitialServerContext<'a, Peer> {
139 peer: &'a Peer,
140 tls: &'a crate::NegotiatedServerTls,
141}
142
143impl<'a, Peer> InitialServerContext<'a, Peer> {
144 pub(crate) const fn new(peer: &'a Peer, tls: &'a crate::NegotiatedServerTls) -> Self {
145 Self { peer, tls }
146 }
147
148 #[must_use]
150 pub const fn peer(&self) -> &Peer {
151 self.peer
152 }
153
154 #[must_use]
156 pub const fn tls(&self) -> &crate::NegotiatedServerTls {
157 self.tls
158 }
159}
160
161pub trait StartupRouteResolver<Peer> {
163 type Error;
165
166 fn resolve<'a>(
168 &'a self,
169 startup: StartupParameters,
170 context: InitialServerContext<'a, Peer>,
171 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>>;
172}
173
174pub trait AuthenticatedRoutePolicy<Peer, Identity> {
176 type Error;
178 fn route<'a>(
180 &'a self,
181 target: ConnectTarget,
182 context: AuthenticatedRouteContext<'a, Peer, Identity>,
183 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>>;
184}
185
186#[derive(Clone, Copy, Debug)]
188pub struct AuthenticatedRouteContext<'a, Peer, Identity> {
189 peer: &'a Peer,
190 identity: &'a Identity,
191}
192
193impl<Peer, Identity> AuthenticatedRouteContext<'_, Peer, Identity> {
194 #[must_use]
196 pub const fn peer(&self) -> &Peer {
197 self.peer
198 }
199
200 #[must_use]
202 pub const fn identity(&self) -> &Identity {
203 self.identity
204 }
205}
206
207#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
209pub struct AllowAuthenticatedRoute;
210
211impl<Peer, Identity> AuthenticatedRoutePolicy<Peer, Identity> for AllowAuthenticatedRoute {
212 type Error = std::convert::Infallible;
213 fn route<'a>(
214 &'a self,
215 target: ConnectTarget,
216 _context: AuthenticatedRouteContext<'a, Peer, Identity>,
217 ) -> Pin<Box<dyn Future<Output = Result<ConnectTarget, Self::Error>> + 'a>> {
218 Box::pin(async move { Ok(target) })
219 }
220}
221
222#[derive(Debug, Eq, PartialEq)]
224pub enum FrontendMiddlewareOutput {
225 Forward(crate::codec::FrontendMessage),
227 Suppress(crate::codec::FrontendMessage),
229 Respond {
231 request: crate::codec::FrontendMessage,
233 responses: Vec<crate::codec::BackendMessage>,
235 },
236}
237
238#[derive(Debug, Eq, PartialEq)]
240pub enum BackendMiddlewareOutput {
241 Forward(crate::codec::BackendMessage),
243 Suppress(crate::codec::BackendMessage),
245}
246
247pub trait IntermediaryMiddleware<State, ServerContext, ClientContext> {
249 type Error;
251
252 fn frontend<'a>(
255 &'a mut self,
256 _server: &'a ServerContext,
257 _client: &'a ClientContext,
258 _state: &'a mut State,
259 message: crate::codec::FrontendMessage,
260 ) -> Pin<Box<dyn Future<Output = Result<FrontendMiddlewareOutput, Self::Error>> + 'a>> {
261 Box::pin(async move { Ok(FrontendMiddlewareOutput::Forward(message)) })
262 }
263
264 fn backend<'a>(
267 &'a mut self,
268 _server: &'a ServerContext,
269 _client: &'a ClientContext,
270 _state: &'a mut State,
271 message: crate::codec::BackendMessage,
272 ) -> Pin<Box<dyn Future<Output = Result<BackendMiddlewareOutput, Self::Error>> + 'a>> {
273 Box::pin(async move { Ok(BackendMiddlewareOutput::Forward(message)) })
274 }
275}
276
277#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
279pub struct IdentityIntermediaryMiddleware;
280
281impl<State, ServerContext, ClientContext>
282 IntermediaryMiddleware<State, ServerContext, ClientContext> for IdentityIntermediaryMiddleware
283{
284 type Error = std::convert::Infallible;
285}
286
287pub trait IntermediaryMiddlewareFactory<ServerContext, ClientContext> {
289 type Handler;
291 fn create(&self, server: &ServerContext, client: &ClientContext) -> Self::Handler;
293}
294
295impl<ServerContext, ClientContext, Handler, Factory>
296 IntermediaryMiddlewareFactory<ServerContext, ClientContext> for Factory
297where
298 Factory: Fn(&ServerContext, &ClientContext) -> Handler,
299{
300 type Handler = Handler;
301 fn create(&self, server: &ServerContext, client: &ClientContext) -> Handler {
302 self(server, client)
303 }
304}
305
306impl<ServerContext, ClientContext> IntermediaryMiddlewareFactory<ServerContext, ClientContext>
307 for IdentityIntermediaryMiddleware
308{
309 type Handler = Self;
310 fn create(&self, _server: &ServerContext, _client: &ClientContext) -> Self {
311 *self
312 }
313}
314
315pub struct Intermediary<
317 Server = (),
318 Client = (),
319 Resolver = (),
320 Route = AllowAuthenticatedRoute,
321 Policy = NoPipeline,
322 Boundary = IdentityIntermediaryMiddleware,
323 Cancellation = RejectCancellation,
324> {
325 pub(crate) server: Server,
326 pub(crate) client: Client,
327 pub(crate) resolver: Resolver,
328 pub(crate) route: Route,
329 pub(crate) pipeline: Policy,
330 pub(crate) boundary: Boundary,
331 pub(crate) cancellation: CancellationPolicy,
332 pub(crate) cancellation_registry: Cancellation,
333 pub(crate) failure_policy: EstablishmentFailurePolicy,
334}
335
336impl Intermediary<()> {
337 #[must_use]
339 pub fn builder() -> IntermediaryBuilder {
340 IntermediaryBuilder::default()
341 }
342}
343
344impl<S, C, R, A, P, B, K> fmt::Debug for Intermediary<S, C, R, A, P, B, K> {
345 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
346 formatter
347 .debug_struct("Intermediary")
348 .field("server", &"<configured>")
349 .field("client", &"<configured>")
350 .field("resolver", &"<redacted>")
351 .field("authenticated_route", &"<redacted>")
352 .field("cancellation", &self.cancellation)
353 .finish_non_exhaustive()
354 }
355}
356
357pub struct IntermediaryBuilder<
359 Server = (),
360 Client = (),
361 Resolver = (),
362 Route = AllowAuthenticatedRoute,
363 Policy = NoPipeline,
364 Boundary = IdentityIntermediaryMiddleware,
365 Cancellation = RejectCancellation,
366> {
367 server: Option<Server>,
368 client: Option<Client>,
369 resolver: Option<Resolver>,
370 route: Route,
371 pipeline: Policy,
372 boundary: Boundary,
373 cancellation: Option<CancellationPolicy>,
374 cancellation_registry: Cancellation,
375 failure_policy: EstablishmentFailurePolicy,
376}
377
378impl Default for IntermediaryBuilder {
379 fn default() -> Self {
380 Self {
381 server: None,
382 client: None,
383 resolver: None,
384 route: AllowAuthenticatedRoute,
385 pipeline: NoPipeline,
386 boundary: IdentityIntermediaryMiddleware,
387 cancellation: None,
388 cancellation_registry: RejectCancellation,
389 failure_policy: EstablishmentFailurePolicy::Close,
390 }
391 }
392}
393
394impl<S, C, R, A, P, B, K> IntermediaryBuilder<S, C, R, A, P, B, K> {
395 #[must_use]
397 pub fn server<Next>(self, server: Next) -> IntermediaryBuilder<Next, C, R, A, P, B, K> {
398 IntermediaryBuilder {
399 server: Some(server),
400 client: self.client,
401 resolver: self.resolver,
402 route: self.route,
403 pipeline: self.pipeline,
404 boundary: self.boundary,
405 cancellation: self.cancellation,
406 cancellation_registry: self.cancellation_registry,
407 failure_policy: self.failure_policy,
408 }
409 }
410
411 #[must_use]
413 pub fn client<Next>(self, client: Next) -> IntermediaryBuilder<S, Next, R, A, P, B, K> {
414 IntermediaryBuilder {
415 server: self.server,
416 client: Some(client),
417 resolver: self.resolver,
418 route: self.route,
419 pipeline: self.pipeline,
420 boundary: self.boundary,
421 cancellation: self.cancellation,
422 cancellation_registry: self.cancellation_registry,
423 failure_policy: self.failure_policy,
424 }
425 }
426
427 #[must_use]
429 pub fn startup_resolver<Next>(
430 self,
431 resolver: Next,
432 ) -> IntermediaryBuilder<S, C, Next, A, P, B, K> {
433 IntermediaryBuilder {
434 server: self.server,
435 client: self.client,
436 resolver: Some(resolver),
437 route: self.route,
438 pipeline: self.pipeline,
439 boundary: self.boundary,
440 cancellation: self.cancellation,
441 cancellation_registry: self.cancellation_registry,
442 failure_policy: self.failure_policy,
443 }
444 }
445
446 #[must_use]
448 pub fn authenticated_route<Next>(
449 self,
450 route: Next,
451 ) -> IntermediaryBuilder<S, C, R, Next, P, B, K> {
452 IntermediaryBuilder {
453 server: self.server,
454 client: self.client,
455 resolver: self.resolver,
456 route,
457 pipeline: self.pipeline,
458 boundary: self.boundary,
459 cancellation: self.cancellation,
460 cancellation_registry: self.cancellation_registry,
461 failure_policy: self.failure_policy,
462 }
463 }
464
465 #[must_use]
467 pub fn pipeline<Next: PipelinePolicy>(
468 self,
469 pipeline: Next,
470 ) -> IntermediaryBuilder<S, C, R, A, Next, B, K> {
471 IntermediaryBuilder {
472 server: self.server,
473 client: self.client,
474 resolver: self.resolver,
475 route: self.route,
476 pipeline,
477 boundary: self.boundary,
478 cancellation: self.cancellation,
479 cancellation_registry: self.cancellation_registry,
480 failure_policy: self.failure_policy,
481 }
482 }
483
484 #[must_use]
486 pub fn middleware<Next>(self, boundary: Next) -> IntermediaryBuilder<S, C, R, A, P, Next, K> {
487 IntermediaryBuilder {
488 server: self.server,
489 client: self.client,
490 resolver: self.resolver,
491 route: self.route,
492 pipeline: self.pipeline,
493 boundary,
494 cancellation: self.cancellation,
495 cancellation_registry: self.cancellation_registry,
496 failure_policy: self.failure_policy,
497 }
498 }
499
500 #[must_use]
502 pub fn cancellation(mut self, cancellation: CancellationPolicy) -> Self {
503 self.cancellation = match cancellation {
504 CancellationPolicy::Reject => Some(CancellationPolicy::Reject),
505 CancellationPolicy::Forward => None,
506 };
507 self
508 }
509
510 #[must_use]
512 pub fn establishment_failure(mut self, policy: EstablishmentFailurePolicy) -> Self {
513 self.failure_policy = policy;
514 self
515 }
516
517 #[must_use]
519 pub fn cancellation_registry<Next>(
520 self,
521 registry: Next,
522 ) -> IntermediaryBuilder<S, C, R, A, P, B, Next> {
523 IntermediaryBuilder {
524 server: self.server,
525 client: self.client,
526 resolver: self.resolver,
527 route: self.route,
528 pipeline: self.pipeline,
529 boundary: self.boundary,
530 cancellation: Some(CancellationPolicy::Forward),
531 cancellation_registry: registry,
532 failure_policy: self.failure_policy,
533 }
534 }
535
536 #[allow(clippy::type_complexity)]
542 pub fn build(self) -> Result<Intermediary<S, C, R, A, P, B, K>, IntermediaryBuildError> {
543 Ok(Intermediary {
544 server: self.server.ok_or(IntermediaryBuildError::MissingServer)?,
545 client: self.client.ok_or(IntermediaryBuildError::MissingClient)?,
546 resolver: self
547 .resolver
548 .ok_or(IntermediaryBuildError::MissingStartupResolver)?,
549 route: self.route,
550 pipeline: self.pipeline,
551 boundary: self.boundary,
552 cancellation: self
553 .cancellation
554 .ok_or(IntermediaryBuildError::MissingCancellationPolicy)?,
555 cancellation_registry: self.cancellation_registry,
556 failure_policy: self.failure_policy,
557 })
558 }
559}
560
561struct StartupResolverAdapter<'a, Resolver> {
562 resolver: &'a Resolver,
563}
564
565#[derive(Debug)]
567pub enum StartupResolutionError<Error> {
568 Parameters(io::Error),
570 Resolver(Error),
572}
573
574impl<Error: fmt::Display> fmt::Display for StartupResolutionError<Error> {
575 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
576 match self {
577 Self::Parameters(error) => error.fmt(formatter),
578 Self::Resolver(error) => error.fmt(formatter),
579 }
580 }
581}
582
583impl<Error: std::error::Error + 'static> std::error::Error for StartupResolutionError<Error> {
584 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
585 match self {
586 Self::Parameters(error) => Some(error),
587 Self::Resolver(error) => Some(error),
588 }
589 }
590}
591
592impl<Resolver, State, Peer, Identity>
593 crate::server_component::StartupResolver<State, Peer, Identity>
594 for StartupResolverAdapter<'_, Resolver>
595where
596 Resolver: StartupRouteResolver<Peer>,
597{
598 type Route = ConnectTarget;
599 type Error = StartupResolutionError<Resolver::Error>;
600
601 fn defer_ready(&self) -> bool {
602 true
603 }
604
605 fn resolve<'a>(
606 &'a mut self,
607 startup: &'a crate::startup::StartupMessage,
608 context: &'a crate::ServerConnectionContext<Peer, Identity>,
609 _state: &'a mut State,
610 ) -> Pin<Box<dyn Future<Output = Result<Self::Route, Self::Error>> + 'a>> {
611 let parameters = StartupParameters::from_wire(startup);
612 let initial = context
613 .tls_if_known()
614 .map(|tls| InitialServerContext::new(context.peer(), tls));
615 let resolver = self.resolver;
616 Box::pin(async move {
617 let parameters = parameters.map_err(StartupResolutionError::Parameters)?;
618 let initial = initial.expect("startup routing runs after TLS negotiation");
619 resolver
620 .resolve(parameters, initial)
621 .await
622 .map_err(StartupResolutionError::Resolver)
623 })
624 }
625}
626
627pub enum IntermediaryAcceptError<
629 ServerError,
630 ResolverError,
631 RouteError,
632 ClientError,
633 RegistryError = std::convert::Infallible,
634 CancellationError = std::convert::Infallible,
635 MiddlewareError = std::convert::Infallible,
636> {
637 Server(ServerError),
639 StartupRoute(StartupResolutionError<ResolverError>),
641 CancellationRejected,
643 AuthenticatedRoute(RouteError),
645 Client(ClientError),
647 CancellationRegistry(RegistryError),
649 ServerOutput(io::Error),
651 Cancellation(CancellationError),
653 Middleware(MiddlewareError),
655}
656
657impl<S, R, A, C, K, X, M> fmt::Debug for IntermediaryAcceptError<S, R, A, C, K, X, M> {
658 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
659 formatter.write_str(match self {
660 Self::Server(_) => "IntermediaryAcceptError::Server([REDACTED])",
661 Self::StartupRoute(_) => "IntermediaryAcceptError::StartupRoute([REDACTED])",
662 Self::CancellationRejected => "IntermediaryAcceptError::CancellationRejected",
663 Self::AuthenticatedRoute(_) => {
664 "IntermediaryAcceptError::AuthenticatedRoute([REDACTED])"
665 }
666 Self::Client(_) => "IntermediaryAcceptError::Client([REDACTED])",
667 Self::CancellationRegistry(_) => {
668 "IntermediaryAcceptError::CancellationRegistry([REDACTED])"
669 }
670 Self::ServerOutput(_) => "IntermediaryAcceptError::ServerOutput([REDACTED])",
671 Self::Cancellation(_) => "IntermediaryAcceptError::Cancellation([REDACTED])",
672 Self::Middleware(_) => "IntermediaryAcceptError::Middleware([REDACTED])",
673 })
674 }
675}
676
677impl<S, R, A, C, K, X, M> fmt::Display for IntermediaryAcceptError<S, R, A, C, K, X, M> {
678 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
679 match self {
680 Self::Server(_) => formatter.write_str("client-facing establishment failed"),
681 Self::StartupRoute(_) => formatter.write_str("startup routing failed"),
682 Self::CancellationRejected => {
683 formatter.write_str("cancellation is explicitly rejected")
684 }
685 Self::AuthenticatedRoute(_) => formatter.write_str("authenticated routing failed"),
686 Self::Client(_) => formatter.write_str("PostgreSQL-facing establishment failed"),
687 Self::CancellationRegistry(_) => {
688 formatter.write_str("cancellation registration failed")
689 }
690 Self::ServerOutput(_) => {
691 formatter.write_str("client-facing establishment output failed")
692 }
693 Self::Cancellation(_) => formatter.write_str("cancellation forwarding failed"),
694 Self::Middleware(_) => {
695 formatter.write_str("forwarding middleware rejected establishment output")
696 }
697 }
698 }
699}
700
701impl<S, R, A, C, K, X, M> std::error::Error for IntermediaryAcceptError<S, R, A, C, K, X, M>
702where
703 S: std::error::Error + 'static,
704 R: std::error::Error + 'static,
705 A: std::error::Error + 'static,
706 C: std::error::Error + 'static,
707 K: std::error::Error + 'static,
708 X: std::error::Error + 'static,
709 M: std::error::Error + 'static,
710{
711 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
712 match self {
713 Self::Server(error) => Some(error),
714 Self::StartupRoute(error) => Some(error),
715 Self::CancellationRejected => None,
716 Self::AuthenticatedRoute(error) => Some(error),
717 Self::Client(error) => Some(error),
718 Self::CancellationRegistry(error) => Some(error),
719 Self::ServerOutput(error) => Some(error),
720 Self::Cancellation(error) => Some(error),
721 Self::Middleware(error) => Some(error),
722 }
723 }
724}
725
726#[derive(Debug)]
728pub struct IntermediaryContexts<ServerContext, ClientContext> {
729 server: ServerContext,
730 client: ClientContext,
731}
732
733impl<ServerContext, ClientContext> IntermediaryContexts<ServerContext, ClientContext> {
734 #[must_use]
736 pub const fn server(&self) -> &ServerContext {
737 &self.server
738 }
739 #[must_use]
741 pub const fn client(&self) -> &ClientContext {
742 &self.client
743 }
744}
745
746pub struct IntermediaryConnection<
748 DT,
749 UT,
750 State,
751 Peer,
752 ServerIdentity,
753 ClientEvidence,
754 ServerHandler,
755 ClientHandler,
756 Boundary,
757 Policy,
758 Cancellation = RejectCancellation,
759> {
760 downstream:
761 crate::server_component::ServerConnectionCore<DT, Peer, ServerIdentity, ServerHandler>,
762 upstream: crate::client_component::ClientConnectionCore<
763 crate::ClientTransport<UT>,
764 crate::Pristine,
765 ClientEvidence,
766 ClientHandler,
767 >,
768 state: State,
769 boundary: Boundary,
770 pipeline: Pipeline<Policy>,
771 target: ConnectTarget,
772 pending_frontend: Option<crate::codec::FrontendMessage>,
773 pending_local: VecDeque<PendingLocalResponses>,
774 cancellation_registry: Cancellation,
775 client_cancel_key: Option<crate::demux::CancelKey>,
776}
777
778struct PendingLocalResponses {
779 operation: crate::pipeline::OperationId,
780 messages: VecDeque<crate::codec::BackendMessage>,
781}
782
783#[derive(Debug)]
785pub enum IntermediaryAccept<Connection> {
786 Session(Connection),
788 CancellationForwarded,
790}
791
792impl<Connection> IntermediaryAccept<Connection> {
793 #[must_use]
798 pub fn into_session(self) -> Connection {
799 match self {
800 Self::Session(connection) => connection,
801 Self::CancellationForwarded => panic!("accepted cancellation has no session"),
802 }
803 }
804}
805
806#[derive(Debug)]
808pub enum ForwardedMessage {
809 Frontend(crate::codec::FrontendMessage),
811 Backend(crate::codec::BackendMessage),
813 FrontendSuppressed(crate::codec::FrontendMessage),
815 FrontendLocallyHandled(crate::codec::FrontendMessage),
817 BackendSuppressed(crate::codec::BackendMessage),
819}
820
821#[derive(Debug, Eq, PartialEq)]
823pub enum FrontendForwarding {
824 Forwarded(crate::codec::FrontendMessage),
826 Suppressed(crate::codec::FrontendMessage),
828 LocallyHandled(crate::codec::FrontendMessage),
830}
831
832impl FrontendForwarding {
833 #[must_use]
835 pub fn into_message(self) -> crate::codec::FrontendMessage {
836 match self {
837 Self::Forwarded(message)
838 | Self::Suppressed(message)
839 | Self::LocallyHandled(message) => message,
840 }
841 }
842}
843
844#[derive(Debug, Eq, PartialEq)]
846pub enum BackendForwarding {
847 Forwarded(crate::codec::BackendMessage),
849 Suppressed(crate::codec::BackendMessage),
851}
852
853impl BackendForwarding {
854 #[must_use]
856 pub fn into_message(self) -> crate::codec::BackendMessage {
857 match self {
858 Self::Forwarded(message) | Self::Suppressed(message) => message,
859 }
860 }
861}
862
863impl<DT, UT, State, Peer, SI, CE, SH, CH, Boundary, Policy, K>
864 IntermediaryConnection<DT, UT, State, Peer, SI, CE, SH, CH, Boundary, Policy, K>
865where
866 Policy: PipelinePolicy,
867{
868 #[must_use]
870 pub const fn target(&self) -> &ConnectTarget {
871 &self.target
872 }
873 #[must_use]
875 pub const fn state(&self) -> &State {
876 &self.state
877 }
878 #[must_use]
880 pub const fn cancellation_key(&self) -> Option<&crate::demux::CancelKey> {
881 self.client_cancel_key.as_ref()
882 }
883
884 pub fn detach_cancellation(&mut self) -> Option<CancellationRoute>
886 where
887 K: IntermediaryCancellationRegistry,
888 {
889 self.client_cancel_key
890 .take()
891 .and_then(|key| self.cancellation_registry.detach(&key))
892 }
893}
894
895impl<
896 DT,
897 UT,
898 State,
899 Peer,
900 ServerIdentity,
901 ClientEvidence,
902 ServerHandler,
903 ClientHandler,
904 Boundary,
905 Policy,
906 K,
907>
908 IntermediaryConnection<
909 DT,
910 UT,
911 State,
912 Peer,
913 ServerIdentity,
914 ClientEvidence,
915 ServerHandler,
916 ClientHandler,
917 Boundary,
918 Policy,
919 K,
920 >
921where
922 DT: AsyncRead + AsyncWrite + Unpin,
923 UT: AsyncRead + AsyncWrite + Unpin,
924 ServerHandler:
925 crate::ServerMiddleware<State, crate::ServerConnectionContext<Peer, ServerIdentity>>,
926 ClientHandler: crate::ClientMiddleware<State, crate::ClientConnectionContext<ClientEvidence>>,
927 Boundary: IntermediaryMiddleware<
928 State,
929 crate::ServerConnectionContext<Peer, ServerIdentity>,
930 crate::ClientConnectionContext<ClientEvidence>,
931 >,
932 Policy: PipelinePolicy,
933 K: IntermediaryCancellationRegistry,
934{
935 pub async fn forward_frontend(
942 &mut self,
943 ) -> Result<FrontendForwarding, ForwardError<Boundary::Error>> {
944 if let Some(message) = self.pending_frontend.take() {
945 self.process_frontend(message, false).await
946 } else {
947 let message = self.downstream.receive_wire_raw().await?;
948 self.process_frontend(message, true).await
949 }
950 }
951
952 async fn process_frontend(
953 &mut self,
954 message: crate::codec::FrontendMessage,
955 intercept_source_and_boundary: bool,
956 ) -> Result<FrontendForwarding, ForwardError<Boundary::Error>> {
957 let decision = if intercept_source_and_boundary {
958 let message = self.downstream.intercept_frontend(&mut self.state, message);
959 self.boundary
960 .frontend(
961 self.downstream.context(),
962 self.upstream.context(),
963 &mut self.state,
964 message,
965 )
966 .await
967 .map_err(ForwardError::Middleware)?
968 } else {
969 FrontendMiddlewareOutput::Forward(message)
970 };
971 let (message, handling) = match decision {
972 FrontendMiddlewareOutput::Forward(message) => {
973 let message = if intercept_source_and_boundary {
974 self.upstream.intercept_frontend(&mut self.state, message)
975 } else {
976 message
977 };
978 (message, FrontendHandling::Forward)
979 }
980 FrontendMiddlewareOutput::Suppress(message) => {
981 return Ok(FrontendForwarding::Suppressed(message));
982 }
983 FrontendMiddlewareOutput::Respond { request, responses } => {
984 let admission = self
985 .pipeline
986 .accept_frontend(request.clone(), FrontendHandling::Local)
987 .map_err(ForwardError::Frontend)?;
988 let FrontendAction::Discard { id } = admission.into_action() else {
989 unreachable!()
990 };
991 let messages = responses
992 .into_iter()
993 .map(|message| self.downstream.intercept_backend(&mut self.state, message))
994 .collect();
995 self.pending_local.push_back(PendingLocalResponses {
996 operation: id,
997 messages,
998 });
999 self.flush_local_responses().await?;
1000 return Ok(FrontendForwarding::LocallyHandled(request));
1001 }
1002 };
1003 let admission = match self.pipeline.accept_frontend(message.clone(), handling) {
1004 Ok(admission) => admission,
1005 Err(error) => {
1006 self.pending_frontend = Some(message);
1007 return Err(ForwardError::Frontend(error));
1008 }
1009 };
1010 let FrontendAction::Forward { message, .. } = admission.into_action() else {
1011 unreachable!()
1012 };
1013 self.upstream.send_wire_raw(message.clone()).await?;
1014 Ok(FrontendForwarding::Forwarded(message))
1015 }
1016
1017 pub async fn forward_backend(
1029 &mut self,
1030 ) -> Result<BackendForwarding, ForwardError<Boundary::Error>> {
1031 let message = self.upstream.receive_wire_raw().await?;
1032 self.process_backend(message).await
1033 }
1034
1035 async fn process_backend(
1036 &mut self,
1037 message: crate::codec::BackendMessage,
1038 ) -> Result<BackendForwarding, ForwardError<Boundary::Error>> {
1039 let message = self.upstream.intercept_backend(&mut self.state, message);
1040 let decision = self
1041 .boundary
1042 .backend(
1043 self.downstream.context(),
1044 self.upstream.context(),
1045 &mut self.state,
1046 message,
1047 )
1048 .await
1049 .map_err(ForwardError::Middleware)?;
1050 let (message, suppress) = match decision {
1051 BackendMiddlewareOutput::Forward(message) => (
1052 self.downstream.intercept_backend(&mut self.state, message),
1053 false,
1054 ),
1055 BackendMiddlewareOutput::Suppress(message) => (message, true),
1056 };
1057 let message = match self
1058 .pipeline
1059 .accept_backend(message)
1060 .map_err(ForwardError::Backend)?
1061 {
1062 BackendAction::Emit(message) => message,
1063 BackendAction::Deferred(message) => return Err(ForwardError::Deferred(message)),
1064 };
1065 if suppress {
1066 self.flush_local_responses().await?;
1067 Ok(BackendForwarding::Suppressed(message))
1068 } else {
1069 self.downstream.send_wire_raw(message.clone()).await?;
1070 self.flush_local_responses().await?;
1071 Ok(BackendForwarding::Forwarded(message))
1072 }
1073 }
1074
1075 async fn flush_local_responses(&mut self) -> Result<(), ForwardError<Boundary::Error>> {
1076 loop {
1077 let Some(pending) = self.pending_local.front_mut() else {
1078 return Ok(());
1079 };
1080 let Some(message) = pending.messages.pop_front() else {
1081 self.pending_local.pop_front();
1082 continue;
1083 };
1084 match self.pipeline.try_emit_local(pending.operation, message) {
1085 Ok(BackendAction::Emit(message)) => {
1086 self.downstream.send_wire_raw(message).await?;
1087 }
1088 Ok(BackendAction::Deferred(message)) => {
1089 pending.messages.push_front(message);
1090 return Ok(());
1091 }
1092 Err(error) => return Err(ForwardError::Backend(error)),
1093 }
1094 }
1095 }
1096
1097 pub async fn forward_next(
1108 &mut self,
1109 ) -> Result<ForwardedMessage, ForwardError<Boundary::Error>> {
1110 if self.pending_frontend.is_some() {
1111 let message = self.upstream.receive_wire_raw().await?;
1112 return self
1113 .process_backend(message)
1114 .await
1115 .map(|outcome| match outcome {
1116 BackendForwarding::Forwarded(message) => ForwardedMessage::Backend(message),
1117 BackendForwarding::Suppressed(message) => {
1118 ForwardedMessage::BackendSuppressed(message)
1119 }
1120 });
1121 }
1122 tokio::select! {
1123 result = self.downstream.receive_wire_raw() => {
1124 let message = result?;
1125 self.process_frontend(message, true).await.map(|outcome| match outcome {
1126 FrontendForwarding::Forwarded(message) => ForwardedMessage::Frontend(message),
1127 FrontendForwarding::Suppressed(message) => ForwardedMessage::FrontendSuppressed(message),
1128 FrontendForwarding::LocallyHandled(message) => ForwardedMessage::FrontendLocallyHandled(message),
1129 })
1130 }
1131 result = self.upstream.receive_wire_raw() => {
1132 let message = result?;
1133 self.process_backend(message).await.map(|outcome| match outcome {
1134 BackendForwarding::Forwarded(message) => ForwardedMessage::Backend(message),
1135 BackendForwarding::Suppressed(message) => ForwardedMessage::BackendSuppressed(message),
1136 })
1137 }
1138 }
1139 }
1140
1141 #[allow(clippy::type_complexity)]
1144 pub fn teardown(
1145 mut self,
1146 ) -> (
1147 crate::AcceptedServerTransport<DT>,
1148 crate::ClientTransport<UT>,
1149 State,
1150 Boundary,
1151 (ServerHandler, ClientHandler),
1152 IntermediaryContexts<
1153 crate::ServerConnectionContext<Peer, ServerIdentity>,
1154 crate::ClientConnectionContext<ClientEvidence>,
1155 >,
1156 ) {
1157 let _ = self.detach_cancellation();
1158 let (downstream, server_handler, server_context) = self.downstream.into_parts();
1159 let (upstream, client_handler, client_context) = self.upstream.into_parts();
1160 (
1161 downstream,
1162 upstream,
1163 self.state,
1164 self.boundary,
1165 (server_handler, client_handler),
1166 IntermediaryContexts {
1167 server: server_context,
1168 client: client_context,
1169 },
1170 )
1171 }
1172}
1173
1174#[derive(Debug)]
1176pub enum ForwardError<MiddlewareError = std::convert::Infallible> {
1177 Io(io::Error),
1179 Frontend(crate::pipeline::FrontendProjectionError),
1181 Backend(crate::pipeline::BackendProjectionError),
1183 Deferred(crate::codec::BackendMessage),
1185 Middleware(MiddlewareError),
1187}
1188
1189impl<E> fmt::Display for ForwardError<E> {
1190 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1191 match self {
1192 Self::Io(error) => error.fmt(formatter),
1193 Self::Frontend(_) => {
1194 formatter.write_str("frontend message violates pipeline legality or capacity")
1195 }
1196 Self::Backend(_) => formatter.write_str("backend message violates pipeline legality"),
1197 Self::Deferred(_) => formatter.write_str("backend response is not yet emittable"),
1198 Self::Middleware(_) => formatter.write_str("forwarding middleware rejected a message"),
1199 }
1200 }
1201}
1202
1203impl<E> std::error::Error for ForwardError<E>
1204where
1205 E: std::error::Error + 'static,
1206{
1207 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
1208 match self {
1209 Self::Io(error) => Some(error),
1210 Self::Middleware(error) => Some(error),
1211 Self::Frontend(_) | Self::Backend(_) | Self::Deferred(_) => None,
1212 }
1213 }
1214}
1215
1216impl<E> From<io::Error> for ForwardError<E> {
1217 fn from(error: io::Error) -> Self {
1218 Self::Io(error)
1219 }
1220}
1221
1222impl<ST, SA, SM, Connector, CT, CA, CM, Resolver, Route, Policy, Boundary, K>
1223 Intermediary<
1224 crate::Server<ST, SA, SM>,
1225 crate::Client<Connector, CT, CA, CM>,
1226 Resolver,
1227 Route,
1228 Policy,
1229 Boundary,
1230 K,
1231 >
1232where
1233 ST: crate::ServerTlsConfiguration,
1234 SA: crate::ServerAuthenticationProvider,
1235 CT: crate::client_component::ClientTlsConfiguration,
1236 CA: crate::ClientAuthentication,
1237 CM: crate::MiddlewareFactory<crate::ClientInitialContext>,
1238 Policy: PipelinePolicy,
1239 K: IntermediaryCancellationRegistry + Clone,
1240{
1241 #[allow(clippy::type_complexity, clippy::too_many_lines)]
1248 pub async fn accept<DT, State, Peer, CW, UT, CE>(
1249 &self,
1250 transport: DT,
1251 peer: Peer,
1252 state: State,
1253 ) -> Result<
1254 IntermediaryAccept<
1255 IntermediaryConnection<
1256 DT,
1257 UT,
1258 State,
1259 Peer,
1260 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1261 CA::Evidence,
1262 <SM as crate::MiddlewareFactory<
1263 crate::ServerConnectionContext<
1264 Peer,
1265 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1266 >,
1267 >>::Handler,
1268 <CM as crate::MiddlewareFactory<crate::ClientInitialContext>>::Handler,
1269 <Boundary as IntermediaryMiddlewareFactory<
1270 crate::ServerConnectionContext<
1271 Peer,
1272 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1273 >,
1274 crate::ClientConnectionContext<CA::Evidence>,
1275 >>::Handler,
1276 Policy,
1277 K,
1278 >,
1279 >,
1280 IntermediaryAcceptError<
1281 crate::AcceptError<
1282 <ST::Provider as crate::ServerIdentityProvider>::Error,
1283 <SA::Authentication as crate::ServerAuthentication<Peer>>::Error,
1284 >,
1285 Resolver::Error,
1286 Route::Error,
1287 crate::ConnectError<
1288 CE,
1289 crate::ClientTlsError<<CT::Provider as crate::ClientTlsProvider>::Error>,
1290 crate::ClientAuthenticationError<CA::Error>,
1291 >,
1292 K::Error,
1293 crate::CancelError<CE>,
1294 <<Boundary as IntermediaryMiddlewareFactory<
1295 crate::ServerConnectionContext<
1296 Peer,
1297 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1298 >,
1299 crate::ClientConnectionContext<CA::Evidence>,
1300 >>::Handler as IntermediaryMiddleware<
1301 State,
1302 crate::ServerConnectionContext<
1303 Peer,
1304 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1305 >,
1306 crate::ClientConnectionContext<CA::Evidence>,
1307 >>::Error,
1308 >,
1309 >
1310 where
1311 DT: AsyncRead + AsyncWrite + Unpin,
1312 UT: AsyncRead + AsyncWrite + Unpin,
1313 SA::Authentication: crate::ServerAuthentication<Peer>,
1314 SM: crate::MiddlewareFactory<
1315 crate::ServerConnectionContext<
1316 Peer,
1317 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1318 >,
1319 >,
1320 <SM as crate::MiddlewareFactory<
1321 crate::ServerConnectionContext<
1322 Peer,
1323 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1324 >,
1325 >>::Handler: crate::ServerMiddleware<
1326 State,
1327 crate::ServerConnectionContext<
1328 Peer,
1329 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1330 >,
1331 >,
1332 Resolver: StartupRouteResolver<Peer>,
1333 Connector: Fn(&ConnectTarget) -> CW,
1334 CW: Future<Output = Result<UT, CE>>,
1335 <CM as crate::MiddlewareFactory<crate::ClientInitialContext>>::Handler:
1336 crate::ClientMiddleware<State, crate::ClientConnectionContext<CA::Evidence>>,
1337 Route: AuthenticatedRoutePolicy<
1338 Peer,
1339 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1340 >,
1341 Boundary: IntermediaryMiddlewareFactory<
1342 crate::ServerConnectionContext<
1343 Peer,
1344 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1345 >,
1346 crate::ClientConnectionContext<CA::Evidence>,
1347 >,
1348 <Boundary as IntermediaryMiddlewareFactory<
1349 crate::ServerConnectionContext<
1350 Peer,
1351 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1352 >,
1353 crate::ClientConnectionContext<CA::Evidence>,
1354 >>::Handler: IntermediaryMiddleware<
1355 State,
1356 crate::ServerConnectionContext<
1357 Peer,
1358 <SA::Authentication as crate::ServerAuthentication<Peer>>::Identity,
1359 >,
1360 crate::ClientConnectionContext<CA::Evidence>,
1361 >,
1362 {
1363 let mut resolver = StartupResolverAdapter {
1364 resolver: &self.resolver,
1365 };
1366 let (accepted, selected) = self
1367 .server
1368 .accept_routed(transport, peer, state, &mut resolver)
1369 .await
1370 .map_err(|error| match error {
1371 crate::server_component::RoutedAcceptError::Accept(error) => {
1372 IntermediaryAcceptError::Server(error)
1373 }
1374 crate::server_component::RoutedAcceptError::Route(error) => {
1375 IntermediaryAcceptError::StartupRoute(error)
1376 }
1377 })?;
1378 let mut downstream = match accepted {
1379 crate::ServerAccept::Session(downstream) => downstream,
1380 crate::ServerAccept::Cancellation(cancellation) => {
1381 if self.cancellation == CancellationPolicy::Reject {
1382 let _ = cancellation.teardown();
1383 return Err(IntermediaryAcceptError::CancellationRejected);
1384 }
1385 let request = cancellation.request();
1386 let client_key = crate::demux::CancelKey {
1387 process_id: request.process_id(),
1388 secret_key: bytes::Bytes::copy_from_slice(request.secret_key()),
1389 };
1390 let Some(route) = self.cancellation_registry.resolve(&client_key) else {
1391 let _ = cancellation.teardown();
1392 return Err(IntermediaryAcceptError::CancellationRejected);
1393 };
1394 if let Err(error) = self
1395 .client
1396 .cancel(route.target(), route.upstream_key())
1397 .await
1398 {
1399 let _ = cancellation.teardown();
1400 return Err(IntermediaryAcceptError::Cancellation(error));
1401 }
1402 let _ = cancellation.teardown();
1403 return Ok(IntermediaryAccept::CancellationForwarded);
1404 }
1405 };
1406 let startup = match StartupParameters::from_wire(downstream.startup()) {
1407 Ok(startup) => startup,
1408 Err(error) => {
1409 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1410 let _ = downstream
1411 .send_generated_error(safe_establishment_diagnostic())
1412 .await;
1413 }
1414 let _ = downstream.teardown();
1415 return Err(IntermediaryAcceptError::StartupRoute(
1416 StartupResolutionError::Parameters(error),
1417 ));
1418 }
1419 };
1420 let context = AuthenticatedRouteContext {
1421 peer: downstream.context().peer(),
1422 identity: downstream.context().identity(),
1423 };
1424 let Some(selected) = selected else {
1425 let _ = downstream.teardown();
1426 return Err(IntermediaryAcceptError::CancellationRejected);
1427 };
1428 let selected = match self.route.route(selected, context).await {
1429 Ok(target) => target,
1430 Err(error) => {
1431 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1432 let _ = downstream
1433 .send_generated_error(safe_establishment_diagnostic())
1434 .await;
1435 }
1436 let _ = downstream.teardown();
1437 return Err(IntermediaryAcceptError::AuthenticatedRoute(error));
1438 }
1439 };
1440 let (mut downstream, mut state) = downstream.into_core_and_state();
1441 let upstream = match self
1442 .client
1443 .connect_core(selected.clone(), startup, &mut state)
1444 .await
1445 {
1446 Ok(upstream) => upstream,
1447 Err(error) => {
1448 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1449 let diagnostic = safe_establishment_diagnostic();
1450 let diagnostic = downstream.intercept_backend(&mut state, diagnostic);
1451 if matches!(diagnostic, crate::codec::BackendMessage::ErrorResponse(_)) {
1452 let _ = downstream.send_wire_raw(diagnostic).await;
1455 }
1456 }
1457 let _ = downstream.into_parts();
1458 return Err(IntermediaryAcceptError::Client(error));
1459 }
1460 };
1461 let boundary = self
1462 .boundary
1463 .create(downstream.context(), upstream.context());
1464 let (client_cancel_key, backend_key_message) =
1465 match (self.cancellation, upstream.context().backend_key().cloned()) {
1466 (CancellationPolicy::Forward, Some(upstream_key)) => {
1467 let client_key = match self
1468 .cancellation_registry
1469 .register(CancellationRoute::new(selected.clone(), upstream_key))
1470 {
1471 Ok(key) => key,
1472 Err(error) => {
1473 if self.failure_policy == EstablishmentFailurePolicy::SafeDiagnostic {
1474 let diagnostic = downstream
1475 .intercept_backend(&mut state, safe_establishment_diagnostic());
1476 if matches!(
1477 diagnostic,
1478 crate::codec::BackendMessage::ErrorResponse(_)
1479 ) {
1480 let _ = downstream.send_wire_raw(diagnostic).await;
1481 }
1482 }
1483 let _ = downstream.into_parts();
1484 let _ = upstream.into_parts();
1485 return Err(IntermediaryAcceptError::CancellationRegistry(error));
1486 }
1487 };
1488 let message = crate::codec::BackendMessage::BackendKeyData {
1489 process_id: client_key.process_id,
1490 secret_key: client_key.secret_key.clone(),
1491 };
1492 (Some(client_key), Some(message))
1493 }
1494 _ => (None, None),
1495 };
1496 let mut connection = IntermediaryConnection {
1497 downstream,
1498 upstream,
1499 state,
1500 boundary,
1501 pipeline: Pipeline::new(self.pipeline),
1502 target: selected,
1503 pending_frontend: None,
1504 pending_local: VecDeque::new(),
1505 cancellation_registry: self.cancellation_registry.clone(),
1506 client_cancel_key,
1507 };
1508 if let Some(message) = backend_key_message {
1509 let expected = message.clone();
1510 let message = connection
1511 .boundary
1512 .backend(
1513 connection.downstream.context(),
1514 connection.upstream.context(),
1515 &mut connection.state,
1516 message,
1517 )
1518 .await;
1519 let message = match message {
1520 Ok(BackendMiddlewareOutput::Forward(message)) => message,
1521 Ok(BackendMiddlewareOutput::Suppress(_)) => {
1522 let _ = connection.detach_cancellation();
1523 let _ = connection.teardown();
1524 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1525 io::ErrorKind::InvalidData,
1526 "middleware suppressed generated cancellation key",
1527 )));
1528 }
1529 Err(error) => {
1530 let _ = connection.detach_cancellation();
1531 let _ = connection.teardown();
1532 return Err(IntermediaryAcceptError::Middleware(error));
1533 }
1534 };
1535 let message = connection
1536 .downstream
1537 .intercept_backend(&mut connection.state, message);
1538 if message != expected {
1539 let _ = connection.detach_cancellation();
1540 let _ = connection.teardown();
1541 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1542 io::ErrorKind::InvalidData,
1543 "middleware rejected generated cancellation key",
1544 )));
1545 }
1546 if let Err(error) = connection.downstream.send_wire_raw(message).await {
1547 let _ = connection.detach_cancellation();
1548 let _ = connection.teardown();
1549 return Err(IntermediaryAcceptError::ServerOutput(error));
1550 }
1551 }
1552 let ready = connection.downstream.intercept_backend(
1553 &mut connection.state,
1554 crate::codec::BackendMessage::ReadyForQuery(crate::codec::TransactionStatus::Idle),
1555 );
1556 if !matches!(ready, crate::codec::BackendMessage::ReadyForQuery(_)) {
1557 let _ = connection.detach_cancellation();
1558 let _ = connection.teardown();
1559 return Err(IntermediaryAcceptError::ServerOutput(io::Error::new(
1560 io::ErrorKind::InvalidData,
1561 "middleware rejected generated readiness",
1562 )));
1563 }
1564 if let Err(error) = connection.downstream.send_wire_raw(ready).await {
1565 let _ = connection.detach_cancellation();
1566 let _ = connection.teardown();
1567 return Err(IntermediaryAcceptError::ServerOutput(error));
1568 }
1569 Ok(IntermediaryAccept::Session(connection))
1570 }
1571}