ActionEndpoint.vala 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. using Invercargill;
  2. using Invercargill.DataStructures;
  3. using Inversion;
  4. using Astralis;
  5. namespace Statum {
  6. /**
  7. * `/_statum/action/{guid}` — the single endpoint that dispatches every
  8. * Statum action.
  9. *
  10. * The GUID is resolved by {@link ActionRegistry} to the action's type; the
  11. * scoped {@link StatumAction} instance is then resolved and its
  12. * {@link StatumAction.handle_request} does the per-request work (resolve held
  13. * slots, decrypt `X-Statum-Private`, parse the form, run {@link
  14. * StatumAction.handle}, render directives). Registered for all common verbs
  15. * so an action may be authored with whichever HTTP method suits it.
  16. *
  17. * This mirrored Spry 0.1's single `ComponentEndpoint`/`PathProvider`
  18. * model; both classes were removed in Spry 0.2.
  19. */
  20. public class ActionEndpoint : Object, Endpoint {
  21. private ActionRegistry action_registry = inject<ActionRegistry>();
  22. private Inversion.Scope scope = inject<Inversion.Scope>();
  23. public async HttpResult handle_request(HttpContext http_context, RouteContext route_context) throws GLib.Error {
  24. var guid = route_context.mapped_parameters.get_or_default("guid");
  25. if (guid == null) {
  26. return new HttpStringResult("Missing action id", StatusCode.BAD_REQUEST);
  27. }
  28. var type = action_registry.resolve((!)guid);
  29. if (type == null || !((!)type).is_a(typeof(StatumAction))) {
  30. return new HttpStringResult("No such action", StatusCode.NOT_FOUND);
  31. }
  32. var action = scope.resolve_type((!)type);
  33. return yield ((StatumAction) action).handle_request(http_context, route_context);
  34. }
  35. }
  36. }