httpclient_link_header 0.0.1

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.
@@ -0,0 +1,77 @@
1
+ require 'httpclient'
2
+
3
+ module HTTP
4
+ class LinkHeaders
5
+ PARAM_REG = /(\w+)=['"](\w+)['"]/
6
+ LINK_REG = /<(.+)>((?:; \w+=['"]\w+['"])*)/
7
+
8
+ def self.parse(link_headers)
9
+ unless link_headers.empty?
10
+ new(parse_link_headers(link_headers))
11
+ end
12
+ end
13
+
14
+ def self.generate(links)
15
+ links.map do |link|
16
+ params = (link['params'] || []).map { |key, value| "; #{key}=\"#{value}\"" }.join
17
+ "<#{link['uri']}>#{params}"
18
+ end
19
+ end
20
+
21
+ def initialize(parsed_headers)
22
+ @parsed_headers = parsed_headers
23
+ end
24
+
25
+ def by(param)
26
+ index_by(param, @parsed_headers)
27
+ end
28
+
29
+ private
30
+
31
+ def self.parse_link_header(link_header)
32
+ parsed = {}
33
+ match = LINK_REG.match(link_header)
34
+ uri, params = match.captures
35
+ parsed['uri'] = uri
36
+ params_split = params.split(";").reject(&:empty?).map(&:strip)
37
+ parsed['params'] = params_split.inject({}) do |pout, param|
38
+ param_match = PARAM_REG.match(param)
39
+ key, value = param_match.captures
40
+ pout[key] = value
41
+ pout
42
+ end
43
+ parsed
44
+ end
45
+
46
+ def self.parse_link_headers(link_headers)
47
+ link_headers.map { |lh| parse_link_header(lh) }
48
+ end
49
+
50
+ def index_by(param, parsed_headers)
51
+ parsed_headers.inject({}) do |index, header|
52
+ param_value = header['params'][param]
53
+ if param_value
54
+ unless index.has_key?(param_value)
55
+ index[param_value] = []
56
+ end
57
+ index[param_value] << header
58
+ end
59
+ index
60
+ end
61
+ end
62
+ end
63
+
64
+ module MLinkHeaders
65
+ LINK_HEADER = "Link"
66
+
67
+ def links
68
+ LinkHeaders.parse(header[LINK_HEADER])
69
+ end
70
+
71
+ def links=(links)
72
+ header.set(LINK_HEADER, LinkHeaders.generate(links))
73
+ end
74
+ end
75
+ end
76
+
77
+ HTTP::Message.send(:include, HTTP::MLinkHeaders)
@@ -0,0 +1,36 @@
1
+ require 'test/unit'
2
+ require 'httpclient_link_header'
3
+ require 'httpclient'
4
+
5
+ class TestLinkHeader < Test::Unit::TestCase
6
+ def test_link_header_parsing
7
+ expected = "compact.css"
8
+ resp = HTTP::Message.new_response(nil)
9
+ resp.header['Link'] = '<compact.css>; rel="stylesheet"; title="hello"'
10
+
11
+ assert_equal(expected, resp.links.by('rel').fetch('stylesheet').first['uri'])
12
+ assert_equal(expected, resp.links.by('title').fetch('hello').first['uri'])
13
+ end
14
+
15
+ def test_link_header_parsing_with_no_links
16
+ resp = HTTP::Message.new_response(nil)
17
+
18
+ assert_equal(nil, resp.links)
19
+ end
20
+
21
+ def test_link_header_generation
22
+ with_params = '<compact.css>; rel="stylesheet"; title="hello"'
23
+ without_params = '<compact.css>'
24
+
25
+ resp = HTTP::Message.new_request('GET', '/')
26
+ resp.links = [
27
+ {'uri' => 'compact.css', 'params' => {'rel' => 'stylesheet', 'title' => 'hello'}},
28
+ {'uri' => 'compact.css'}
29
+ ]
30
+ links = resp.header['Link']
31
+
32
+ assert_equal(2, links.size)
33
+ assert_equal(with_params, links[0])
34
+ assert_equal(without_params, links[1])
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: httpclient_link_header
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - TempoDB, Inc.
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-03-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: httpclient
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Parse and process W3C compliant Link headers within HTTPClient (http://www.w3.org/Protocols/9707-link-header.html)
31
+ email: software@tempo-db.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/httpclient_link_header.rb
37
+ - test/test_httpclient_link_header.rb
38
+ homepage: http://tempo-db.com
39
+ licenses: []
40
+ post_install_message:
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ requirements: []
57
+ rubyforge_project:
58
+ rubygems_version: 1.8.25
59
+ signing_key:
60
+ specification_version: 3
61
+ summary: HTTPClient Link Header Parser
62
+ test_files:
63
+ - test/test_httpclient_link_header.rb