MCPcopy Create free account
hub / github.com/BohemiaInteractive/CWR / register_server

Function register_server

mserver/MasterService/src/http.rs:205–268  ·  view source on GitHub ↗
(
    State(state): State<AppState>,
    headers: HeaderMap,
    Json(mut request): Json<RegisterServerRequest>,
)

Source from the content-addressed store, hash-verified

203 path = "/v1/servers/register",
204 request_body = RegisterServerRequest,
205 responses(
206 (status = 200, description = "Registered server row", body = DirectoryServerRecord)
207 )
208)]
209async fn register_server(
210 State(state): State<AppState>,
211 headers: HeaderMap,
212 connect_info: Option<ConnectInfo<SocketAddr>>,
213 Json(mut request): Json<RegisterServerRequest>,
214) -> Result<Json<DirectoryServerRecord>, (StatusCode, String)> {
215 if let Some(ip) = publish_client_ip(&state, &headers, connect_info.as_ref().map(|info| info.0))
216 {
217 request.server_id = format!("{ip}:{}", request.hostport);
218 request.address = ip;
219 }
220 let server_id = request.server_id.clone();
221
222 let existing = state
223 .service
224 .get(&server_id)
225 .await
226 .map_err(|error| internal_error(&error))?;
227 let stored_hash = state
228 .service
229 .server_token_hash(&server_id)
230 .await
231 .map_err(|error| internal_error(&error))?;
232 let provided_token = bearer_token(&headers);
233 let token_ok = matches!(
234 (&provided_token, &stored_hash),
235 (Some(token), Some(hash)) if &service::token_hash(token) == hash
236 );
237
238 // Protect an actively-heartbeating, token-held row from takeover by a wrong/missing
239 // token (only when enforcement is on). A stale row (silent owner) may be reclaimed,
240 // which is the crash-recovery path.
241 if state.require_server_token && !token_ok && stored_hash.is_some() {
242 let fresh = existing.is_some_and(|row| {
243 current_time_millis() - row.last_seen_unix_ms < SERVER_TOKEN_RECOVERY_MS
244 });
245 if fresh {
246 return Err((
247 StatusCode::UNAUTHORIZED,
248 "missing or invalid server token".to_string(),
249 ));
250 }
251 }
252
253 let mut record = state
254 .service
255 .register(request, current_time_millis())
256 .await
257 .map_err(|error| internal_error(&error))?;
258
259 // Issue a token on first registration, and rotate it on an (authorized) takeover; a
260 // valid-token heartbeat keeps the existing token.
261 if !token_ok {
262 let (token, hash) = service::issue_token().map_err(|error| internal_error(&error))?;

Callers

nothing calls this directly

Calls 10

client_ipFunction · 0.85
internal_errorFunction · 0.85
bearer_tokenFunction · 0.85
issue_tokenFunction · 0.85
cloneMethod · 0.80
current_time_millisFunction · 0.70
getMethod · 0.45
server_token_hashMethod · 0.45
registerMethod · 0.45
set_token_hashMethod · 0.45

Tested by

no test coverage detected