MCPcopy Create free account
hub / github.com/URLab-Sim/UnrealRoboticsLab / DispatchInternal

Method DispatchInternal

Source/URLab/Private/Bridge/RpcDispatcher.cpp:406–472  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

404}
405
406TSharedPtr<FJsonObject> FURLabRpcDispatcher::DispatchInternal(const TSharedPtr<FJsonObject>& Req)
407{
408 // Do NOT hold DispatchMutex across the handler body. Direct-mode
409 // HandleStep waits up to 5s and HandleBeginPie polls for up to 30s;
410 // holding the mutex across either wedges every other RPC.
411 if (!Req.IsValid())
412 {
413 return MakeError(TEXT("bad_request"), TEXT("Failed to parse request (json or msgpack)"));
414 }
415
416 FString Op;
417 if (!Req->TryGetStringField(TEXT("op"), Op))
418 {
419 return MakeError(TEXT("missing_op"), TEXT("Request missing 'op' field"));
420 }
421
422 // hello / meta are pre-session bootstrap endpoints.
423 if (Op.Equals(TEXT("hello")))
424 return HandleHello(Req);
425 if (Op.Equals(TEXT("meta")))
426 return HandleMeta(Req);
427
428 {
429 FScopeLock Lock(&DispatchMutex);
430 FString SessionId;
431 Req->TryGetStringField(TEXT("session_id"), SessionId);
432 if (!ValidateSession(SessionId))
433 {
434 return MakeError(TEXT("session_expired"),
435 FString::Printf(TEXT("Session id '%s' does not match active session"), *SessionId));
436 }
437 }
438
439 const TOptional<URLabOpRegistry::FOpDecl> Decl = URLabOpRegistry::FindOp(Op);
440 if (!Decl.IsSet() || !Decl->Body)
441 {
442 if (URLabOpRegistry::IsEditorOnlyOp(Op))
443 {
444 return MakeError(TEXT("not_in_editor"),
445 FString::Printf(TEXT("op '%s' is editor-only and has no registered handler"), *Op));
446 }
447 return MakeError(TEXT("unknown_op"), FString::Printf(TEXT("Unknown op '%s'"), *Op));
448 }
449
450 // RequiredFields runs before the manager-required check so malformed
451 // requests get `missing_field` regardless of PIE state.
452 for (const FString& Field : Decl->RequiredFields)
453 {
454 if (!Req->HasField(Field))
455 {
456 return MakeError(TEXT("missing_field"),
457 FString::Printf(TEXT("op '%s' missing required field '%s'"),
458 *Op, *Field));
459 }
460 }
461
462 if (Decl->Category == URLabOpRegistry::EOpCategory::ManagerRequired
463 && !OwnerMgr.IsValid())

Callers

nothing calls this directly

Calls 6

MakeErrorFunction · 0.85
ValidateSessionFunction · 0.85
FindOpFunction · 0.85
IsEditorOnlyOpFunction · 0.85
IsValidMethod · 0.80
BodyMethod · 0.80

Tested by

no test coverage detected