      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115

    use std::{fmt, net};

    use actix_net::either::Either;
    use actix_net::server::{Server, ServiceFactory};
    use actix_net::service::{NewService, NewServiceExt};

    use super::acceptor::{
        AcceptorServiceFactory, AcceptorTimeout, ServerMessageAcceptor, TcpAcceptor,
    };
    use super::error::AcceptorError;
    use super::handler::IntoHttpHandler;
    use super::service::HttpService;
    use super::settings::{ServerSettings, ServiceConfig};
    use super::KeepAlive;

    pub(crate) trait ServiceProvider {
        fn register(
            &self, server: Server, lst: net::TcpListener, host: String,
            addr: net::SocketAddr, keep_alive: KeepAlive, secure: bool, client_timeout: u64,
            client_shutdown: u64,
        ) -> Server;
    }

    /// Utility type that builds complete http pipeline
    pub(crate) struct HttpServiceBuilder<F, H, A>
    where
        F: Fn() -> H + Send + Clone,
    {
        factory: F,
        acceptor: A,
    }

    impl<F, H, A> HttpServiceBuilder<F, H, A>
    where
        F: Fn() -> H + Send + Clone + 'static,
        H: IntoHttpHandler,
        A: AcceptorServiceFactory,
        <A::NewService as NewService>::InitError: fmt::Debug,
    {
        /// Create http service builder
        pub fn new(factory: F, acceptor: A) -> Self {
            Self { factory, acceptor }
        }

        fn finish(
            &self, host: String, addr: net::SocketAddr, keep_alive: KeepAlive, secure: bool,
            client_timeout: u64, client_shutdown: u64,
        ) -> impl ServiceFactory {
            let factory = self.factory.clone();
            let acceptor = self.acceptor.clone();
            move || {
                let app = (factory)().into_handler();
                let settings = ServiceConfig::new(
                    app,
                    keep_alive,
                    client_timeout,
                    client_shutdown,
                    ServerSettings::new(addr, &host, false),
                );

                if secure {
                    Either::B(ServerMessageAcceptor::new(
                        TcpAcceptor::new(AcceptorTimeout::new(
                            client_timeout,
                            acceptor.create(),
                        )).map_err(|_| ())
                        .map_init_err(|_| ())
                        .and_then(
                            HttpService::new(settings)
                                .map_init_err(|_| ())
                                .map_err(|_| ()),
                        ),
                    ))
                } else {
                    Either::A(ServerMessageAcceptor::new(
                        TcpAcceptor::new(acceptor.create().map_err(AcceptorError::Service))
                            .map_err(|_| ())
                            .map_init_err(|_| ())
                            .and_then(
                                HttpService::new(settings)
                                    .map_init_err(|_| ())
                                    .map_err(|_| ()),
                            ),
                    ))
                }
            }
        }
    }

    impl<F, H, A> ServiceProvider for HttpServiceBuilder<F, H, A>
    where
        F: Fn() -> H + Send + Clone + 'static,
        A: AcceptorServiceFactory,
        <A::NewService as NewService>::InitError: fmt::Debug,
        H: IntoHttpHandler,
    {
        fn register(
            &self, server: Server, lst: net::TcpListener, host: String,
            addr: net::SocketAddr, keep_alive: KeepAlive, secure: bool, client_timeout: u64,
            client_shutdown: u64,
        ) -> Server {
            server.listen2(
                "actix-web",
                lst,
                self.finish(
                    host,
                    addr,
                    keep_alive,
                    secure,
                    client_timeout,
                    client_shutdown,
                ),
            )
        }
    }

# Help

## Keyboard Shortcuts

`?`
  Show this help dialog
`S`
  Focus the search field
`↑`
  Move up in search results
`↓`
  Move down in search results
`↹`
  Switch tab
`⏎`
  Go to active search result
`+`
  Expand all sections
`-`
  Collapse all sections

## Search Tricks

Prefix searches with a type followed by a colon (e.g. `fn:`) to restrict the search to a given type.

Accepted types are: `fn`, `mod`, `struct`, `enum`, `trait`, `type`, `macro`, and `const`.

Search functions by type signature (e.g. `vec -> usize` or `* -> vec`)

Search multiple things at once by splitting your query with comma (e.g. `str,u8` or `String,struct:Vec,test`)