Class: LinkHeader

Inherits:
Object
  • Object
show all
Defined in:
lib/govdelivery/tms/link_header.rb

Overview

Represents an HTTP link header of the form described in the draft spec tools.ietf.org/id/draft-nottingham-http-link-header-06.txt. It is simply a list of LinkHeader::Link objects and some conversion functions.

Defined Under Namespace

Classes: Link

Constant Summary collapse

HREF =

Regexes for link header parsing. TOKEN and QUOTED in particular should conform to RFC2616.

Acknowledgement: The QUOTED regexp is based on stackoverflow.com/questions/249791/regexp-for-quoted-string-with-escaping-quotes/249937#249937

/ *< *([^>]*) *> *;? */
TOKEN =

:nodoc: non-empty sequence of non-separator characters

/([^()<>@,;:\"\[\]?={}\s]+)/
QUOTED =

:nodoc: double-quoted strings with backslash-escaped double quotes

/"((?:[^"\\]|\\.)*)"/
ATTR =

:nodoc:

/#{TOKEN} *= *(#{TOKEN}|#{QUOTED}) */
SEMI =

:nodoc:

/; */
COMMA =

:nodoc:

/, */

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(links = []) ⇒ LinkHeader

Initialize from a collection of either LinkHeader::Link objects or data from which Link objects can be created.

From a list of LinkHeader::Link objects:

LinkHeader.new([
  LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]),
  LinkHeader::Link.new("http://example.com/",    [["rel", "up"]])])

From the equivalent JSON-friendly raw data:

LinkHeader.new([
  ["http://example.com/foo", [["rel", "self"]]],
  ["http://example.com/",    [["rel", "up"]]]]).to_s

See also LinkHeader.parse



49
50
51
52
53
54
55
# File 'lib/govdelivery/tms/link_header.rb', line 49

def initialize(links = [])
  if links
    @links = links.map { |l| l.is_a?(Link) ? l : Link.new(*l) }
  else
    @links = []
  end
end

Instance Attribute Details

An array of Link objects



30
31
32
# File 'lib/govdelivery/tms/link_header.rb', line 30

def links
  @links
end

Class Method Details

.parse(link_header) ⇒ Object

Parse a link header, returning a new LinkHeader object

LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
#=> [["http://example.com/foo", [["rel", "self"]]],
     ["http://example.com/", [["rel", "up"]]]]


100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/govdelivery/tms/link_header.rb', line 100

def self.parse(link_header)
  return new unless link_header

  scanner = StringScanner.new(link_header)
  links = []
  while scanner.scan(HREF)
    href = scanner[1]
    attrs = []
    while scanner.scan(ATTR)
      attr_name, token, quoted = scanner[1], scanner[3], scanner[4].gsub(/\\"/, '"')
      attrs.push([attr_name, token || quoted])
      break unless scanner.scan(SEMI)
    end
    links.push(Link.new(href, attrs))
    break unless scanner.scan(COMMA)
  end

  new(links)
end

Instance Method Details

Find a member link that has the given attributes



123
124
125
126
127
128
129
# File 'lib/govdelivery/tms/link_header.rb', line 123

def find_link(*attr_pairs)
  links.detect do |link|
    !attr_pairs.detect do |pair|
      !link.attr_pairs.include?(pair)
    end
  end
end

#to_aObject

Convert to a JSON-friendly array

LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
#=> [["http://example.com/foo", [["rel", "self"]]],
     ["http://example.com/", [["rel", "up"]]]]


64
65
66
# File 'lib/govdelivery/tms/link_header.rb', line 64

def to_a
  links.map(&:to_a)
end

#to_html(separator = "\n") ⇒ Object

Render as a list of HTML link elements



134
135
136
# File 'lib/govdelivery/tms/link_header.rb', line 134

def to_html(separator = "\n")
  links.map(&:to_html).join(separator)
end

#to_sObject

Convert to string representation as per the link header spec

LinkHeader.new([
  ["http://example.com/foo", [["rel", "self"]]],
  ["http://example.com/",    [["rel", "up"]]]]).to_s
#=> '<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"'


76
77
78
# File 'lib/govdelivery/tms/link_header.rb', line 76

def to_s
  links.join(', ')
end