@@ -23,6 +23,9 @@ pub const SRUN_PORTAL: &str = "http://10.0.0.55";
23
23
pub const SRUN_TYPE : & str = "1" ;
24
24
pub const SRUN_N : & str = "200" ;
25
25
26
+ /// An arbitrary HTTP URL for srun to redirect
27
+ pub const CAPTIVE_PORTAL_TEST : & str = "http://www.bit.edu.cn" ;
28
+
26
29
/// The response from the `/rad_user_info` endpoint
27
30
///
28
31
/// This response is used to determine if the device is logged in or not, and if it is logged in,
@@ -128,12 +131,12 @@ pub async fn get_login_state(client: &Client, verbose: bool) -> Result<SrunLogin
128
131
Ok ( parsed_json)
129
132
}
130
133
131
- /// Get the ac_id of the current device
132
- async fn get_acid ( client : & Client ) -> Result < String > {
133
- let resp = client. get ( SRUN_PORTAL ) . send ( ) . await . with_context ( || {
134
+ /// Get the ac_id of the current device by visiting a URL
135
+ async fn get_acid_by_url ( client : & Client , url : & str ) -> Result < String > {
136
+ let resp = client. get ( url ) . send ( ) . await . with_context ( || {
134
137
format ! (
135
138
"failed to get ac_id from `{}`" ,
136
- SRUN_PORTAL . if_supports_color( Stdout , |t| t. underline( ) )
139
+ url . if_supports_color( Stdout , |t| t. underline( ) )
137
140
)
138
141
} ) ?;
139
142
let redirect_url = resp. url ( ) . to_string ( ) ;
@@ -154,6 +157,20 @@ async fn get_acid(client: &Client) -> Result<String> {
154
157
Ok ( ac_id. 1 )
155
158
}
156
159
160
+ /// Get the ac_id of the current device
161
+ async fn get_acid ( client : & Client ) -> Result < String > {
162
+ // Try to visit `CAPTIVE_PORTAL_TEST`.
163
+ // If not logged in, it will be redirected to `SRUN_PORTAL` with ac_id.
164
+ // Otherwise, we fall back to visit `SRUN_PORTAL` directly.
165
+ // https://en.wikipedia.org/wiki/Captive_portal#Detection
166
+ //
167
+ // Because of ITC's double authentication mechanism, visiting `SRUN_PORTAL` directly is not preferred.
168
+ // https://itc.bit.edu.cn/fwzn/zxbl/f2c0c8e939ce4e9cace880d5403fe4b5.htm
169
+ get_acid_by_url ( client, CAPTIVE_PORTAL_TEST )
170
+ . await
171
+ . or ( get_acid_by_url ( client, SRUN_PORTAL ) . await )
172
+ }
173
+
157
174
/// SRUN portal response type when calling login/logout
158
175
///
159
176
/// Note that fields that are not used are omitted
0 commit comments