link_header 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt CHANGED
@@ -1,3 +1,7 @@
1
+ == 0.0.3 2009-07-24
2
+
3
+ * FFC-compliant parsing and formatting; add example.rb
4
+
1
5
  == 0.0.2 2009-07-23
2
6
 
3
7
  * Fix installation instructions
data/Manifest.txt CHANGED
@@ -4,6 +4,7 @@ Manifest.txt
4
4
  PostInstall.txt
5
5
  README.rdoc
6
6
  Rakefile
7
+ example.rb
7
8
  lib/link_header.rb
8
9
  script/console
9
10
  script/destroy
data/example.rb ADDED
@@ -0,0 +1,36 @@
1
+ require "link_header"
2
+ require "pp"
3
+
4
+ #
5
+ # Create a LinkHeader with Link objects
6
+ #
7
+ link_header = LinkHeader.new([
8
+ LinkHeader::Link.new("http://example.com/foo", [["rel", "self"]]),
9
+ LinkHeader::Link.new("http://example.com/", [["rel", "up"]])])
10
+
11
+ puts link_header.to_s
12
+ #=> <http://example.com/foo>; rel="self", <http://example.com/>; rel="up"
13
+
14
+ link_header.links.map do |link|
15
+ puts "href #{link.href.inspect}, attr_pairs #{link.attr_pairs.inspect}, attrs #{link.attrs.inspect}"
16
+ end
17
+ #=> href "http://example.com/foo", attr_pairs [["rel", "self"]], attrs {"rel"=>"self"}
18
+ # href "http://example.com/", attr_pairs [["rel", "up"]], attrs {"rel"=>"up"}
19
+
20
+ #
21
+ # Create a LinkHeader from raw (JSON-friendly) data
22
+ #
23
+ puts LinkHeader.new([
24
+ ["http://example.com/foo", [["rel", "self"]]],
25
+ ["http://example.com/", [["rel", "up"]]]]).to_s
26
+ #=> <http://example.com/foo>; rel="self", <http://example.com/>; rel="up"
27
+
28
+ #
29
+ # Parse a link header into a LinkHeader object then produce its raw data representation
30
+ #
31
+ pp LinkHeader.parse('<http://example.com/foo>; rel="self", <http://example.com/>; rel = "up"').to_a
32
+ #=> [["http://example.com/foo", [["rel", "self"]]],
33
+ # ["http://example.com/", [["rel", "up"]]]]
34
+
35
+
36
+
data/lib/link_header.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require "strscan"
2
2
 
3
3
  class LinkHeader
4
- VERSION = "0.0.2"
4
+ VERSION = "0.0.3"
5
5
 
6
6
  # an array of Link objects
7
7
  attr_reader :links
@@ -27,9 +27,15 @@ class LinkHeader
27
27
  links.join(', ')
28
28
  end
29
29
 
30
- HREF = / *<([^>]*)> *;? */
31
- TOKEN = /([a-zA-Z0-9_\-]+)/
32
- QUOTED = /"([^"]*)"/
30
+ #
31
+ # Regexes for link header parsing. TOKEN and QUOTED in particular should conform to RFC2616.
32
+ #
33
+ # Acknowledgement: The QUOTED regexp is based on
34
+ # http://stackoverflow.com/questions/249791/regexp-for-quoted-string-with-escaping-quotes/249937#249937
35
+ #
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
33
39
  ATTR = /#{TOKEN} *= *(#{TOKEN}|#{QUOTED}) */
34
40
  SEMI = /; */
35
41
  COMMA = /, */
@@ -46,7 +52,8 @@ class LinkHeader
46
52
  href = scanner[1]
47
53
  attrs = []
48
54
  while scanner.scan(ATTR)
49
- attrs.push([scanner[1], scanner[3] || scanner[4]])
55
+ attr_name, token, quoted = scanner[1], scanner[3], scanner[4].gsub(/\\"/, '"')
56
+ attrs.push([attr_name, token || quoted])
50
57
  break unless scanner.scan(SEMI)
51
58
  end
52
59
  links.push(Link.new(href, attrs))
@@ -98,7 +105,7 @@ class LinkHeader
98
105
  # Convert to string representation as per the link header spec
99
106
  #
100
107
  def to_s
101
- (["<#{href}>"] + attr_pairs.map{|k, v| "#{k}=\"#{v}\""}).join('; ')
108
+ (["<#{href}>"] + attr_pairs.map{|k, v| "#{k}=\"#{v.gsub(/"/, '\"')}\""}).join('; ')
102
109
  end
103
110
  end
104
111
  end
@@ -1,9 +1,9 @@
1
1
  require "test/unit"
2
2
 
3
3
  LINK_HEADER_S_A = [
4
- %Q(<http://example.com/>; rel="up"; meta="bar"),
5
- %Q(<http://example.com/foo>; rel="self"),
6
- %Q(<http://example.com/>)
4
+ '<http://example.com/>; rel="up"; meta="bar"',
5
+ '<http://example.com/foo>; rel="self"',
6
+ '<http://example.com/>'
7
7
  ]
8
8
  LINK_HEADER_S = LINK_HEADER_S_A.join(', ')
9
9
 
@@ -49,4 +49,16 @@ class TestLinkHeader < Test::Unit::TestCase
49
49
  def test_link_header_to_s
50
50
  assert_equal(LINK_HEADER_S, LinkHeader.new(LINK_HEADER_A).to_s)
51
51
  end
52
+
53
+ def test_parse_href
54
+ assert_equal("any old stuff!", LinkHeader.parse('<any old stuff!>').links[0].href)
55
+ end
56
+
57
+ def test_parse_attribute
58
+ assert_equal(['a-token', 'escaped "'], LinkHeader.parse('<any old stuff!> ;a-token="escaped \""').links[0].attr_pairs[0])
59
+ end
60
+
61
+ def test_format_attribute
62
+ assert_equal('<any old stuff!>; a-token="escaped \""', LinkHeader.new([['any old stuff!', [['a-token', 'escaped "']]]]).to_s)
63
+ end
52
64
  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.2
4
+ version: 0.0.3
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-23 00:00:00 +02:00
12
+ date: 2009-07-24 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -50,6 +50,7 @@ files:
50
50
  - PostInstall.txt
51
51
  - README.rdoc
52
52
  - Rakefile
53
+ - example.rb
53
54
  - lib/link_header.rb
54
55
  - script/console
55
56
  - script/destroy