Module: SecurityBox::Rpcs
- Defined in:
- lib/security_box/configuration.rb
Overview
Validated collection of guest-callable RPC handlers (stage 6). A
handler is a name => callable pair; rpcs in a Configuration is a
frozen hash, so the value survives #with and #to_h.
Handlers execute on the host (between guest steps, inside the RPC import) and are therefore host-only state: they are excluded from #fingerprint, and a Configuration carrying Procs is not Ractor-shareable — RactorPool rejects rpcs and strips them before a config crosses a Ractor boundary.
Validation (InvalidConfiguration on any violation):
- raw is a Hash of name => handler, or an Array of one-pair hashes
(the register DSL appends one pair per c.rpc call)
- name: non-empty String, unique
- handler: anything responding to #call; it receives the
JSON-parsed request args and must return a JSON-serializable
value (non-serializable results surface as inspect strings)
- at most MAX_RPCS handlers
Constant Summary collapse
- MAX_RPCS =
64
Class Method Summary collapse
-
.normalize(raw) ⇒ Object
Validates + normalizes
rawand returns a frozen name => handler hash.
Class Method Details
.normalize(raw) ⇒ Object
Validates + normalizes raw and returns a frozen
name => handler hash.
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/security_box/configuration.rb', line 379 def normalize(raw) return {}.freeze if raw.nil? pairs = case raw when Hash then raw.entries when Array unless raw.all? { |entry| entry.is_a?(Hash) && entry.size == 1 } raise InvalidConfiguration, "rpcs must be a Hash or an Array of one-pair hashes, " \ "got #{raw.inspect[0, 80]}" end raw.flat_map(&:entries) else raise InvalidConfiguration, "rpcs must be a Hash of name => handler, got #{raw.class}" end rpcs = {} pairs.each do |name, handler| unless name.is_a?(String) && !name.empty? raise InvalidConfiguration, "rpc name must be a non-empty String, got #{name.inspect}" end unless handler.respond_to?(:call) raise InvalidConfiguration, "rpc handler for #{name.inspect} must respond to #call, " \ "got #{handler.inspect[0, 80]}" end raise InvalidConfiguration, "duplicate rpc name #{name.inspect}" if rpcs.key?(name) rpcs[name] = handler end return rpcs.freeze if rpcs.size <= MAX_RPCS raise InvalidConfiguration, "too many rpcs (#{rpcs.size}); the limit is #{MAX_RPCS}" end |