link_header 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  == 0.0.3 2009-07-24
2
2
 
3
- * FFC-compliant parsing and formatting; add example.rb
3
+ * RFC-compliant parsing and formatting; add example.rb
4
4
 
5
5
  == 0.0.2 2009-07-23
6
6
 
data/README.rdoc CHANGED
@@ -9,6 +9,21 @@ Converts conforming link headers to and from text, LinkHeader objects and corres
9
9
  == Installation
10
10
 
11
11
  sudo gem install link_header
12
+
13
+ == Usage
14
+
15
+ require "link_header"
16
+
17
+ LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
18
+ #=> [["http://example.com/foo", [["rel", "self"]]],
19
+ ["http://example.com/", [["rel", "up"]]]]
20
+
21
+ LinkHeader.new([
22
+ ["http://example.com/foo", [["rel", "self"]]],
23
+ ["http://example.com/", [["rel", "up"]]]]).to_s
24
+ #=> '<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"'
25
+
26
+ For more information see the LinkHeader and LinkHeader::Link classes (both defined in lib/link_header.rb).
12
27
 
13
28
  == Author
14
29
 
data/lib/link_header.rb CHANGED
@@ -1,21 +1,48 @@
1
1
  require "strscan"
2
2
 
3
+ #
4
+ # Represents an HTTP link header of the form described in the draft spec http://tools.ietf.org/id/draft-nottingham-http-link-header-06.txt.
5
+ # It is simply a list of LinkHeader::Link objects and some conversion functions.
6
+ #
3
7
  class LinkHeader
4
- VERSION = "0.0.3"
8
+ # rubygem version
9
+ VERSION = "0.0.4"
5
10
 
6
- # an array of Link objects
11
+ # An array of Link objects
7
12
  attr_reader :links
8
13
 
9
14
  #
10
- # Initialize from array of Link objects or the data from which said Link objects can be created
15
+ # Initialize from a collection of either LinkHeader::Link objects or data from which Link objects can be created.
16
+ #
17
+ # From a list of LinkHeader::Link objects:
18
+ #
19
+ # LinkHeader.new([
20
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]),
21
+ # LinkHeader::Link.new("http://example.com/", [["rel", "up"]])])
22
+ #
23
+ # From the equivalent JSON-friendly raw data:
24
+ #
25
+ # LinkHeader.new([
26
+ # ["http://example.com/foo", [["rel", "self"]]],
27
+ # ["http://example.com/", [["rel", "up"]]]]).to_s
28
+ #
29
+ # See also LinkHeader.parse
11
30
  #
12
31
  def initialize(links=[])
13
- @links= links.map{|l| l.kind_of?(Link) ? l : Link.new(*l)}
32
+ if links
33
+ @links = links.map{|l| l.kind_of?(Link) ? l : Link.new(*l)}
34
+ else
35
+ @links = []
36
+ end
14
37
  end
15
38
 
16
39
  #
17
40
  # Convert to a JSON-friendly array
18
41
  #
42
+ # LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
43
+ # #=> [["http://example.com/foo", [["rel", "self"]]],
44
+ # ["http://example.com/", [["rel", "up"]]]]
45
+ #
19
46
  def to_a
20
47
  links.map{|l| l.to_a}
21
48
  end
@@ -23,6 +50,11 @@ class LinkHeader
23
50
  #
24
51
  # Convert to string representation as per the link header spec
25
52
  #
53
+ # LinkHeader.new([
54
+ # ["http://example.com/foo", [["rel", "self"]]],
55
+ # ["http://example.com/", [["rel", "up"]]]]).to_s
56
+ # #=> '<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"'
57
+ #
26
58
  def to_s
27
59
  links.join(', ')
28
60
  end
@@ -33,16 +65,20 @@ class LinkHeader
33
65
  # Acknowledgement: The QUOTED regexp is based on
34
66
  # http://stackoverflow.com/questions/249791/regexp-for-quoted-string-with-escaping-quotes/249937#249937
35
67
  #
36
- HREF = / *< *([^>]*) *> *;? */ # note: no attempt to check URI validity
37
- TOKEN = /([^()<>@,;:\"\[\]?={}\s]+)/ # non-empty sequence of non-separator characters
38
- QUOTED = /"((?:[^"\\]|\\.)*)"/ # double-quoted strings with backslash-escaped double quotes
39
- ATTR = /#{TOKEN} *= *(#{TOKEN}|#{QUOTED}) */
40
- SEMI = /; */
41
- COMMA = /, */
68
+ HREF = / *< *([^>]*) *> *;? */ #:nodoc: note: no attempt to check URI validity
69
+ TOKEN = /([^()<>@,;:\"\[\]?={}\s]+)/ #:nodoc: non-empty sequence of non-separator characters
70
+ QUOTED = /"((?:[^"\\]|\\.)*)"/ #:nodoc: double-quoted strings with backslash-escaped double quotes
71
+ ATTR = /#{TOKEN} *= *(#{TOKEN}|#{QUOTED}) */ #:nodoc:
72
+ SEMI = /; */ #:nodoc:
73
+ COMMA = /, */ #:nodoc:
42
74
 
