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 +1 -1
- data/README.rdoc +15 -0
- data/lib/link_header.rb +88 -13
- data/test/test_link_header.rb +5 -0
- metadata +2 -2
data/History.txt
CHANGED
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
|
-
|
8
|
+
# rubygem version
|
9
|
+
VERSION = "0.0.4"
|
5
10
|
|
6
|
-
#
|
11
|
+
# An array of Link objects
|
7
12
|
attr_reader :links
|
8
13
|
|
9
14
|
#
|
10
|
-
# Initialize from
|
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
|
-
|
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 = / *< *([^>]*) *> *;? */
|
37
|
-
TOKEN = /([^()<>@,;:\"\[\]?={}\s]+)/
|
38
|
-
QUOTED = /"((?:[^"\\]|\\.)*)"/
|
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
|
-
#
|
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
|
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
|
data/test/test_link_header.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2009-07-27 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|