Class: Rbkb::Http::Headers
- Inherits:
-
Array
- Object
- Array
- Rbkb::Http::Headers
- Includes:
- CommonInterface
- Defined in:
- lib/rbkb/http/headers.rb
Overview
A base class for RequestHeaders and ResponseHeaders
Includes common implementations of to_raw, to_raw_array, capture, and the class method parse
The Headers array are stored internally as an named value pairs array.
The headers are generally name/value pairs in the form of:
[ ["Name1", "value1"], ["Name2", "value2"], ... ]
Which will be rendered with to_raw() to (or captured with capture() from):
Name1: value1
Name2: value2
...
This has the benefit of letting the data= accessor automatically render a Hash or any other Enumerable to a Headers object through the use of to_a. However it has the caveat that named pairs are expected on various operations.
Instance Attribute Summary collapse
-
#base ⇒ Object
Returns the value of attribute base.
Class Method Summary collapse
-
.parse(str) ⇒ Object
Instantiates a new Headers object and returns the result of capture(str) Note, this method does not distinguish between ResponseHeaders or RequestHeaders, and so the object may need to be extended with one or the other, if you need access to specific behviors from either.
-
.parse_full_headers(str, first_obj) ⇒ Object
Instantiates a new Headers object and returns the result of capture_full_headers(str, first_obj).
-
.request_hdr(*args) ⇒ Object
Class method to instantiate a new RequestHeaders object.
-
.response_hdr(*args) ⇒ Object
Class method to instantiate a new ResponseHeaders object.
Instance Method Summary collapse
-
#capture(str) {|_self, heads| ... } ⇒ Object
Captures a raw string of headers into this instance’s internal array.
-
#capture_complete? ⇒ Boolean
Indicates whether this object is ready to capture fresh data, or is waiting for additional data or a reset from a previous incomplete or otherwise broken capture.
-
#capture_full_headers(str, first_obj = nil) ⇒ Object
This method parses a full set of raw headers from the ‘str’ argument.
-
#data ⇒ Object
The data method provides a common interface to access internal non-raw information stored in the object.
-
#data=(d) ⇒ Object
The data= method provides a common interface to access internal non-raw information stored in the object.
- #delete_header(k) ⇒ Object
- #get_all(k) ⇒ Object
- #get_all_values_for(k) ⇒ Object (also: #all_values_for)
-
#get_first_obj ⇒ Object
See capture_full_headers.
- #get_header(k) ⇒ Object
-
#get_parameterized_value(k) ⇒ Object
(also: #parameterized_value)
returns a header value after “fully” parsing it.
- #get_value_for(k) ⇒ Object (also: #get_header_value, #value_for)
-
#initialize(*args) ⇒ Headers
constructor
Instantiates a new Headers object.
-
#reset_capture ⇒ Object
This method will non-destructively reset the capture state on this object.
-
#reset_capture! ⇒ Object
This method will destructively reset the capture state on this object.
- #set_header(k, v) ⇒ Object (also: #set_all_for)
- #set_parameterized_value(k, v) ⇒ Object
-
#to_raw ⇒ Object
The to_raw method returns a raw string of headers as they appear on the wire.
-
#to_raw_array ⇒ Object
The to_raw_array method returns an interim formatted array of raw “Cookie: Value” strings.
Methods included from CommonInterface
Constructor Details
#initialize(*args) ⇒ Headers
Instantiates a new Headers object.
Arguments:
raw: String or Enumerable. Strings are parsed with capture.
Enumerables are converted with 'to_a' and stored directly.
opts: Options which affect the behavior of the Headers object.
(none currently defined)
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/rbkb/http/headers.rb', line 62 def initialize(*args) super() if args.first.kind_of? Enumerable raw=args.first args[0]=nil _common_init(*args) self.data = raw.to_a else _common_init(*args) end end |
Instance Attribute Details
#base ⇒ Object
Returns the value of attribute base.
74 75 76 |
# File 'lib/rbkb/http/headers.rb', line 74 def base @base end |
Class Method Details
.parse(str) ⇒ Object
Instantiates a new Headers object and returns the result of capture(str) Note, this method does not distinguish between ResponseHeaders or RequestHeaders, and so the object may need to be extended with one or the other, if you need access to specific behviors from either.
43 44 45 |
# File 'lib/rbkb/http/headers.rb', line 43 def self.parse(str) new().capture(str) end |
.parse_full_headers(str, first_obj) ⇒ Object
Instantiates a new Headers object and returns the result of capture_full_headers(str, first_obj)
49 50 51 |
# File 'lib/rbkb/http/headers.rb', line 49 def self.parse_full_headers(str, first_obj) new().capture_full_headers(str, first_obj) end |
.request_hdr(*args) ⇒ Object
Class method to instantiate a new RequestHeaders object
30 31 32 |
# File 'lib/rbkb/http/headers.rb', line 30 def self.request_hdr(*args) Headers.new(*args).extend(RequestHeaders) end |
.response_hdr(*args) ⇒ Object
Class method to instantiate a new ResponseHeaders object
35 36 37 |
# File 'lib/rbkb/http/headers.rb', line 35 def self.response_hdr(*args) Headers.new(*args).extend(ResponseHeaders) end |
Instance Method Details
#capture(str) {|_self, heads| ... } ⇒ Object
Captures a raw string of headers into this instance’s internal array. Note: This method expects not to include the first element such as a RequestAction or ResponseStatus. See capture_full_headers for a version that can handle this.
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/rbkb/http/headers.rb', line 202 def capture(str) raise "arg 0 must be a string" unless str.is_a?(String) heads = str.split(/\s*\r?\n/) # pass interim parsed headers to a block if given yield(self, heads) if block_given? self.replace [] if capture_complete? heads.each do |s| k,v = s.split(/\s*:\s*/, 2) self << [k,v] end return self end |
#capture_complete? ⇒ Boolean
Indicates whether this object is ready to capture fresh data, or is waiting for additional data or a reset from a previous incomplete or otherwise broken capture. See also: reset_capture, reset_capture!
265 266 267 |
# File 'lib/rbkb/http/headers.rb', line 265 def capture_complete? not @capture_state end |
#capture_full_headers(str, first_obj = nil) ⇒ Object
This method parses a full set of raw headers from the ‘str’ argument. Unlike the regular capture method, the string is expected to start with a line which will be parsed by first_obj using its own capture method. For example, first_obj would parse something like “GET / HTTP/1.1” for RequestAction or “HTTP/1.1 200 OK” for ResponseStatus. If first_obj is not defined, there will be an attempt to resolve it by calling get_first_obj which should return the appropriate type of object or raise an exception.
Returns a 2 element array containing [first_entity, headers] where first entity is the instantiated first_obj object and headers is self.
235 236 237 238 239 240 241 242 243 244 |
# File 'lib/rbkb/http/headers.rb', line 235 def capture_full_headers(str, first_obj=nil) first_obj ||= get_first_obj() {|x|} first = nil capture(str) do |this, heads| first = first_obj.capture(heads.shift) yield(heads) if block_given? end return [first, self] end |
#data ⇒ Object
The data method provides a common interface to access internal non-raw information stored in the object.
The Headers incarnation returns the internal headers array (actually self).
91 92 93 |
# File 'lib/rbkb/http/headers.rb', line 91 def data self end |
#data=(d) ⇒ Object
The data= method provides a common interface to access internal non-raw information stored in the object.
This method stores creates a shallow copy for anything but another Headers object which it references directly. A few rules are enforced:
* 1-dimensional elements will be expanded to tuples with 'nil' as the
second value.
* Names which are enumerables will be 'join()'ed, but not values.
104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/rbkb/http/headers.rb', line 104 def data=(d) if d.kind_of? Headers self.replace d else self.replace [] d.to_a.each do |k, v| k = k.to_s if k.is_a? Numeric self << [k,v] end end return self end |
#delete_header(k) ⇒ Object
188 189 190 |
# File 'lib/rbkb/http/headers.rb', line 188 def delete_header(k) self.delete_if {|h| h[0].downcase == k.downcase } end |
#get_all(k) ⇒ Object
123 124 125 |
# File 'lib/rbkb/http/headers.rb', line 123 def get_all(k) self.select {|h| h[0].downcase == k.downcase } end |
#get_all_values_for(k) ⇒ Object Also known as: all_values_for
127 128 129 |
# File 'lib/rbkb/http/headers.rb', line 127 def get_all_values_for(k) self.get_all(k).collect {|h,v| v } end |
#get_first_obj ⇒ Object
See capture_full_headers. This method is used to resolve the parser for the first entity above the HTTP headers. This instance is designed to raise an exception when capturing.
221 |
# File 'lib/rbkb/http/headers.rb', line 221 def get_first_obj; raise "get_first_obj called on base stub"; end |
#get_header(k) ⇒ Object
132 133 134 |
# File 'lib/rbkb/http/headers.rb', line 132 def get_header(k) self.find {|h| h[0].downcase == k.downcase } end |
#get_parameterized_value(k) ⇒ Object Also known as: parameterized_value
returns a header value after “fully” parsing it. Any semi-colon separated key=value or key parameters after the first value in the header will be returned as an extra HeaderParams array in addition to the value. T
XXX NOTE, the current implementation will incorrectly parse several headers that may legally contain ‘;’ with no special meaning. For example, ‘Referer: example.com;sometimes_a_url_parameter=1’
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/rbkb/http/headers.rb', line 151 def get_parameterized_value(k) if v=get_value_for(k) if i=v.index(';') val = v[0,i] parms = v[(i+1)..-1] [ val, HeaderParams.parse( parms ) ] else [ v, HeaderParams.new ] end end end |
#get_value_for(k) ⇒ Object Also known as: get_header_value, value_for
136 137 138 139 140 |
# File 'lib/rbkb/http/headers.rb', line 136 def get_value_for(k) if h=self.get_header(k) return h[1] end end |
#reset_capture ⇒ Object
This method will non-destructively reset the capture state on this object. The existing headers are maintained when this is called. See also: capture_complete? reset_capture!
249 250 251 252 |
# File 'lib/rbkb/http/headers.rb', line 249 def reset_capture @capture_state = nil self end |
#reset_capture! ⇒ Object
This method will destructively reset the capture state on this object. The existing headers array is emptied when this is called. See also: capture_complete?, reset_capture
257 258 259 260 |
# File 'lib/rbkb/http/headers.rb', line 257 def reset_capture! @capture_state = nil self.data = [] end |
#set_header(k, v) ⇒ Object Also known as: set_all_for
174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/rbkb/http/headers.rb', line 174 def set_header(k,v) sel = get_all(k) if sel.empty? self << [k,v] return [[k,v]] else sel.each {|h| h[1] = v } return sel end end |
#set_parameterized_value(k, v) ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/rbkb/http/headers.rb', line 165 def set_parameterized_value(k, v) raise "v is not an array. use set_header()" unless v.kind_of? Array parms = v[1] v = v[0].to_s v << parms.to_raw if parms set_header(k,v) end |
#to_raw ⇒ Object
The to_raw method returns a raw string of headers as they appear on the wire.
194 195 196 |
# File 'lib/rbkb/http/headers.rb', line 194 def to_raw to_raw_array.join("\r\n") << "\r\n" end |
#to_raw_array ⇒ Object
The to_raw_array method returns an interim formatted array of raw “Cookie: Value” strings.
119 120 121 |
# File 'lib/rbkb/http/headers.rb', line 119 def to_raw_array self.map {|h,v| "#{h}: #{v}" } end |