5
5
6
6
use std:: collections:: HashMap ;
7
7
use std:: convert:: Infallible ;
8
+ use std:: fs;
9
+ use std:: io:: { Read , Write } ;
8
10
use std:: net:: { IpAddr , Ipv4Addr , SocketAddr } ;
9
11
use std:: path:: { Path , PathBuf } ;
10
12
use std:: sync:: { Arc , Mutex } ;
@@ -13,7 +15,6 @@ use std::time::{Duration, Instant};
13
15
use const_format:: concatcp;
14
16
use hyper:: service:: { make_service_fn, service_fn} ;
15
17
use hyper:: { Body , Request , Response , Server } ;
16
- use tempfile:: { tempdir, TempDir } ;
17
18
use tokio:: io:: { AsyncBufReadExt , BufReader } ;
18
19
use tokio:: pin;
19
20
@@ -77,21 +78,15 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
77
78
legal:: require_consent ( & ctx. paths , args. accept_server_license_terms ) ?;
78
79
79
80
let platform: crate :: update_service:: Platform = PreReqChecker :: new ( ) . verify ( ) . await ?;
80
- let token_file = if !args. without_connection_token {
81
+ if !args. without_connection_token {
81
82
// Ensure there's a defined connection token, since if multiple server versions
82
83
// are excuted, they will need to have a single shared token.
83
- let connection_token = args
84
- . connection_token
85
- . clone ( )
86
- . unwrap_or_else ( || uuid:: Uuid :: new_v4 ( ) . to_string ( ) ) ;
87
- let tf = ConnectionTokenFile :: new ( & connection_token)
84
+ let token_path = ctx. paths . root ( ) . join ( "serve-web-token" ) ;
85
+ let token = mint_connection_token ( & token_path, args. connection_token . clone ( ) )
88
86
. map_err ( CodeError :: CouldNotCreateConnectionTokenFile ) ?;
89
- args. connection_token = Some ( connection_token) ;
90
- args. connection_token_file = Some ( tf. path ( ) . to_string_lossy ( ) . to_string ( ) ) ;
91
- Some ( tf)
92
- } else {
93
- None
94
- } ;
87
+ args. connection_token = Some ( token) ;
88
+ args. connection_token_file = Some ( token_path. to_string_lossy ( ) . to_string ( ) ) ;
89
+ }
95
90
96
91
let cm = ConnectionManager :: new ( & ctx, platform, args. clone ( ) ) ;
97
92
let key = get_server_key_half ( & ctx. paths ) ;
@@ -143,7 +138,6 @@ pub async fn serve_web(ctx: CommandContext, mut args: ServeWebArgs) -> Result<i3
143
138
} ;
144
139
145
140
r. map_err ( CodeError :: CouldNotListenOnInterface ) ?;
146
- drop ( token_file) ; // ensure it lives long enough
147
141
148
142
Ok ( 0 )
149
143
}
@@ -789,20 +783,29 @@ struct StartArgs {
789
783
opener : BarrierOpener < Result < StartData , String > > ,
790
784
}
791
785
792
- struct ConnectionTokenFile {
793
- path : PathBuf ,
794
- _dir : TempDir , // implements Drop to delete the dir
795
- }
796
-
797
- impl ConnectionTokenFile {
798
- fn new ( connection_token : & str ) -> std:: io:: Result < Self > {
799
- let d = tempdir ( ) ?;
800
- let path = d. path ( ) . join ( "connection-token" ) ;
801
- std:: fs:: write ( & path, connection_token) ?;
802
- Ok ( ConnectionTokenFile { path, _dir : d } )
786
+ fn mint_connection_token ( path : & Path , prefer_token : Option < String > ) -> std:: io:: Result < String > {
787
+ #[ cfg( not( windows) ) ]
788
+ use std:: os:: unix:: fs:: OpenOptionsExt ;
789
+
790
+ let mut f = fs:: OpenOptions :: new ( ) ;
791
+ f. create ( true ) ;
792
+ f. write ( true ) ;
793
+ f. read ( true ) ;
794
+ #[ cfg( not( windows) ) ]
795
+ f. mode ( 0o600 ) ;
796
+ let mut f = f. open ( path) ?;
797
+
798
+ if prefer_token. is_none ( ) {
799
+ let mut t = String :: new ( ) ;
800
+ f. read_to_string ( & mut t) ?;
801
+ let t = t. trim ( ) ;
802
+ if !t. is_empty ( ) {
803
+ return Ok ( t. to_string ( ) ) ;
804
+ }
803
805
}
804
806
805
- fn path ( & self ) -> & Path {
806
- & self . path
807
- }
807
+ f. set_len ( 0 ) ?;
808
+ let prefer_token = prefer_token. unwrap_or_else ( || uuid:: Uuid :: new_v4 ( ) . to_string ( ) ) ;
809
+ f. write_all ( prefer_token. as_bytes ( ) ) ?;
810
+ Ok ( prefer_token)
808
811
}
0 commit comments