class Hoodoo::Client::Headers
Hoodoo::Client
and related software such as Hoodoo::Services::Middleware
need common access to information about special processing headers defined by Hoodoo
and the Hoodoo
API. This class is just a container - pretty much a namespaced library - holding that kind of information and support methods.
Constants
- BOOLEAN_HEADER_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called withtrue
orfalse
evaluates to String “yes” fortrue
or “no” for any other value.- BOOLEAN_PROPERTY_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with some non-nil value from an HTTP header representing a Boolean as “yes” or “no”, evaluates to eithertrue
for “yes” orfalse
for any other value. Case insensitive.- DATETIME_HEADER_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with a DateTime instance evaluates to a String representing the DateTime as an ISO 8601 subset value given to nanosecond precision.- DATETIME_IN_PAST_ONLY_PROPERTY_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with some non-nil value from an HTTP header representing a Date/Time in a supported format, evaluates to either a parsed DateTime instance ornil
if the value appeared to not be in a supported format.- DATETIME_WRITER_PROC
Used by
HEADER_TO_PROPERTY
; this Proc is called with a Time, Date, DateTime or DateTime-parseable String and returns a DateTime. It is used for a custom write accessor for the property associated with a header entry and works independently of the validation mechanism for inbound String-only from-header data.- HEADER_TO_PROPERTY
Various “X-Foo”-style HTTP headers specified in the
Hoodoo
API Specification have special meanings and values for those need to be set up in request data andHoodoo::Client
endpoints. Processing around these is data driven by this mapping Hash.Keys are the HTTP header names in
Rack
(upper case, “HTTP_”-prefix) format. Values are options bundles as follows:property
-
The property name to be associated with the header, as a Symbol.
property_proc
-
A Proc that’s called to both validate and clean up the raw value from the HTTP header. It evaluates to
nil
if the value is invalid, or non-nil
for any other case. Note that there is no way for an HTTP header to explicitly convey a corresponding value internally ofnil
as a result, by design; instead the relevant header would simply be omitted by the caller (and/or change your header design!). writer_proc
-
If a property has a possible amigbuity of input data types when set externally, independently of any validation etc. from the
property_proc
option, then this optional entry contains a Proc that is used for a custom write accessor and canonicalises assumed-valid but possibly not canonical input for writing. An example would be the conversion of String or Time instances to a DateTime so that a property always reads back with a DateTime instance. header
-
For speed in lookups where it’s needed, this is the “real” (not
Rack
format) HTTP header name. header_proc
-
A Proc that’s called to convert a cleaned-up value set in the
property
by itsproperty_proc
. It is called with this value and returns an equivalent appropriate value for use with the HTTP header given inheader
. This MUST always be a String. secured
-
Optional, default
nil
. Iftrue
, marks that this header and its associated value can only be processed if there is a Session with a Caller that has anauthorised_http_headers
entry for this header. auto_transfer
-
Optional, default
nil
. Only relevant to inter-resource call scenarios. Iftrue
, when one resource calls another, the value of this property is automatically transferred to the downstream resource. Otherwise, it is not, and the downstream resource will operate under whatever defaults are present. An inter-resource call endpoint which inherits an auto-transfer property can always have this property explicitly overwritten before any calls are made through it.
An additional key of
:property_writer
will be set up automatically which contains the value of the:property
key with an “=” sign added, resulting in the name of a write accessor method for that property.- KVP_HEADER_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with some non-nested Hash evaluates to a URL-encoded form data String as per:- KVP_PROPERTY_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with some non-nil value from an HTTP header containing URL-encoded simple key/value pair data returns a decoded Hash of key/value pairs. Use URL encoding in the HTTP header value as per:www.w3.org/TR/html5/forms.html#url-encoded-form-data
Invalid input will produce unusual results, e.g. an empty Hash or a Hash where certain keys may have empty string values.
- UUID_HEADER_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with someUUID
evaluates to the input value coerced to a String and no other changes.- UUID_PROPERTY_PROC
Used by
HEADER_TO_PROPERTY
; this Proc when called with some non-nil value from an HTTP header representing aUUID
, evaluates to either theUUID
as a String ornil
if the value appeared to not be aUUID
.
Public Class Methods
Define a series of read and custom write accessors according to the HTTP_HEADER_OPTIONS_MAP. For example, a property of “dated_at” results in a dated_at
reader, a dated_at=
writer which calls Hoodoo::Utilities.rationalise_datetime
to clean up the input value and sets the result into the @dated_at
instance variable which the read accessor will be expecting to use.
klass
-
The Class to which the instance methods will be added.
# File lib/hoodoo/client/headers.rb, line 240 def self.define_accessors_for_header_equivalents( klass ) klass.class_eval do HEADER_TO_PROPERTY.each do | rack_header, description | attr_reader( description[ :property ] ) custom_writer = description[ :writer_proc ] if custom_writer.nil? attr_writer( description[ :property ] ) else define_method( "#{ description[ :property ] }=" ) do | parameter | instance_variable_set( "@#{ description[ :property ] }", description[ :writer_proc ].call( parameter ) ) result = instance_variable_get("@#{ description[ :property ] }") end end end end end
From a Hash-like source where keys are HTTP header names and values are the corresponding HTTP header values, extract interesting values and return a Hash of options as described below.
Any X-Foo
header is extracted, including core Hoodoo
extension headers such as X-Interaction-ID
, which is present in any response. The “X-” is stripped, the rest converted to lower case and hyphens converted to underscores. The interaction ID, therefore, would be set as an interaction_id
option. X-Foo
would be set as a foo
option - and so-on.
The header matcher accepts headers from the Hash-like source in upper or lower case with hyphens or underscores inside; extracted headers can therefore start with any of X_
, x_
, X-
or x-
. The Hash-like source must support the each
operator yielding a key and value to the block on each iteration.
Header values are not translated at all, so (unless something very unsual is going on) the option values will be Strings.
If the same header is encountered more than once, only the first one encountered (in enumeration order, whatever that might be) is stored.
Parameters:
hashlike_source
-
Hash-like source containing HTTP headers/values.
# File lib/hoodoo/client/headers.rb, line 289 def self.x_header_to_options( hashlike_source ) hashlike_source ||= {} options = {} hashlike_source.each do | key, value | next unless ( key[ 0 ] == 'x' || key[ 0 ] == 'X' ) && ( key[ 1 ] == '-' || key[ 1 ] == '_' ) entry = key.to_s.downcase.gsub( '-', '_' )[ 2..-1 ] unless entry == '' || options.has_key?( entry ) options[ entry ] = value end end return options end