@@ -56,6 +56,9 @@ pub enum Error {
56
56
57
57
#[ snafu( display( "failed to set safe TLS protocol versions" ) ) ]
58
58
SetSafeTlsProtocolVersions { source : tokio_rustls:: rustls:: Error } ,
59
+
60
+ #[ snafu( display( "failed to run task in blocking thread" ) ) ]
61
+ TokioSpawnBlocking { source : tokio:: task:: JoinError } ,
59
62
}
60
63
61
64
/// Custom implementation of [`std::cmp::PartialEq`] because some inner types
@@ -94,37 +97,49 @@ pub struct TlsServer {
94
97
impl TlsServer {
95
98
#[ instrument( name = "create_tls_server" , skip( router) ) ]
96
99
pub async fn new ( socket_addr : SocketAddr , router : Router ) -> Result < Self > {
97
- let mut certificate_authority =
98
- CertificateAuthority :: new_rsa ( ) . context ( CreateCertificateAuthoritySnafu ) ?;
99
-
100
- let leaf_certificate = certificate_authority
101
- . generate_rsa_leaf_certificate ( "Leaf" , "webhook" , Duration :: from_secs ( 3600 ) )
102
- . context ( GenerateLeafCertificateSnafu ) ?;
103
-
104
- let certificate_der = leaf_certificate
105
- . certificate_der ( )
106
- . context ( EncodeCertificateDerSnafu ) ?;
107
-
108
- let private_key_der = leaf_certificate
109
- . private_key_der ( )
110
- . context ( EncodePrivateKeyDerSnafu ) ?;
111
-
112
- let tls_provider = default_provider ( ) ;
113
- let mut config = ServerConfig :: builder_with_provider ( tls_provider. into ( ) )
114
- . with_protocol_versions ( & [ & TLS12 , & TLS13 ] )
115
- . context ( SetSafeTlsProtocolVersionsSnafu ) ?
116
- . with_no_client_auth ( )
117
- . with_single_cert ( vec ! [ certificate_der] , private_key_der)
118
- . context ( InvalidTlsPrivateKeySnafu ) ?;
119
-
120
- config. alpn_protocols = vec ! [ b"h2" . to_vec( ) , b"http/1.1" . to_vec( ) ] ;
121
- let config = Arc :: new ( config) ;
122
-
123
- Ok ( Self {
124
- socket_addr,
125
- config,
126
- router,
100
+ // NOTE(@NickLarsenNZ): This code is not async, and does take some
101
+ // non-negligable amount of time to complete (moreso in debug ).
102
+ // We run this in a thread reserved for blocking code so that the Tokio
103
+ // executor is able to make progress on other futures instead of being
104
+ // blocked.
105
+ // See https://docs.rs/tokio/latest/tokio/task/fn.spawn_blocking.html
106
+ let task = tokio:: task:: spawn_blocking ( move || {
107
+ let mut certificate_authority =
108
+ CertificateAuthority :: new_rsa ( ) . context ( CreateCertificateAuthoritySnafu ) ?;
109
+
110
+ let leaf_certificate = certificate_authority
111
+ . generate_rsa_leaf_certificate ( "Leaf" , "webhook" , Duration :: from_secs ( 3600 ) )
112
+ . context ( GenerateLeafCertificateSnafu ) ?;
113
+
114
+ let certificate_der = leaf_certificate
115
+ . certificate_der ( )
116
+ . context ( EncodeCertificateDerSnafu ) ?;
117
+
118
+ let private_key_der = leaf_certificate
119
+ . private_key_der ( )
120
+ . context ( EncodePrivateKeyDerSnafu ) ?;
121
+
122
+ let tls_provider = default_provider ( ) ;
123
+ let mut config = ServerConfig :: builder_with_provider ( tls_provider. into ( ) )
124
+ . with_protocol_versions ( & [ & TLS12 , & TLS13 ] )
125
+ . context ( SetSafeTlsProtocolVersionsSnafu ) ?
126
+ . with_no_client_auth ( )
127
+ . with_single_cert ( vec ! [ certificate_der] , private_key_der)
128
+ . context ( InvalidTlsPrivateKeySnafu ) ?;
129
+
130
+ config. alpn_protocols = vec ! [ b"h2" . to_vec( ) , b"http/1.1" . to_vec( ) ] ;
131
+ let config = Arc :: new ( config) ;
132
+
133
+ Ok ( Self {
134
+ socket_addr,
135
+ config,
136
+ router,
137
+ } )
127
138
} )
139
+ . await
140
+ . context ( TokioSpawnBlockingSnafu ) ??;
141
+
142
+ Ok ( task)
128
143
}
129
144
130
145
/// Runs the TLS server by listening for incoming TCP connections on the
0 commit comments