StatumDirectives.vala 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. using Invercargill;
  2. using Invercargill.DataStructures;
  3. using Astralis;
  4. namespace Statum {
  5. /**
  6. * Helpers for rendering Statum directive responses.
  7. */
  8. public class StatumDirectives : Object {
  9. /** The content type that distinguishes a Statum directive response. */
  10. public const string CONTENT_TYPE = "application/vnd.statum+json";
  11. /**
  12. * Builds the short-circuit response an endpoint returns when the request
  13. * carried slots the server does not have in memory: a `transmit(retry)`
  14. * per missing key (plus an `invalidate` per untrustworthy frame
  15. * signature). The client re-sends the frames to the slot post endpoint,
  16. * drops any that fail verification, then re-issues the original request.
  17. */
  18. public static HttpResult transmit_result(Lot<string> transmit_keys, Lot<string>? invalid_signatures = null) throws GLib.Error {
  19. var directives = new Series<Model.DirectiveDto>();
  20. foreach (var key in transmit_keys) {
  21. directives.add(new Model.TransmitDirectiveDto.with(key, true));
  22. }
  23. return to_result(directives, invalid_signatures);
  24. }
  25. /**
  26. * Renders a lot of directives as the JSON array response served by every
  27. * directive-returning endpoint, with the Statum content type and
  28. * `Cache-Control: no-store`.
  29. *
  30. * Any invalid frame `signature`s are appended as `invalidate` directives
  31. * so the client drops slots whose frames the server could not trust.
  32. */
  33. public static HttpResult to_result(Lot<Model.DirectiveDto> directives, Lot<string>? invalid_signatures = null) throws GLib.Error {
  34. var rendered = new Series<Model.DirectiveDto>();
  35. foreach (var directive in directives) {
  36. rendered.add(directive);
  37. }
  38. if (invalid_signatures != null) {
  39. foreach (var signature in (!)invalid_signatures) {
  40. rendered.add(new Model.InvalidateDirectiveDto.with_signature(signature));
  41. }
  42. }
  43. var json = Model.DirectiveDto.serialize_array(rendered);
  44. var result = new HttpStringResult(json.stringify());
  45. result.set_header("Content-Type", CONTENT_TYPE);
  46. result.set_header("Cache-Control", "no-store");
  47. return result;
  48. }
  49. }
  50. }