Skip to main content

hyperlane_core/server/
impl.rs

1use super::*;
2
3/// Provides a default implementation for Server.
4impl Default for Server {
5    /// Creates a new Server instance with default values.
6    ///
7    /// # Returns
8    ///
9    /// - `Self` - A new instance with default configuration.
10    #[inline(always)]
11    fn default() -> Self {
12        Self {
13            server_config: ServerConfig::default(),
14            request_config: RequestConfig::default(),
15            task_panic: Vec::new(),
16            request_error: Vec::new(),
17            route_matcher: RouteMatcher::new(),
18            request_middleware: Vec::new(),
19            response_middleware: Vec::new(),
20        }
21    }
22}
23
24/// Implements the `PartialEq` trait for `Server`.
25///
26/// This allows for comparing two `Server` instances for equality.
27impl PartialEq for Server {
28    /// Checks if two `Server` instances are equal.
29    ///
30    /// # Arguments
31    ///
32    /// - `&Self` - The other `Server` instance to compare against.
33    ///
34    /// # Returns
35    ///
36    /// - `bool` - `true` if the instances are equal, `false` otherwise.
37    #[inline]
38    fn eq(&self, other: &Self) -> bool {
39        self.get_server_config() == other.get_server_config()
40            && self.get_request_config() == other.get_request_config()
41            && self.get_route_matcher() == other.get_route_matcher()
42            && self.get_task_panic().len() == other.get_task_panic().len()
43            && self.get_request_error().len() == other.get_request_error().len()
44            && self.get_request_middleware().len() == other.get_request_middleware().len()
45            && self.get_response_middleware().len() == other.get_response_middleware().len()
46            && self
47                .get_task_panic()
48                .iter()
49                .zip(other.get_task_panic().iter())
50                .all(|pair: (&ServerHookHandler, &ServerHookHandler)| Arc::ptr_eq(pair.0, pair.1))
51            && self
52                .get_request_error()
53                .iter()
54                .zip(other.get_request_error().iter())
55                .all(|pair: (&ServerHookHandler, &ServerHookHandler)| Arc::ptr_eq(pair.0, pair.1))
56            && self
57                .get_request_middleware()
58                .iter()
59                .zip(other.get_request_middleware().iter())
60                .all(|pair: (&ServerHookHandler, &ServerHookHandler)| Arc::ptr_eq(pair.0, pair.1))
61            && self
62                .get_response_middleware()
63                .iter()
64                .zip(other.get_response_middleware().iter())
65                .all(|pair: (&ServerHookHandler, &ServerHookHandler)| Arc::ptr_eq(pair.0, pair.1))
66    }
67}
68
69/// Implements the `Eq` trait for `Server`.
70///
71/// This indicates that `Server` has a total equality relation.
72impl Eq for Server {}
73
74/// Implementation of `From` trait for converting `usize` address into `Server`.
75impl From<usize> for Server {
76    /// Converts a memory address into an owned `Server` by cloning from the reference.
77    ///
78    /// # Arguments
79    ///
80    /// - `usize` - The memory address of the `Server` instance.
81    ///
82    /// # Returns
83    ///
84    /// - `Server` - A cloned `Server` instance from the given address.
85    #[inline(always)]
86    fn from(address: usize) -> Self {
87        let server: &Server = address.into();
88        server.clone()
89    }
90}
91
92/// Implementation of `From` trait for converting `usize` address into `&Server`.
93impl From<usize> for &'static Server {
94    /// Converts a memory address into a reference to `Server`.
95    ///
96    /// # Arguments
97    ///
98    /// - `usize` - The memory address of the `Server` instance.
99    ///
100    /// # Returns
101    ///
102    /// - `&'static Server` - A reference to the `Server` at the given address.
103    ///
104    /// # Safety
105    ///
106    /// - The address is guaranteed to be a valid `Server` instance
107    ///   that was previously converted from a reference and is managed by the runtime.
108    #[inline(always)]
109    fn from(address: usize) -> &'static Server {
110        unsafe { &*(address as *const Server) }
111    }
112}
113
114/// Implementation of `From` trait for converting `usize` address into `&mut Server`.
115impl From<usize> for &'static mut Server {
116    /// Converts a memory address into a mutable reference to `Server`.
117    ///
118    /// # Arguments
119    ///
120    /// - `usize` - The memory address of the `Server` instance.
121    ///
122    /// # Returns
123    ///
124    /// - `&'static mut Server` - A mutable reference to the `Server` at the given address.
125    ///
126    /// # Safety
127    ///
128    /// - The address is guaranteed to be a valid `Server` instance
129    ///   that was previously converted from a reference and is managed by the runtime.
130    #[inline(always)]
131    fn from(address: usize) -> &'static mut Server {
132        unsafe { &mut *(address as *mut Server) }
133    }
134}
135
136/// Implementation of `From` trait for converting `&Server` into `usize` address.
137impl From<&Server> for usize {
138    /// Converts a reference to `Server` into its memory address.
139    ///
140    /// # Arguments
141    ///
142    /// - `&Server` - The reference to the `Server` instance.
143    ///
144    /// # Returns
145    ///
146    /// - `usize` - The memory address of the `Server` instance.
147    #[inline(always)]
148    fn from(server: &Server) -> Self {
149        server as *const Server as usize
150    }
151}
152
153/// Implementation of `From` trait for converting `&mut Server` into `usize` address.
154impl From<&mut Server> for usize {
155    /// Converts a mutable reference to `Server` into its memory address.
156    ///
157    /// # Arguments
158    ///
159    /// - `&mut Server` - The mutable reference to the `Server` instance.
160    ///
161    /// # Returns
162    ///
163    /// - `usize` - The memory address of the `Server` instance.
164    #[inline(always)]
165    fn from(server: &mut Server) -> Self {
166        server as *mut Server as usize
167    }
168}
169
170/// Implementation of `AsRef` trait for `Server`.
171impl AsRef<Server> for Server {
172    /// Converts `&Server` to `&Server` via memory address conversion.
173    ///
174    /// # Returns
175    ///
176    /// - `&Self` - A reference to the `Server` instance.
177    #[inline(always)]
178    fn as_ref(&self) -> &Self {
179        let address: usize = self.into();
180        address.into()
181    }
182}
183
184/// Implementation of `AsMut` trait for `Server`.
185impl AsMut<Server> for Server {
186    /// Converts `&mut Server` to `&mut Server` via memory address conversion.
187    ///
188    /// # Returns
189    ///
190    /// - `&mut Self` - A mutable reference to the `Server` instance.
191    #[inline(always)]
192    fn as_mut(&mut self) -> &mut Self {
193        let address: usize = self.into();
194        address.into()
195    }
196}
197
198/// Converts a `ServerConfig` into a `Server` instance.
199///
200/// This allows creating a `Server` directly from its configuration,
201/// using default values for other fields.
202impl From<ServerConfig> for Server {
203    /// Creates a new `Server` instance from the given `ServerConfig`.
204    ///
205    /// # Arguments
206    ///
207    /// - `ServerConfig` - The server configuration to use.
208    ///
209    /// # Returns
210    ///
211    /// - `Self` - A new `Server` instance with the provided configuration.
212    #[inline(always)]
213    fn from(server_config: ServerConfig) -> Self {
214        Self {
215            server_config,
216            ..Default::default()
217        }
218    }
219}
220
221/// Converts a `RequestConfig` into a `Server` instance.
222///
223/// This allows creating a `Server` directly from its request configuration,
224/// using default values for other fields.
225impl From<RequestConfig> for Server {
226    /// Creates a new `Server` instance from the given `RequestConfig`.
227    ///
228    /// # Arguments
229    ///
230    /// - `RequestConfig` - The request configuration to use.
231    ///
232    /// # Returns
233    ///
234    /// - `Self` - A new `Server` instance with the provided request configuration.
235    #[inline(always)]
236    fn from(request_config: RequestConfig) -> Self {
237        Self {
238            request_config,
239            ..Default::default()
240        }
241    }
242}
243
244/// Implementation of `Lifetime` trait for `Server`.
245impl Lifetime for Server {
246    /// Converts a reference to the server into a `'static` reference.
247    ///
248    /// # Returns
249    ///
250    /// - `&'static Self` - A reference to the server with a `'static` lifetime.
251    ///
252    /// # Safety
253    ///
254    /// - The address is guaranteed to be a valid `Server` instance
255    ///   that was previously converted from a reference and is managed by the runtime.
256    #[inline(always)]
257    unsafe fn leak(&self) -> &'static Self {
258        let address: usize = self.into();
259        address.into()
260    }
261
262    /// Converts a reference to the server into a `'static` mutable reference.
263    ///
264    /// # Returns
265    ///
266    /// - `&'static mut Self` - A mutable reference to the server with a `'static` lifetime.
267    ///
268    /// # Safety
269    ///
270    /// - The address is guaranteed to be a valid `Server` instance
271    ///   that was previously converted from a reference and is managed by the runtime.
272    #[inline(always)]
273    unsafe fn leak_mut(&self) -> &'static mut Self {
274        let address: usize = self.into();
275        address.into()
276    }
277}
278
279/// Represents the server, providing methods to configure and run it.
280///
281/// This struct wraps the `Server` configuration and routing logic,
282/// offering a high-level API for setting up the HTTP and WebSocket server.
283impl Server {
284    /// Registers a hook into the server's processing pipeline.
285    ///
286    /// This function dispatches the provided `HookType` to the appropriate
287    /// internal hook collection based on its variant. The hook will be executed
288    /// at the corresponding stage of request processing according to its type:
289    /// - `Panic` - Added to panic handlers for error recovery
290    /// - `RequestError` - Added to request error handlers
291    /// - `RequestMiddleware` - Added to pre-route middleware chain
292    /// - `Route` - Registered as a route handler for the specified path
293    /// - `ResponseMiddleware` - Added to post-route middleware chain
294    ///
295    /// # Arguments
296    ///
297    /// - `HookType` - The `HookType` instance containing the hook configuration and factory.
298    #[inline]
299    pub fn handle_hook(&mut self, hook: HookType) {
300        match hook {
301            HookType::TaskPanic(_, hook) => {
302                self.get_mut_task_panic().push(hook());
303            }
304            HookType::RequestError(_, hook) => {
305                self.get_mut_request_error().push(hook());
306            }
307            HookType::RequestMiddleware(_, hook) => {
308                self.get_mut_request_middleware().push(hook());
309            }
310            HookType::Route(path, hook) => {
311                self.get_mut_route_matcher().add(path, hook()).unwrap();
312            }
313            HookType::ResponseMiddleware(_, hook) => {
314                self.get_mut_response_middleware().push(hook());
315            }
316        };
317    }
318
319    /// Sets the server configuration from a JSON string.
320    ///
321    /// # Arguments
322    ///
323    /// - `C` - The configuration.
324    ///
325    /// # Returns
326    ///
327    /// - `&mut Self` - Reference to self for method chaining.
328    #[inline]
329    pub fn config_from_json<C>(&mut self, json: C) -> &mut Self
330    where
331        C: AsRef<str>,
332    {
333        let config: ServerConfig = serde_json::from_str(json.as_ref()).unwrap();
334        self.set_server_config(config);
335        self
336    }
337
338    /// Sets the server configuration.
339    ///
340    /// # Arguments
341    ///
342    /// - `ServerConfig` - The server configuration.
343    ///
344    /// # Returns
345    ///
346    /// - `&mut Self` - Reference to self for method chaining.
347    #[inline(always)]
348    pub fn server_config(&mut self, config: ServerConfig) -> &mut Self {
349        self.set_server_config(config);
350        self
351    }
352
353    /// Sets the HTTP request config.
354    ///
355    /// # Arguments
356    ///
357    /// - `RequestConfig` - The HTTP request config to set.
358    ///
359    /// # Returns
360    ///
361    /// - `&mut Self` - Reference to self for method chaining.
362    #[inline(always)]
363    pub fn request_config(&mut self, config: RequestConfig) -> &mut Self {
364        self.set_request_config(config);
365        self
366    }
367
368    /// Registers a task panic handler to the processing pipeline.
369    ///
370    /// This method allows registering task panic handlers that implement the `ServerHook` trait,
371    /// which will be executed when a panic occurs during request processing.
372    ///
373    /// # Returns
374    ///
375    /// - `&mut Self` - Reference to self for method chaining.
376    #[inline(always)]
377    pub fn task_panic<S>(&mut self) -> &mut Self
378    where
379        S: ServerHook,
380    {
381        self.get_mut_task_panic().push(Hook::factory::<S>());
382        self
383    }
384
385    /// Registers a request error handler to the processing pipeline.
386    ///
387    /// This method allows registering request error handlers that implement the `ServerHook` trait,
388    /// which will be executed when a request error occurs during HTTP request processing.
389    ///
390    /// # Returns
391    ///
392    /// - `&mut Self` - Reference to self for method chaining.
393    #[inline(always)]
394    pub fn request_error<S>(&mut self) -> &mut Self
395    where
396        S: ServerHook,
397    {
398        self.get_mut_request_error().push(Hook::factory::<S>());
399        self
400    }
401
402    /// Registers a route hook for a specific path.
403    ///
404    /// This method allows registering route handlers that implement the `ServerHook` trait,
405    /// providing type safety and better code organization.
406    ///
407    /// # Arguments
408    ///
409    /// - `impl AsRef<str>` - The route path pattern.
410    ///
411    /// # Returns
412    ///
413    /// - `&mut Self` - Reference to self for method chaining.
414    #[inline(always)]
415    pub fn route<S>(&mut self, path: impl AsRef<str>) -> &mut Self
416    where
417        S: ServerHook,
418    {
419        self.get_mut_route_matcher()
420            .add(path.as_ref(), Hook::factory::<S>())
421            .unwrap();
422        self
423    }
424
425    /// Registers request middleware to the processing pipeline.
426    ///
427    /// This method allows registering middleware that implements the `ServerHook` trait,
428    /// which will be executed before route handlers for every incoming request.
429    ///
430    /// # Returns
431    ///
432    /// - `&mut Self` - Reference to self for method chaining.
433    #[inline(always)]
434    pub fn request_middleware<S>(&mut self) -> &mut Self
435    where
436        S: ServerHook,
437    {
438        self.get_mut_request_middleware().push(Hook::factory::<S>());
439        self
440    }
441
442    /// Registers response middleware to the processing pipeline.
443    ///
444    /// This method allows registering middleware that implements the `ServerHook` trait,
445    /// which will be executed after route handlers for every outgoing response.
446    ///
447    /// # Returns
448    ///
449    /// - `&mut Self` - Reference to self for method chaining.
450    #[inline(always)]
451    pub fn response_middleware<S>(&mut self) -> &mut Self
452    where
453        S: ServerHook,
454    {
455        self.get_mut_response_middleware()
456            .push(Hook::factory::<S>());
457        self
458    }
459
460    /// Format the host and port into a bindable address string.
461    ///
462    /// # Arguments
463    ///
464    /// - `H` - The host address.
465    /// - `u16` - The port number.
466    ///
467    /// # Returns
468    ///
469    /// - `String` - The formatted address string in the form "host:port".
470    #[inline(always)]
471    pub fn format_bind_address<H>(host: H, port: u16) -> String
472    where
473        H: AsRef<str>,
474    {
475        format!("{}{COLON}{port}", host.as_ref())
476    }
477
478    /// Flushes the standard output stream.
479    ///
480    /// # Returns
481    ///
482    /// - `io::Result<()>` - The result of the flush operation.
483    #[inline(always)]
484    pub fn try_flush_stdout() -> io::Result<()> {
485        stdout().flush()
486    }
487
488    /// Flushes the standard output stream.
489    ///
490    /// # Panics
491    ///
492    /// This function will panic if the flush operation fails.
493    #[inline(always)]
494    pub fn flush_stdout() {
495        stdout().flush().unwrap();
496    }
497
498    /// Flushes the standard error stream.
499    ///
500    /// # Returns
501    ///
502    /// - `io::Result<()>` - The result of the flush operation.
503    #[inline(always)]
504    pub fn try_flush_stderr() -> io::Result<()> {
505        stderr().flush()
506    }
507
508    /// Flushes the standard error stream.
509    ///
510    /// # Panics
511    ///
512    /// This function will panic if the flush operation fails.
513    #[inline(always)]
514    pub fn flush_stderr() {
515        stderr().flush().unwrap();
516    }
517
518    /// Flushes both the standard output and error streams.
519    ///
520    /// # Returns
521    ///
522    /// - `io::Result<()>` - The result of the flush operation.
523    #[inline(always)]
524    pub fn try_flush_stdout_and_stderr() -> io::Result<()> {
525        Self::try_flush_stdout()?;
526        Self::try_flush_stderr()
527    }
528
529    /// Flushes both the standard output and error streams.
530    ///
531    /// # Panics
532    ///
533    /// This function will panic if either flush operation fails.
534    #[inline(always)]
535    pub fn flush_stdout_and_stderr() {
536        Self::flush_stdout();
537        Self::flush_stderr();
538    }
539
540    /// Executes trait-based request middleware in sequence.
541    ///
542    /// # Arguments
543    ///
544    /// - `&mut Stream` - The `Stream` for the current request.
545    /// - `&mut Context` - The `Context` for the current request.
546    ///
547    /// # Returns
548    ///
549    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
550    pub(super) async fn handle_request_middleware(
551        &self,
552        stream: &mut Stream,
553        ctx: &mut Context,
554    ) -> bool {
555        for hook in self.get_request_middleware().iter() {
556            if hook(stream, ctx).await.is_reject() {
557                return true;
558            }
559        }
560        false
561    }
562
563    /// Executes a trait-based route hook if one matches.
564    ///
565    /// # Arguments
566    ///
567    /// - `&mut Stream` - The `Stream` for the current request.
568    /// - `&mut Context` - The `Context` for the current request.
569    /// - `&str` - The request path to match.
570    ///
571    /// # Returns
572    ///
573    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
574    pub(super) async fn handle_route_matcher(
575        &self,
576        stream: &mut Stream,
577        ctx: &mut Context,
578        path: &str,
579    ) -> bool {
580        if let Some(hook) = self.get_route_matcher().try_resolve_route(ctx, path)
581            && hook(stream, ctx).await.is_reject()
582        {
583            return true;
584        }
585        false
586    }
587
588    /// Executes trait-based response middleware in sequence.
589    ///
590    /// # Arguments
591    ///
592    /// - `&mut Stream` - The `Stream` for the current request.
593    /// - `&mut Context` - The `Context` for the current request.
594    ///
595    /// # Returns
596    ///
597    /// - `bool` - `true` if the lifecycle was aborted, `false` otherwise.
598    pub(super) async fn handle_response_middleware(
599        &self,
600        stream: &mut Stream,
601        ctx: &mut Context,
602    ) -> bool {
603        for hook in self.get_response_middleware().iter() {
604            if hook(stream, ctx).await.is_reject() {
605                return true;
606            }
607        }
608        false
609    }
610
611    /// Handles errors that occur while processing HTTP requests.
612    ///
613    /// # Arguments
614    ///
615    /// - `&mut Stream` - The `Stream` for the current request.
616    /// - `&mut Context` - The `Context` for the current request.
617    /// - `&RequestError` - The error that occurred.
618    pub async fn handle_request_error(
619        &self,
620        stream: &mut Stream,
621        ctx: &mut Context,
622        error: &RequestError,
623    ) {
624        ctx.set_request_error_data(error.clone());
625        stream.set_closed(false);
626        for hook in self.get_request_error().iter() {
627            if hook(stream, ctx).await.is_reject() {
628                return;
629            }
630        }
631    }
632
633    /// The core request handling pipeline.
634    ///
635    /// This function orchestrates the execution of request middleware, the route hook,
636    /// and response middleware. It supports both function-based and trait-based handlers.
637    ///
638    /// # Arguments
639    ///
640    /// - `&mut Stream` - The `Stream` for the current request.
641    /// - `&mut Context` - The `Context` for the current request.
642    /// - `Request` - The incoming request to be processed.
643    ///
644    /// # Returns
645    ///
646    /// - `bool` - A boolean indicating whether the connection should be kept alive.
647    pub(crate) async fn request_hook(
648        &self,
649        stream: &mut Stream,
650        ctx: &mut Context,
651        request: Request,
652    ) -> bool {
653        let keep_alive: bool = request.is_enable_keep_alive();
654        let version: RequestVersion = request.get_version().clone();
655        ctx.set_request(request);
656        ctx.get_mut_response().reset().set_version(version);
657        ctx.clear_route_params();
658        ctx.clear_attribute();
659        stream.set_closed(false);
660        if self.handle_request_middleware(stream, ctx).await {
661            return stream.is_keep_alive(keep_alive);
662        }
663        // A static route is the common case and needs nothing but the path,
664        // so the path is borrowed from the request instead of being copied
665        // out of it. Only a pattern route, which is the rarer case, pays for
666        // the copy.
667        let static_hook: Option<&ServerHookHandler> = {
668            let path: &str = ctx.get_request().get_path().as_str();
669            self.get_route_matcher().try_resolve_static_route(path)
670        };
671        if let Some(hook) = static_hook {
672            if hook(stream, ctx).await.is_reject() {
673                return stream.is_keep_alive(keep_alive);
674            }
675        } else {
676            let route: RequestPath = ctx.get_request().get_path().clone();
677            if self.handle_route_matcher(stream, ctx, &route).await {
678                return stream.is_keep_alive(keep_alive);
679            }
680        }
681        if self.handle_response_middleware(stream, ctx).await {
682            return stream.is_keep_alive(keep_alive);
683        }
684        stream.is_keep_alive(keep_alive)
685    }
686
687    /// Handles subsequent HTTP requests on a persistent (keep-alive) connection.
688    ///
689    /// # Arguments
690    ///
691    /// - `&mut Stream` - The `Stream` for the current request.
692    /// - `&mut Context` - The `Context` for the current request.
693    /// - `Request` - The initial request that established the keep-alive connection.
694    async fn handle_http_requests(&self, stream: &mut Stream, ctx: &mut Context, request: Request) {
695        if !self.request_hook(stream, ctx, request).await {
696            return;
697        }
698        loop {
699            let mut reused_request: Request = mem::take(ctx.get_mut_request());
700            match stream.try_fill_http_request(&mut reused_request).await {
701                Ok(()) => {
702                    if !self.request_hook(stream, ctx, reused_request).await {
703                        return;
704                    }
705                }
706                Err(error) => {
707                    ctx.set_request(reused_request);
708                    self.handle_request_error(stream, ctx, &error).await;
709                    return;
710                }
711            }
712        }
713    }
714
715    /// Handles a single client connection, determining whether it's an HTTP or WebSocket request.
716    ///
717    /// It reads the initial request from the stream and dispatches it to the appropriate hook.
718    /// Both arguments are borrowed: the stream and the context belong to the
719    /// caller, so this leaves them alive for whatever runs next — the panic
720    /// hooks after an unwind, or the next request on a keep alive connection.
721    ///
722    /// # Arguments
723    ///
724    /// - `&mut Stream` - The `Stream` for the current request.
725    /// - `&mut Context` - The `Context` for the current request.
726    async fn handle_connection(&self, stream: &mut Stream, ctx: &mut Context) {
727        match stream.try_get_http_request().await {
728            Ok(request) => {
729                self.handle_http_requests(stream, ctx, request).await;
730            }
731            Err(error) => {
732                self.handle_request_error(stream, ctx, &error).await;
733            }
734        }
735    }
736
737    /// Serves one HTTP/1.1 connection through the existing keep alive pipeline.
738    ///
739    /// This is the same pipeline a plaintext connection has always used: the
740    /// request parser runs in a loop, so keep alive, upgrades and raw writes
741    /// behave exactly as they did before TLS and the multiplexed protocols
742    /// existed. A handler that panics is caught here and reported through the
743    /// existing task panic hooks, so the accept loop survives it and the hooks
744    /// see the panic while the stream and context are still alive.
745    ///
746    /// # Arguments
747    ///
748    /// - `&mut Stream` - The stream carrying the connection.
749    ///
750    /// # Returns
751    ///
752    /// - `()` - Resolves once the connection is finished.
753    pub(crate) async fn serve_h1_connection_stream(&self, stream: &mut Stream) {
754        let mut ctx: Context = Context::default();
755        let panicked: Option<PanicData> =
756            catch_connection_panic(self.handle_connection(stream, &mut ctx)).await;
757        let Some(panic) = panicked else {
758            return;
759        };
760        ctx.set_task_panic(panic)
761            .get_mut_response()
762            .set_status_code(HttpStatus::InternalServerError.code());
763        stream.set_closed(false);
764        for hook in self.get_task_panic().iter() {
765            if hook(stream, &mut ctx).await.is_reject() {
766                break;
767            }
768        }
769    }
770
771    /// Serves one request that arrived on a multiplexed protocol stream.
772    ///
773    /// The lifecycle is the one an HTTP/1.1 request runs: the request
774    /// middleware, the matched route and the response middleware, in that
775    /// order, against the same context and the same error hook. A panic inside
776    /// it is caught the same way a connection panic is.
777    ///
778    /// # Arguments
779    ///
780    /// - `&mut Stream` - The stream the pipeline writes its response onto.
781    /// - `&mut Context` - The context for the current request.
782    /// - `Request` - The request converted from the protocol head and body.
783    ///
784    /// # Returns
785    ///
786    /// - `()` - Resolves once the pipeline has finished writing.
787    pub(crate) async fn run_protocol_lifecycle(
788        &self,
789        stream: &mut Stream,
790        ctx: &mut Context,
791        request: Request,
792    ) {
793        let panicked: Option<PanicData> = catch_connection_panic(async {
794            let _keep_alive: bool = self.request_hook(stream, ctx, request).await;
795        })
796        .await;
797        let Some(panic) = panicked else {
798            return;
799        };
800        ctx.set_task_panic(panic)
801            .get_mut_response()
802            .set_status_code(HttpStatus::InternalServerError.code());
803        stream.set_closed(false);
804        for hook in self.get_task_panic().iter() {
805            if hook(stream, ctx).await.is_reject() {
806                break;
807            }
808        }
809    }
810
811    /// Starts the server, binds to the configured address, and begins listening.
812    ///
813    /// The configured protocol selects the listener. HTTP/1.1 and HTTP/2 share
814    /// the TCP listener, the latter speaking its own preface and optionally
815    /// wrapping the connection in TLS, while HTTP/3 binds a QUIC UDP endpoint.
816    /// Invalid TLS material and an HTTP/3 configuration without TLS are both
817    /// rejected before the socket is bound, so a misconfigured server fails to
818    /// start rather than accepting connections it cannot serve.
819    ///
820    /// The accept loop owns a clone of the server instead of borrowing it, so
821    /// running a short lived `Server` stays safe and dropping it leaves no
822    /// leaked allocation behind.
823    ///
824    /// # Returns
825    ///
826    /// - `Result<ServerControlHook, Box<ServerError>>` - The shutdown hook on
827    ///   success, or the failure that prevented the server from binding.
828    pub async fn run(&self) -> Result<ServerControlHook, Box<ServerError>> {
829        let server_config: &ServerConfig = self.get_server_config();
830        let protocol: ServerProtocol = server_config.get_protocol();
831        let tls_config: Option<TlsConfig> = server_config.get_tls().clone();
832        if protocol == ServerProtocol::Http3 && tls_config.is_none() {
833            return Err(Box::new(ServerError::MissingTlsForHttp3));
834        }
835        let stream_tls: Option<Arc<rustls::ServerConfig>> = match tls_config.clone() {
836            Some(_) if protocol == ServerProtocol::Http3 => None,
837            Some(config) => Some(build_stream_tls_config(&config, &protocol)?),
838            None => None,
839        };
840        let bind_address: &String = server_config.get_address();
841        let server: Arc<Server> = Arc::new(Self::clone(self));
842        let request_config: RequestConfig = *self.get_request_config();
843        let (shutdown_sender, shutdown_receiver) = channel(());
844        let (running_sender, running_receiver) = channel(SERVER_RUNNING);
845        let _: JoinHandle<()> = match protocol {
846            ServerProtocol::Http3 => {
847                let Some(config) = tls_config.clone() else {
848                    return Err(Box::new(ServerError::MissingTlsForHttp3));
849                };
850                let quic_config: Arc<quinn::crypto::rustls::QuicServerConfig> = Arc::new(
851                    quinn::crypto::rustls::QuicServerConfig::try_from(build_quic_tls_config(
852                        &config,
853                    )?)
854                    .map_err(
855                        |error: quinn::crypto::rustls::NoInitialCipherSuite| {
856                            Box::new(ServerError::Tls(format!(
857                                "no compatible cipher suite for quic: {}",
858                                error
859                            )))
860                        },
861                    )?,
862                );
863                let bind_addr: SocketAddr =
864                    bind_address
865                        .parse::<SocketAddr>()
866                        .map_err(|error: AddrParseError| {
867                            Box::new(ServerError::Tls(format!(
868                                "invalid bind address {}: {}",
869                                bind_address, error
870                            )))
871                        })?;
872                let endpoint: Endpoint =
873                    Endpoint::server(quinn::ServerConfig::with_crypto(quic_config), bind_addr)
874                        .map_err(|error: io::Error| Box::new(ServerError::from(error)))?;
875                let env: ConnectionEnv = ConnectionEnv {
876                    server,
877                    request_config,
878                    protocol,
879                };
880                spawn(async move {
881                    let _: Result<(), Box<ServerError>> =
882                        quic_accept(env, endpoint, shutdown_receiver, running_sender).await;
883                })
884            }
885            _ => {
886                let tcp_listener: TcpListener = TcpListener::bind(&bind_address)
887                    .await
888                    .map_err(|error: io::Error| Box::new(ServerError::from(error)))?;
889                let env: ConnectionEnv = ConnectionEnv {
890                    server,
891                    request_config,
892                    protocol,
893                };
894                spawn(async move {
895                    tcp_accept(
896                        env,
897                        stream_tls,
898                        AcceptSignal {
899                            listener: tcp_listener,
900                            shutdown_receiver,
901                            running_sender,
902                        },
903                    )
904                    .await;
905                })
906            }
907        };
908        let wait_hook: ServerControlHookHandler<()> = Arc::new(move || {
909            let mut running_receiver_clone: Receiver<bool> = running_receiver.clone();
910            Box::pin(async move {
911                while !*running_receiver_clone.borrow_and_update() {
912                    let _: Result<(), tokio::sync::watch::error::RecvError> =
913                        running_receiver_clone.changed().await;
914                }
915            })
916        });
917        let shutdown_hook: ServerControlHookHandler<()> = Arc::new(move || {
918            let shutdown_sender_clone: Sender<()> = shutdown_sender.clone();
919            Box::pin(async move {
920                let _: Result<(), tokio::sync::watch::error::SendError<()>> =
921                    shutdown_sender_clone.send(());
922            })
923        });
924        let mut server_control_hook: ServerControlHook = ServerControlHook::default();
925        server_control_hook.set_shutdown_hook(shutdown_hook);
926        server_control_hook.set_wait_hook(wait_hook);
927        Ok(server_control_hook)
928    }
929}