Class: Obxcura::Headers

Inherits:
Object
  • Object
show all
Defined in:
lib/obxcura/headers.rb

Overview

Extra HTTP headers sent with requests, as a small mutable collection.

page.headers.set("X-Token" => "abc")   # replaces the whole table
page.headers.add("Accept" => "*/*")    # merges into it
page.headers["X-Token"]                # => "abc"
page.headers.delete("X-Token")
page.headers.clear

Reached through Page#headers.

Why the state lives here

CDP is write-only about this: Network.setExtraHTTPHeaders sets the table and there is no matching getter — Obscura answers Network.getExtraHTTPHeaders with Unknown Network method. So #get reports what this object last sent, which is the only readable record that exists. Change the headers through another route — a raw Page#command, a second Headers on another page — and this object will not know.

Two measured behaviours worth knowing

The scope is the connection, not the page. The API hangs off Page because that is the only session the command works from — sent without a session it is accepted and silently does nothing — but Obscura applies one table per connection. Setting headers on one page changes them for every page on that browser, and the last write wins. Two pages cannot carry different headers.

They cover navigation only. Obscura attaches extra headers to the document and its subresources, never to requests started from script. A Page#post — or any in-page fetch/XMLHttpRequest — does not carry them, which is why #post takes its own headers argument.

Header names are case-insensitive per RFC 9110, so writing x-token after X-Token replaces it rather than sending both. Names and values are sent as strings, since that is what CDP accepts.

Instance Method Summary collapse

Constructor Details

#initialize(page) ⇒ Headers

Returns a new instance of Headers.

Parameters:

  • page (Obxcura::Page)

    the page whose session carries the command.



42
43
44
45
# File 'lib/obxcura/headers.rb', line 42

def initialize(page)
  @page = page
  @headers = {}
end

Instance Method Details

#[](name) ⇒ String?

Returns the value, or nil if unset.

Parameters:

  • name (String, Symbol)

    header name, matched case-insensitively.

Returns:

  • (String, nil)

    the value, or nil if unset.



84
85
86
87
# File 'lib/obxcura/headers.rb', line 84

def [](name)
  _, value = entry(name)
  value
end

#[]=(name, value) ⇒ Object

Set a single header, leaving the rest in place.

Parameters:

  • name (String, Symbol)

    header name.

  • value (Object)

    value, stringified.

Returns:

  • (Object)

    value, as assignment in Ruby always does.



94
95
96
97
98
# File 'lib/obxcura/headers.rb', line 94

def []=(name, value)
  store(name.to_s, value.to_s)
  apply
  value
end

#add(headers) ⇒ Hash{String=>String}

Merge headers into the current table, replacing only the names given.

Parameters:

  • headers (Hash)

    names and values.

Returns:

  • (Hash{String=>String})

    the resulting table.



69
70
71
72
# File 'lib/obxcura/headers.rb', line 69

def add(headers)
  normalize(headers).each { |name, value| store(name, value) }
  apply
end

#clearHash

Remove every header.

Returns:

  • (Hash)

    the now-empty table.



77
78
79
80
# File 'lib/obxcura/headers.rb', line 77

def clear
  @headers = {}
  apply
end

#delete(name) ⇒ String?

Remove a single header.

Parameters:

  • name (String, Symbol)

    header name, matched case-insensitively.

Returns:

  • (String, nil)

    the removed value, or nil if it was not set.



104
105
106
107
108
109
110
111
# File 'lib/obxcura/headers.rb', line 104

def delete(name)
  key, value = entry(name)
  return nil if key.nil?

  @headers.delete(key)
  apply
  value
end

#empty?Boolean

Returns whether any header is set.

Returns:

  • (Boolean)

    whether any header is set.



121
122
123
# File 'lib/obxcura/headers.rb', line 121

def empty?
  @headers.empty?
end

#getHash{String=>String} Also known as: to_h

The headers this object last sent.

Returns:

  • (Hash{String=>String})

    a copy, safe to mutate.



50
51
52
# File 'lib/obxcura/headers.rb', line 50

def get
  @headers.dup
end

#inspectString

Returns:

  • (String)


132
133
134
# File 'lib/obxcura/headers.rb', line 132

def inspect
  "#<#{self.class} #{@headers.inspect}>"
end

#key?(name) ⇒ Boolean Also known as: include?

Returns whether the header is set.

Parameters:

  • name (String, Symbol)

    header name, matched case-insensitively.

Returns:

  • (Boolean)

    whether the header is set.



115
116
117
# File 'lib/obxcura/headers.rb', line 115

def key?(name)
  !entry(name).first.nil?
end

#set(headers) ⇒ Hash{String=>String}

Replace every header with headers. Mirrors what the browser does: the table is overwritten, not merged.

Parameters:

  • headers (Hash)

    names and values, stringified on the way in.

Returns:

  • (Hash{String=>String})

    the resulting table.



60
61
62
63
# File 'lib/obxcura/headers.rb', line 60

def set(headers)
  @headers = normalize(headers)
  apply
end

#sizeInteger Also known as: length

Returns how many headers are set.

Returns:

  • (Integer)

    how many headers are set.



126
127
128
# File 'lib/obxcura/headers.rb', line 126

def size
  @headers.size
end