Serve a TLS connection with an optional mTLS peer identity.
(
&self,
stream: S,
peer_identity: Option<Identity>,
)
| 145 | |
| 146 | /// Serve a TLS connection with an optional mTLS peer identity. |
| 147 | pub async fn serve_with_peer_identity<S>( |
| 148 | &self, |
| 149 | stream: S, |
| 150 | peer_identity: Option<Identity>, |
| 151 | ) -> Result<(), Box<dyn std::error::Error + Send + Sync>> |
| 152 | where |
| 153 | S: AsyncRead + AsyncWrite + Unpin + Send + 'static, |
| 154 | { |
| 155 | let openshell = OpenShellServer::new(OpenShellService::new(self.state.clone())) |
| 156 | .max_decoding_message_size(MAX_GRPC_DECODE_SIZE); |
| 157 | let inference = InferenceServer::new(InferenceService::new(self.state.clone())) |
| 158 | .max_decoding_message_size(MAX_GRPC_DECODE_SIZE); |
| 159 | let authz_policy = self.state.config.oidc.as_ref().map(|oidc| AuthzPolicy { |
| 160 | admin_role: oidc.admin_role.clone(), |
| 161 | user_role: oidc.user_role.clone(), |
| 162 | scopes_enabled: !oidc.scopes_claim.is_empty(), |
| 163 | }); |
| 164 | let authenticator_chain = build_authenticator_chain(&self.state); |
| 165 | let grpc_service = AuthGrpcRouter::with_peer_identity( |
| 166 | GrpcRouter::new(openshell, inference), |
| 167 | authenticator_chain, |
| 168 | authz_policy, |
| 169 | self.state |
| 170 | .config |
| 171 | .mtls_auth |
| 172 | .enabled |
| 173 | .then_some(peer_identity) |
| 174 | .flatten(), |
| 175 | self.state.config.mtls_auth.enabled, |
| 176 | self.state.config.auth.allow_unauthenticated_users, |
| 177 | ); |
| 178 | let grpc_service = |
| 179 | GrpcRateLimitService::new(grpc_service, self.state.grpc_rate_limiter.clone()); |
| 180 | let http_service = http_router(self.state.clone()); |
| 181 | |
| 182 | let grpc_service = request_id_middleware!(grpc_service); |
| 183 | let http_service = request_id_middleware!(http_service); |
| 184 | |
| 185 | let service = MultiplexedService::new(grpc_service, http_service); |
| 186 | |
| 187 | let mut builder = Builder::new(TokioExecutor::new()); |
| 188 | // Server-side HTTP/2 keepalive: supervisors hold long-lived sessions, and without |
| 189 | // it the gateway never PINGs them, so idle/half-dead connections linger and orphan |
| 190 | // in-flight relay execs. The timer is required — hyper panics on the keepalive |
| 191 | // interval without one. |
| 192 | builder |
| 193 | .http2() |
| 194 | .timer(TokioTimer::new()) |
| 195 | .adaptive_window(true) |
| 196 | .keep_alive_interval(Some(Duration::from_secs(20))) |
| 197 | .keep_alive_timeout(Duration::from_secs(10)); |
| 198 | |
| 199 | builder |
| 200 | .serve_connection_with_upgrades(TokioIo::new(stream), service) |
| 201 | .await?; |
| 202 | |
| 203 | Ok(()) |
| 204 | } |
no test coverage detected