@@ -8,9 +8,9 @@ mod wagi;
8
8
use std:: {
9
9
collections:: HashMap ,
10
10
future:: ready,
11
- net:: { Ipv4Addr , SocketAddr , ToSocketAddrs } ,
11
+ net:: { Ipv4Addr , SocketAddr , SocketAddrV4 , ToSocketAddrs } ,
12
12
path:: PathBuf ,
13
- sync:: Arc ,
13
+ sync:: Arc , str :: FromStr , fmt :: Display ,
14
14
} ;
15
15
16
16
use anyhow:: { Context , Error , Result } ;
@@ -56,18 +56,71 @@ pub struct HttpTrigger {
56
56
component_trigger_configs : HashMap < String , HttpTriggerConfig > ,
57
57
}
58
58
59
- #[ derive( Args ) ]
59
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord , Debug ) ]
60
+ pub struct SocketAddress ( SocketAddr ) ;
61
+
62
+ impl SocketAddress {
63
+ pub fn new ( v4 : Ipv4Addr , port : u16 ) -> Self {
64
+ Self ( SocketAddr :: V4 ( SocketAddrV4 :: new ( v4, port) ) )
65
+ }
66
+ }
67
+
68
+ impl Into < SocketAddr > for SocketAddress {
69
+ fn into ( self ) -> SocketAddr {
70
+ return self . 0
71
+ }
72
+ }
73
+
74
+ impl ToSocketAddrs for SocketAddress {
75
+ type Iter = <SocketAddr as ToSocketAddrs >:: Iter ;
76
+
77
+ fn to_socket_addrs ( & self ) -> std:: io:: Result < Self :: Iter > {
78
+ self . 0 . to_socket_addrs ( )
79
+ }
80
+ }
81
+
82
+
83
+
84
+ impl Display for SocketAddress {
85
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
86
+ self . 0 . fmt ( f)
87
+ }
88
+ }
89
+
90
+ impl Default for SocketAddress {
91
+ fn default ( ) -> Self {
92
+ Self :: new ( Ipv4Addr :: LOCALHOST , 3000 )
93
+ }
94
+ }
95
+
96
+ impl FromStr for SocketAddress {
97
+ type Err = anyhow:: Error ;
98
+ fn from_str ( addr : & str ) -> Result < SocketAddress > {
99
+ let addrs: Vec < SocketAddr > = addr. to_socket_addrs ( ) ?. collect ( ) ;
100
+ // Prefer 127.0.0.1 over e.g. [::1] because CHANGE IS HARD
101
+ if let Some ( addr) = addrs
102
+ . iter ( )
103
+ . find ( |addr| addr. is_ipv4 ( ) && addr. ip ( ) == Ipv4Addr :: LOCALHOST )
104
+ {
105
+ return Ok ( Self ( * addr) ) ;
106
+ }
107
+ // Otherwise, take the first addr (OS preference)
108
+ addrs. into_iter ( ) . next ( ) . context ( "couldn't resolve address" ) . map ( Self )
109
+ }
110
+ }
111
+
112
+ #[ derive( Args , Clone ) ]
60
113
pub struct CliArgs {
61
114
/// IP address and port to listen on
62
- #[ clap ( long = "listen" , default_value = "127.0.0.1:3000" , value_parser = parse_listen_addr ) ]
63
- pub address : SocketAddr ,
115
+ #[ arg ( long = "listen" , default_value_t = SocketAddress :: default ( ) ) ]
116
+ pub address : SocketAddress ,
64
117
65
118
/// The path to the certificate to use for https, if this is not set, normal http will be used. The cert should be in PEM format
66
- #[ clap ( long, env = "SPIN_TLS_CERT" , requires = "tls-key " ) ]
119
+ #[ arg ( long, env = "SPIN_TLS_CERT" , requires = "tls_key " ) ]
67
120
pub tls_cert : Option < PathBuf > ,
68
121
69
122
/// The path to the certificate key to use for https, if this is not set, normal http will be used. The key should be in PKCS#8 format
70
- #[ clap ( long, env = "SPIN_TLS_KEY" , requires = "tls-cert " ) ]
123
+ #[ arg ( long, env = "SPIN_TLS_KEY" , requires = "tls_cert " ) ]
71
124
pub tls_key : Option < PathBuf > ,
72
125
}
73
126
@@ -177,11 +230,10 @@ impl TriggerExecutor for HttpTrigger {
177
230
}
178
231
179
232
if let Some ( tls) = tls {
180
- self . serve_tls ( listen_addr, tls) . await ?
233
+ self . serve_tls ( listen_addr, tls) . await
181
234
} else {
182
- self . serve ( listen_addr) . await ?
183
- } ;
184
- Ok ( ( ) )
235
+ self . serve ( listen_addr) . await
236
+ }
185
237
}
186
238
}
187
239
@@ -293,7 +345,7 @@ impl HttpTrigger {
293
345
. body ( Body :: empty ( ) ) ?)
294
346
}
295
347
296
- async fn serve ( self , listen_addr : SocketAddr ) -> Result < ( ) > {
348
+ async fn serve ( self , listen_addr : SocketAddress ) -> Result < ( ) > {
297
349
let self_ = Arc :: new ( self ) ;
298
350
let make_service = make_service_fn ( |conn : & AddrStream | {
299
351
let self_ = self_. clone ( ) ;
@@ -307,14 +359,14 @@ impl HttpTrigger {
307
359
}
308
360
} ) ;
309
361
310
- Server :: try_bind ( & listen_addr)
362
+ Server :: try_bind ( & listen_addr. into ( ) )
311
363
. with_context ( || format ! ( "Unable to listen on {}" , listen_addr) ) ?
312
364
. serve ( make_service)
313
365
. await ?;
314
366
Ok ( ( ) )
315
367
}
316
368
317
- async fn serve_tls ( self , listen_addr : SocketAddr , tls : TlsConfig ) -> Result < ( ) > {
369
+ async fn serve_tls ( self , listen_addr : SocketAddress , tls : TlsConfig ) -> Result < ( ) > {
318
370
let self_ = Arc :: new ( self ) ;
319
371
let make_service = make_service_fn ( |conn : & TlsStream < TcpStream > | {
320
372
let self_ = self_. clone ( ) ;
@@ -340,7 +392,7 @@ impl HttpTrigger {
340
392
}
341
393
} ) ;
342
394
343
- let listener = TcpListener :: bind ( & listen_addr)
395
+ let listener = TcpListener :: bind :: < SocketAddr > ( listen_addr. into ( ) )
344
396
. await
345
397
. with_context ( || format ! ( "Unable to listen on {}" , listen_addr) ) ?;
346
398
@@ -369,19 +421,6 @@ pub struct AppInfo {
369
421
pub bindle_version : Option < String > ,
370
422
}
371
423
372
- fn parse_listen_addr ( addr : & str ) -> anyhow:: Result < SocketAddr > {
373
- let addrs: Vec < SocketAddr > = addr. to_socket_addrs ( ) ?. collect ( ) ;
374
- // Prefer 127.0.0.1 over e.g. [::1] because CHANGE IS HARD
375
- if let Some ( addr) = addrs
376
- . iter ( )
377
- . find ( |addr| addr. is_ipv4 ( ) && addr. ip ( ) == Ipv4Addr :: LOCALHOST )
378
- {
379
- return Ok ( * addr) ;
380
- }
381
- // Otherwise, take the first addr (OS preference)
382
- addrs. into_iter ( ) . next ( ) . context ( "couldn't resolve address" )
383
- }
384
-
385
424
fn set_req_uri ( req : & mut Request < Body > , scheme : Scheme ) -> Result < ( ) > {
386
425
const DEFAULT_HOST : & str = "localhost" ;
387
426
@@ -649,7 +688,7 @@ mod tests {
649
688
650
689
#[ test]
651
690
fn parse_listen_addr_prefers_ipv4 ( ) {
652
- let addr = parse_listen_addr ( "localhost:12345" ) . unwrap ( ) ;
691
+ let addr = SocketAddr :: from_str ( "localhost:12345" ) . unwrap ( ) ;
653
692
assert_eq ! ( addr. ip( ) , Ipv4Addr :: LOCALHOST ) ;
654
693
assert_eq ! ( addr. port( ) , 12345 ) ;
655
694
}
0 commit comments