43
75
  #
44
76
  # Parse a link header, returning a new LinkHeader object
45
77
  #
78
+ # LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
79
+ # #=> [["http://example.com/foo", [["rel", "self"]]],
80
+ # ["http://example.com/", [["rel", "up"]]]]
81
+ #
46
82
  def self.parse(link_header)
47
83
  return new unless link_header
48
84
 
@@ -62,20 +98,44 @@ class LinkHeader
62
98
 
63
99
  new(links)
64
100
  end
65
-
101
+
102
+ def find_link(*attr_pairs)
103
+ links.detect do |link|
104
+ !attr_pairs.detect do |pair|
105
+ !link.attr_pairs.include?(pair)
106
+ end
107
+ end
108
+ end
109
+
66
110
  #
67
111
  # Represents a link - an href and a list of attributes (key value pairs)
68
112
  #
113
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]).to_s
114
+ # => '<http://example.com/foo>; rel="self"'
115
+ #
69
116
  class Link
70
- # The Link's href (a URI string)
117
+ #
118
+ # The link's URI string
119
+ #
120
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]).href
121
+ # => 'http://example.com/foo>'
122
+ #
71
123
  attr_reader :href
72
124
 
125
+ #
73
126
  # The link's attributes, an array of key-value pairs
127
+ #
128
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"], ["rel", "canonical"]]).attr_pairs
129
+ # => [["rel", "self"], ["rel", "canonical"]]
130
+ #
74
131
  attr_reader :attr_pairs
75
132
 
76
133
  #
77
134
  # Initialize a Link from an href and attribute list
78
135
  #
136
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]).to_s
137
+ # => '<http://example.com/foo>; rel="self"'
138
+ #
79
139
  def initialize(href, attr_pairs)
80
140
  @href, @attr_pairs = href, attr_pairs
81
141
  end
@@ -83,12 +143,17 @@ class LinkHeader
83
143
  #
84
144
  # Lazily convert the attribute list to a Hash
85
145
  #
146
+ # Beware repeated attribute names (it's safer to use #attr_pairs if this is risk):
147
+ #
148
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"], ["rel", "canonical"]]).attrs
149
+ # => {"rel" =>"canonical"}
150
+ #
86
151
  def attrs
87
152
  @attrs ||= Hash[*attr_pairs.flatten]
88
153
  end
89
154
 
90
155
  #
91
- # Access an attribute by key
156
+ # Access #attrs by key
92
157
  #
93
158
  def [](key)
94
159
  attrs[key]
@@ -97,13 +162,23 @@ class LinkHeader
97
162
  #
98
163
  # Convert to a JSON-friendly Array
99
164
  #
165
+ # LinkHeader::Link.new("http://example.com/foo", [["rel", "self"], ["rel", "canonical"]]).to_a
166
+ # => ["http://example.com/foo", [["rel", "self"], ["rel", "canonical"]]]
167
+ #
100
168
  def to_a
101
169
  [href, attr_pairs]
102
170
  end
103
171
 
172
+ #
173
+ # Convert to string representation as per the link header spec. This includes backspace-escaping doublequote characters in
174
+ # quoted attribute values.
175
+ #
104
176
  #
105
177
  # Convert to string representation as per the link header spec
106
178
  #
179
+ # LinkHeader::Link.new(["http://example.com/foo", [["rel", "self"]]]).to_s
180
+ # #=> '<http://example.com/foo>; rel="self"'
181
+ #
107
182
  def to_s
108
183
  (["<#{href}>"] + attr_pairs.map{|k, v| "#{k}=\"#{v.gsub(/"/, '\"')}\""}).join('; ')
109
184
  end
@@ -61,4 +61,9 @@ class TestLinkHeader < Test::Unit::TestCase
61
61
  def test_format_attribute
62
62
  assert_equal('<any old stuff!>; a-token="escaped \""', LinkHeader.new([['any old stuff!', [['a-token', 'escaped "']]]]).to_s)
63
63
  end
64
+
65
+ def test_find_link
66
+ link_header = LinkHeader.new(LINK_HEADER_A)
67
+ assert_equal([["rel", "self"]], link_header.find_link(["rel", "self"]).attr_pairs)
68
+ end
64
69
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: link_header
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mike Burrows
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-24 00:00:00 +02:00
12
+ date: 2009-07-27 00:00:00 +01:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency