link_header 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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