Class: Dommy::Headers
- Inherits:
-
Object
- Object
- Dommy::Headers
- Includes:
- Bridge::Methods
- Defined in:
- lib/dommy/fetch.rb
Overview
WHATWG ‘Headers`. Names are stored lowercased and compared case-insensitively; iteration (`keys`/`values`/`entries`/`forEach`) is sorted by name with duplicate values combined by “, ” (the spec’s “sort and combine” output). ‘new Headers(init)` fills from a record (Hash → set per key), a sequence (Array of `[name, value]` pairs → append), or another Headers instance.
Constant Summary collapse
- HEADER_NAME =
RFC 7230 token — a valid header name (one or more of these bytes).
/\A[!#$%&'*+\-.^_`|~0-9A-Za-z]+\z/.freeze
- HTTP_WHITESPACE =
Leading/trailing HTTP whitespace (tab or space) trimmed from a value.
/\A[\t ]+|[\t ]+\z/.freeze
Class Method Summary collapse
-
.canonical(name) ⇒ Object
RFC 7230 Title-Case form of a header name.
Instance Method Summary collapse
- #__js_call__(method, args) ⇒ Object
- #__js_get__(_key) ⇒ Object
- #__js_set__(_key, _value) ⇒ Object
-
#__raw_pairs__ ⇒ Object
Internal: a copy of the raw [name, value] pairs — lets one Headers be filled from another without losing duplicates or split Set-Cookie values.
-
#fill(init) ⇒ Object
WHATWG “fill”: a record (Hash) sets each key; a sequence (Array) appends each [name, value] pair (a non-2-element member is a TypeError); another Headers is copied pair-for-pair.
-
#initialize(init = nil) ⇒ Headers
constructor
A new instance of Headers.
-
#make_immutable! ⇒ Object
WHATWG: mark these headers immutable — the guard ‘Response.error()` / `Response.redirect()` give their headers.
-
#to_h ⇒ Object
A plain Hash of name => combined value (duplicate names combined by “, ”; Set-Cookie collapses to its combined value — use getSetCookie for the split list).
Methods included from Bridge::Methods
Constructor Details
#initialize(init = nil) ⇒ Headers
Returns a new instance of Headers.
604 605 606 607 608 |
# File 'lib/dommy/fetch.rb', line 604 def initialize(init = nil) @list = [] # ordered [lowercased name, value] pairs (duplicates allowed) @guard = :none # :none (mutable) or :immutable (Response.error/redirect) fill(init) end |
Class Method Details
.canonical(name) ⇒ Object
RFC 7230 Title-Case form of a header name. Retained as a public helper; the Headers store itself is lowercased per the WHATWG spec.
711 712 713 |
# File 'lib/dommy/fetch.rb', line 711 def self.canonical(name) name.split("-").map(&:capitalize).join("-") end |
Instance Method Details
#__js_call__(method, args) ⇒ Object
665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 |
# File 'lib/dommy/fetch.rb', line 665 def __js_call__(method, args) case method when "set" set_value(args[0], args[1]) nil when "append" append_value(args[0], args[1]) nil when "delete" ensure_mutable! name = validate_name!(args[0]) @list.reject! { |n, _| n == name } nil when "get" get_combined(validate_name!(args[0])) when "has" name = validate_name!(args[0]) @list.any? { |n, _| n == name } when "keys" sort_and_combine.map(&:first) when "values" sort_and_combine.map(&:last) when "entries" sort_and_combine when "getSetCookie" # WHATWG: Set-Cookie's individual values, in insertion order (never # combined, unlike every other header). @list.select { |n, _| n == "set-cookie" }.map(&:last) when "forEach" # WHATWG: forEach(callback) — callback(value, key, headers), in the # sort-and-combine order. `self` is the third argument so # `(_, _, h) => h.get(...)` works the same as in a browser. cb = args[0] sort_and_combine.each do |k, v| if cb.respond_to?(:__js_call__) cb.__js_call__("call", [v, k, self]) elsif cb.respond_to?(:call) cb.call(v, k, self) end end nil end end |
#__js_get__(_key) ⇒ Object
655 656 657 |
# File 'lib/dommy/fetch.rb', line 655 def __js_get__(_key) nil end |
#__js_set__(_key, _value) ⇒ Object
659 660 661 |
# File 'lib/dommy/fetch.rb', line 659 def __js_set__(_key, _value) Bridge::UNHANDLED end |
#__raw_pairs__ ⇒ Object
Internal: a copy of the raw [name, value] pairs — lets one Headers be filled from another without losing duplicates or split Set-Cookie values.
642 643 644 |
# File 'lib/dommy/fetch.rb', line 642 def __raw_pairs__ @list.map(&:dup) end |
#fill(init) ⇒ Object
WHATWG “fill”: a record (Hash) sets each key; a sequence (Array) appends each [name, value] pair (a non-2-element member is a TypeError); another Headers is copied pair-for-pair.
622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
# File 'lib/dommy/fetch.rb', line 622 def fill(init) case init when Headers init.__raw_pairs__.each { |name, value| append_value(name, value) } when Array init.each do |pair| unless pair.is_a?(Array) && pair.length == 2 raise Bridge::TypeError, "Failed to construct 'Headers': The provided value cannot be converted to a sequence of [name, value] pairs." end append_value(pair[0], pair[1]) end when Hash init.each { |name, value| set_value(name, value) } end nil end |
#make_immutable! ⇒ Object
WHATWG: mark these headers immutable — the guard ‘Response.error()` / `Response.redirect()` give their headers. Any later set/append/delete then raises a TypeError. (Other guards — request/request-no-cors/response forbidden-name filtering — are out of scope: fetch here is stubbed.)
614 615 616 617 |
# File 'lib/dommy/fetch.rb', line 614 def make_immutable! @guard = :immutable self end |
#to_h ⇒ Object
A plain Hash of name => combined value (duplicate names combined by “, ”; Set-Cookie collapses to its combined value — use getSetCookie for the split list). For callers that want a simple record.
649 650 651 652 653 |
# File 'lib/dommy/fetch.rb', line 649 def to_h sort_and_combine.each_with_object({}) do |(name, value), out| out[name] = out.key?(name) ? "#{out[name]}, #{value}" : value end end |