@@ -7,9 +7,11 @@ mod wagi;
7
7
8
8
use std:: {
9
9
collections:: HashMap ,
10
+ fmt:: Display ,
10
11
future:: ready,
11
- net:: { Ipv4Addr , SocketAddr , ToSocketAddrs } ,
12
+ net:: { Ipv4Addr , SocketAddr , SocketAddrV4 , ToSocketAddrs } ,
12
13
path:: PathBuf ,
14
+ str:: FromStr ,
13
15
sync:: Arc ,
14
16
} ;
15
17
@@ -56,18 +58,73 @@ pub struct HttpTrigger {
56
58
component_trigger_configs : HashMap < String , HttpTriggerConfig > ,
57
59
}
58
60
59
- #[ derive( Args ) ]
61
+ #[ derive( Copy , Clone , PartialEq , Eq , Hash , PartialOrd , Ord , Debug ) ]
62
+ pub struct SocketAddress ( SocketAddr ) ;
63
+
64
+ impl SocketAddress {
65
+ pub fn new ( v4 : Ipv4Addr , port : u16 ) -> Self {
66
+ Self ( SocketAddr :: V4 ( SocketAddrV4 :: new ( v4, port) ) )
67
+ }
68
+ }
69
+
70
+ impl Into < SocketAddr > for SocketAddress {
71
+ fn into ( self ) -> SocketAddr {
72
+ return self . 0 ;
73
+ }
74
+ }
75
+
76
+ impl ToSocketAddrs for SocketAddress {
77
+ type Iter = <SocketAddr as ToSocketAddrs >:: Iter ;
78
+
79
+ fn to_socket_addrs ( & self ) -> std:: io:: Result < Self :: Iter > {
80
+ self . 0 . to_socket_addrs ( )
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
109
+ . into_iter ( )
110
+ . next ( )
111
+ . context ( "couldn't resolve address" )
112
+ . map ( Self )
113
+ }
114
+ }
115
+
116
+ #[ derive( Args , Clone ) ]
60
117
pub struct CliArgs {
61
118
/// 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 ,
119
+ #[ arg ( long = "listen" , default_value_t = SocketAddress :: default ( ) ) ]
120
+ pub address : SocketAddress ,
64
121
65
122
/// 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 " ) ]
123
+ #[ arg ( long, env = "SPIN_TLS_CERT" , requires = "tls_key " ) ]
67
124
pub tls_cert : Option < PathBuf > ,
68
125
69
126
/// 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 " ) ]
127
+ #[ arg ( long, env = "SPIN_TLS_KEY" , requires = "tls_cert " ) ]
71
128
pub tls_key : Option < PathBuf > ,
72
129
}
73
130
@@ -177,11 +234,10 @@ impl TriggerExecutor for HttpTrigger {
177
234
}
178
235
179
236
if let Some ( tls) = tls {
180
- self . serve_tls ( listen_addr, tls) . await ?
237
+ self . serve_tls ( listen_addr, tls) . await
181
238
} else {
182
- self . serve ( listen_addr) . await ?
183
- } ;
184
- Ok ( ( ) )
239
+ self . serve ( listen_addr) . await
240
+ }
185
241
}
186
242
}
187
243
@@ -293,7 +349,7 @@ impl HttpTrigger {
293
349
. body ( Body :: empty ( ) ) ?)
294
350
}
295
351
296
- async fn serve ( self , listen_addr : SocketAddr ) -> Result < ( ) > {
352
+ async fn serve ( self , listen_addr : SocketAddress ) -> Result < ( ) > {
297
353
let self_ = Arc :: new ( self ) ;
298
354
let make_service = make_service_fn ( |conn : & AddrStream | {
299
355
let self_ = self_. clone ( ) ;
@@ -307,14 +363,14 @@ impl HttpTrigger {
307
363
}
308
364
} ) ;
309
365
310
- Server :: try_bind ( & listen_addr)
366
+ Server :: try_bind ( & listen_addr. into ( ) )
311
367
. with_context ( || format ! ( "Unable to listen on {}" , listen_addr) ) ?
312
368
. serve ( make_service)
313
369
. await ?;
314
370
Ok ( ( ) )
315
371
}
316
372
317
- async fn serve_tls ( self , listen_addr : SocketAddr , tls : TlsConfig ) -> Result < ( ) > {
373
+ async fn serve_tls ( self , listen_addr : SocketAddress , tls : TlsConfig ) -> Result < ( ) > {
318
374
let self_ = Arc :: new ( self ) ;
319
375
let make_service = make_service_fn ( |conn : & TlsStream < TcpStream > | {
320
376
let self_ = self_. clone ( ) ;
@@ -340,7 +396,7 @@ impl HttpTrigger {
340
396
}
341
397
} ) ;
342
398
343
- let listener = TcpListener :: bind ( & listen_addr)
399
+ let listener = TcpListener :: bind :: < SocketAddr > ( listen_addr. into ( ) )
344
400
. await
345
401
. with_context ( || format ! ( "Unable to listen on {}" , listen_addr) ) ?;
346
402
@@ -369,19 +425,6 @@ pub struct AppInfo {
369
425
pub bindle_version : Option < String > ,
370
426
}
371
427
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
428
fn set_req_uri ( req : & mut Request < Body > , scheme : Scheme ) -> Result < ( ) > {
386
429
const DEFAULT_HOST : & str = "localhost" ;
387
430
@@ -649,7 +692,7 @@ mod tests {
649
692
650
693
#[ test]
651
694
fn parse_listen_addr_prefers_ipv4 ( ) {
652
- let addr = parse_listen_addr ( "localhost:12345" ) . unwrap ( ) ;
695
+ let addr = SocketAddr :: from_str ( "localhost:12345" ) . unwrap ( ) ;
653
696
assert_eq ! ( addr. ip( ) , Ipv4Addr :: LOCALHOST ) ;
654
697
assert_eq ! ( addr. port( ) , 12345 ) ;
655
698
}
0 commit comments