xenon-routing 0.0.4 → 0.0.5
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.
- checksums.yaml +4 -4
- data/{xenon-routing/lib → lib}/xenon/api.rb +20 -11
- data/{xenon-routing/lib → lib}/xenon/marshallers.rb +24 -14
- data/{xenon-routing/lib → lib}/xenon/request.rb +10 -2
- data/{xenon-routing/lib → lib}/xenon/response.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing/context.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing/directives.rb +1 -0
- data/{xenon-routing/lib → lib}/xenon/routing/header_directives.rb +0 -0
- data/lib/xenon/routing/marshalling_directives.rb +24 -0
- data/{xenon-routing/lib → lib}/xenon/routing/method_directives.rb +10 -4
- data/{xenon-routing/lib → lib}/xenon/routing/param_directives.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing/path_directives.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing/route_directives.rb +0 -0
- data/{xenon-routing/lib → lib}/xenon/routing/security_directives.rb +6 -0
- data/{xenon-routing/lib → lib}/xenon/routing_version.rb +0 -0
- data/{xenon-http/spec → spec}/spec_helper.rb +0 -0
- data/{xenon-routing/xenon-routing.gemspec → xenon-routing.gemspec} +2 -2
- metadata +25 -80
- data/.codeclimate.yml +0 -18
- data/.gitignore +0 -25
- data/.rspec +0 -3
- data/.travis.yml +0 -6
- data/Gemfile +0 -20
- data/Guardfile +0 -16
- data/LICENSE +0 -22
- data/README.md +0 -116
- data/Rakefile +0 -40
- data/VERSION +0 -1
- data/examples/hello_world/config.ru +0 -3
- data/examples/hello_world/hello_world.rb +0 -27
- data/xenon-http/lib/xenon/auth.rb +0 -63
- data/xenon-http/lib/xenon/errors.rb +0 -5
- data/xenon-http/lib/xenon/etag.rb +0 -48
- data/xenon-http/lib/xenon/headers.rb +0 -112
- data/xenon-http/lib/xenon/headers/accept.rb +0 -34
- data/xenon-http/lib/xenon/headers/accept_charset.rb +0 -59
- data/xenon-http/lib/xenon/headers/accept_encoding.rb +0 -63
- data/xenon-http/lib/xenon/headers/accept_language.rb +0 -59
- data/xenon-http/lib/xenon/headers/authorization.rb +0 -50
- data/xenon-http/lib/xenon/headers/cache_control.rb +0 -56
- data/xenon-http/lib/xenon/headers/content_type.rb +0 -23
- data/xenon-http/lib/xenon/headers/if_match.rb +0 -53
- data/xenon-http/lib/xenon/headers/if_modified_since.rb +0 -22
- data/xenon-http/lib/xenon/headers/if_none_match.rb +0 -53
- data/xenon-http/lib/xenon/headers/if_range.rb +0 -45
- data/xenon-http/lib/xenon/headers/if_unmodified_since.rb +0 -22
- data/xenon-http/lib/xenon/headers/user_agent.rb +0 -65
- data/xenon-http/lib/xenon/headers/www_authenticate.rb +0 -71
- data/xenon-http/lib/xenon/http.rb +0 -7
- data/xenon-http/lib/xenon/http_version.rb +0 -3
- data/xenon-http/lib/xenon/media_type.rb +0 -162
- data/xenon-http/lib/xenon/parsers/basic_rules.rb +0 -86
- data/xenon-http/lib/xenon/parsers/header_rules.rb +0 -60
- data/xenon-http/lib/xenon/parsers/media_type.rb +0 -53
- data/xenon-http/lib/xenon/quoted_string.rb +0 -20
- data/xenon-http/spec/xenon/etag_spec.rb +0 -19
- data/xenon-http/spec/xenon/headers/accept_charset_spec.rb +0 -31
- data/xenon-http/spec/xenon/headers/accept_encoding_spec.rb +0 -40
- data/xenon-http/spec/xenon/headers/accept_language_spec.rb +0 -33
- data/xenon-http/spec/xenon/headers/accept_spec.rb +0 -54
- data/xenon-http/spec/xenon/headers/authorization_spec.rb +0 -47
- data/xenon-http/spec/xenon/headers/cache_control_spec.rb +0 -64
- data/xenon-http/spec/xenon/headers/if_match_spec.rb +0 -73
- data/xenon-http/spec/xenon/headers/if_modified_since_spec.rb +0 -19
- data/xenon-http/spec/xenon/headers/if_none_match_spec.rb +0 -79
- data/xenon-http/spec/xenon/headers/if_range_spec.rb +0 -45
- data/xenon-http/spec/xenon/headers/if_unmodified_since_spec.rb +0 -19
- data/xenon-http/spec/xenon/headers/user_agent_spec.rb +0 -67
- data/xenon-http/spec/xenon/headers/www_authenticate_spec.rb +0 -43
- data/xenon-http/spec/xenon/media_type_spec.rb +0 -267
- data/xenon-http/xenon-http.gemspec +0 -25
- data/xenon-routing/spec/spec_helper.rb +0 -94
- data/xenon.gemspec +0 -26
@@ -1,60 +0,0 @@
|
|
1
|
-
require 'xenon/quoted_string'
|
2
|
-
require 'xenon/parsers/basic_rules'
|
3
|
-
|
4
|
-
module Xenon
|
5
|
-
module Parsers
|
6
|
-
|
7
|
-
module HeaderRules
|
8
|
-
include Parslet, BasicRules
|
9
|
-
|
10
|
-
# http://tools.ietf.org/html/rfc7230#section-3.2.6
|
11
|
-
rule(:list_sep) { str(',') >> sp? }
|
12
|
-
rule(:param_sep) { str(';') >> sp? }
|
13
|
-
rule(:obs_text) { match(/[\u0080-\u00ff]/)}
|
14
|
-
rule(:qdtext) { htab | sp | match(/[\u0021\u0023-\u005b\u005d-\u007e]/) | obs_text }
|
15
|
-
rule(:quoted_pair) { str('\\') >> (htab | sp | vchar | obs_text) }
|
16
|
-
rule(:quoted_string) { (dquote >> (qdtext | quoted_pair).repeat >> dquote).as(:quoted_string) }
|
17
|
-
rule(:ctext) { htab | sp | match(/[\u0021-\u0027\u002a-\u005b\u005d-\u007e]/) | obs_text }
|
18
|
-
rule(:comment) { (str('(') >> (ctext | quoted_pair | comment).repeat >> str(')')).as(:comment) }
|
19
|
-
|
20
|
-
# http://tools.ietf.org/html/rfc7231#section-5.3.1
|
21
|
-
rule(:weight_value) { (digit >> (str('.') >> digit.repeat(0, 3)).maybe).as(:q) }
|
22
|
-
rule(:weight) { param_sep >> str('q') >> sp? >> str('=') >> sp? >> weight_value >> sp? }
|
23
|
-
end
|
24
|
-
|
25
|
-
module AuthHeaderRules
|
26
|
-
include Parslet, HeaderRules
|
27
|
-
|
28
|
-
rule(:token68) { ((alpha | digit | match(/[\-\._~\+\/]/)) >> str('=').repeat).repeat(1).as(:token) }
|
29
|
-
rule(:auth_scheme) { token.as(:auth_scheme) }
|
30
|
-
rule(:name) { token.as(:name) }
|
31
|
-
rule(:value) { token.as(:value) }
|
32
|
-
rule(:auth_param) { (name >> bws >> str('=') >> bws >> (token | quoted_string).as(:value)).as(:auth_param) }
|
33
|
-
rule(:auth_params) { (auth_param.maybe >> (ows >> comma >> ows >> auth_param).repeat).as(:auth_params) }
|
34
|
-
end
|
35
|
-
|
36
|
-
module ETagHeaderRules
|
37
|
-
include Parslet, HeaderRules
|
38
|
-
|
39
|
-
# http://tools.ietf.org/html/rfc7232#section-2.3
|
40
|
-
rule(:wildcard) { str('*').as(:wildcard) }
|
41
|
-
rule(:weak) { str('W/').as(:weak) }
|
42
|
-
rule(:etagc) { str('!') | match(/[\u0023-\u007e#-~]/) | obs_text }
|
43
|
-
rule(:opaque_tag) { dquote >> etagc.repeat.as(:opaque_tag) >> dquote }
|
44
|
-
rule(:etag) { (weak.maybe >> opaque_tag).as(:etag) }
|
45
|
-
end
|
46
|
-
|
47
|
-
class HeaderTransform < BasicTransform
|
48
|
-
using QuotedString
|
49
|
-
|
50
|
-
rule(quoted_string: simple(:qs)) { qs.unquote }
|
51
|
-
rule(comment: simple(:c)) { c.uncomment }
|
52
|
-
end
|
53
|
-
|
54
|
-
class ETagHeaderTransform < HeaderTransform
|
55
|
-
rule(etag: { opaque_tag: simple(:t), weak: simple(:w) }) { Xenon::ETag.new(t, weak: true) }
|
56
|
-
rule(etag: { opaque_tag: simple(:t) }) { Xenon::ETag.new(t) }
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
require 'xenon/parsers/basic_rules'
|
2
|
-
|
3
|
-
module Xenon
|
4
|
-
module Parsers
|
5
|
-
|
6
|
-
# note this uses the rules from https://tools.ietf.org/html/rfc6838 not http://tools.ietf.org/html/rfc7231
|
7
|
-
# because the latter is slightly ambiguous, e.g. a token can include * so */json would parse correctly
|
8
|
-
module MediaTypeRules
|
9
|
-
include Parslet, BasicRules
|
10
|
-
|
11
|
-
rule(:restricted_name_first) { match(/[a-zA-Z0-9]/) }
|
12
|
-
rule(:restricted_name_chars) { match(/[a-zA-Z0-9!#\$&\-\^_\.\+]/).repeat(0, 126) }
|
13
|
-
rule(:restricted_name) { restricted_name_first >> restricted_name_chars }
|
14
|
-
|
15
|
-
rule(:type) { restricted_name.as(:type) }
|
16
|
-
rule(:slash) { str('/') }
|
17
|
-
rule(:subtype) { restricted_name.as(:subtype) >> sp? }
|
18
|
-
|
19
|
-
rule(:param_sep) { str(';') >> sp? }
|
20
|
-
rule(:param_name) { restricted_name.as(:param_name) >> sp? }
|
21
|
-
rule(:equals) { str('=') >> sp? }
|
22
|
-
rule(:param_value) { token.as(:param_value) >> sp? } # not quite correct but probably correct enough
|
23
|
-
rule(:param) { param_sep >> param_name >> (equals >> param_value).maybe >> sp? }
|
24
|
-
rule(:params) { param.repeat.as(:params) }
|
25
|
-
|
26
|
-
rule(:media_type) { (type >> slash >> subtype >> params).as(:media_type) >> sp? }
|
27
|
-
|
28
|
-
rule(:wildcard) { str('*') }
|
29
|
-
rule(:wild_media_range) { wildcard.as(:type) >> slash >> wildcard.as(:subtype) >> params }
|
30
|
-
rule(:root_media_range) { type >> slash >> (wildcard.as(:subtype) | subtype) >> params }
|
31
|
-
rule(:media_range) { (wild_media_range | root_media_range).as(:media_range) >> sp? }
|
32
|
-
end
|
33
|
-
|
34
|
-
class MediaType < Parslet::Parser
|
35
|
-
include MediaTypeRules
|
36
|
-
root(:media_type)
|
37
|
-
end
|
38
|
-
|
39
|
-
class MediaRange < Parslet::Parser
|
40
|
-
include MediaTypeRules
|
41
|
-
root(:media_range)
|
42
|
-
end
|
43
|
-
|
44
|
-
class MediaTypeTransform < Parslet::Transform
|
45
|
-
rule(param_name: simple(:n), param_value: simple(:v)) { [n.str, v.str] }
|
46
|
-
rule(param_name: simple(:n)) { [n.str, nil] }
|
47
|
-
rule(type: simple(:t), subtype: simple(:s), params: subtree(:p)) { { type: t.str, subtype: s.str, params: Hash[p] } }
|
48
|
-
rule(media_type: subtree(:mt)) { Xenon::MediaType.new(mt[:type], mt[:subtype], mt[:params])}
|
49
|
-
rule(media_range: subtree(:mr)) { Xenon::MediaRange.new(mr[:type], mr[:subtype], mr[:params])}
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
module Xenon
|
2
|
-
module QuotedString
|
3
|
-
refine String do
|
4
|
-
def quote
|
5
|
-
qs = gsub(/([\\"])/, '\\\\\1')
|
6
|
-
self == qs ? self : %{"#{qs}"}
|
7
|
-
end
|
8
|
-
|
9
|
-
def unquote
|
10
|
-
qs = start_with?('"') && end_with?('"') ? self[1..-2] : self
|
11
|
-
qs.gsub(/\\(.)/, '\1')
|
12
|
-
end
|
13
|
-
|
14
|
-
def uncomment
|
15
|
-
qs = start_with?('(') && end_with?(')') ? self[1..-2] : self
|
16
|
-
qs.gsub(/\\(.)/, '\1')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'xenon/etag'
|
2
|
-
|
3
|
-
describe Xenon::ETag do
|
4
|
-
|
5
|
-
describe '::parse' do
|
6
|
-
it 'can parse a strong etag' do
|
7
|
-
etag = Xenon::ETag.parse('"xyzzy"')
|
8
|
-
expect(etag.opaque_tag).to eq 'xyzzy'
|
9
|
-
expect(etag).to be_strong
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can parse a weak etag' do
|
13
|
-
etag = Xenon::ETag.parse('W/"xyzzy"')
|
14
|
-
expect(etag.opaque_tag).to eq 'xyzzy'
|
15
|
-
expect(etag).to be_weak
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'xenon/headers/accept_charset'
|
2
|
-
|
3
|
-
describe Xenon::Headers::AcceptCharset do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
it 'can parse a basic charset range' do
|
7
|
-
header = Xenon::Headers::AcceptCharset.parse('unicode-1-1;q=0.8')
|
8
|
-
expect(header.charset_ranges.size).to eq(1)
|
9
|
-
expect(header.charset_ranges[0].to_s).to eq('unicode-1-1; q=0.8')
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can parse the example from RFC 7231 § 5.3.3 with the right precedence' do
|
13
|
-
header = Xenon::Headers::AcceptCharset.parse('iso-8859-5, unicode-1-1;q=0.8')
|
14
|
-
expect(header.charset_ranges.size).to eq(2)
|
15
|
-
expect(header.charset_ranges[0].to_s).to eq('iso-8859-5')
|
16
|
-
expect(header.charset_ranges[1].to_s).to eq('unicode-1-1; q=0.8')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context '#merge' do
|
21
|
-
it 'can merge two headers with the right precedence' do
|
22
|
-
h1 = Xenon::Headers::AcceptCharset.parse('unicode-1-1;q=0.8')
|
23
|
-
h2 = Xenon::Headers::AcceptCharset.parse('iso-8859-5')
|
24
|
-
header = h1.merge(h2)
|
25
|
-
expect(header.charset_ranges.size).to eq(2)
|
26
|
-
expect(header.charset_ranges[0].to_s).to eq('iso-8859-5')
|
27
|
-
expect(header.charset_ranges[1].to_s).to eq('unicode-1-1; q=0.8')
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'xenon/headers/accept_encoding'
|
2
|
-
|
3
|
-
describe Xenon::Headers::AcceptEncoding do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
%w(identity compress x-compress deflate gzip x-gzip *).each do |cc|
|
7
|
-
it "can parse the #{cc} content coding" do
|
8
|
-
header = Xenon::Headers::AcceptEncoding.parse(cc)
|
9
|
-
expect(header.coding_ranges.size).to eq(1)
|
10
|
-
expect(header.coding_ranges[0].to_s).to eq(cc)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'can parse the fifth example from RFC 7231 § 5.3.4 with the right precedence' do
|
15
|
-
header = Xenon::Headers::AcceptEncoding.parse('gzip;q=1.0, identity; q=0.5, *;q=0')
|
16
|
-
expect(header.coding_ranges.size).to eq(3)
|
17
|
-
expect(header.coding_ranges[0].to_s).to eq('gzip')
|
18
|
-
expect(header.coding_ranges[1].to_s).to eq('identity; q=0.5')
|
19
|
-
expect(header.coding_ranges[2].to_s).to eq('*; q=0.0')
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'parses an empty header as containing no codings' do
|
23
|
-
header = Xenon::Headers::AcceptEncoding.parse('')
|
24
|
-
expect(header.coding_ranges.size).to eq(0)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
context '#merge' do
|
29
|
-
it 'can merge two headers with the right precedence' do
|
30
|
-
h1 = Xenon::Headers::AcceptEncoding.parse('identity; q=0.5')
|
31
|
-
h2 = Xenon::Headers::AcceptEncoding.parse('gzip;q=1.0, *;q=0')
|
32
|
-
header = h1.merge(h2)
|
33
|
-
expect(header.coding_ranges.size).to eq(3)
|
34
|
-
expect(header.coding_ranges[0].to_s).to eq('gzip')
|
35
|
-
expect(header.coding_ranges[1].to_s).to eq('identity; q=0.5')
|
36
|
-
expect(header.coding_ranges[2].to_s).to eq('*; q=0.0')
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'xenon/headers/accept_language'
|
2
|
-
|
3
|
-
describe Xenon::Headers::AcceptLanguage do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
it 'can parse a basic language range' do
|
7
|
-
header = Xenon::Headers::AcceptLanguage.parse('en-gb;q=0.8')
|
8
|
-
expect(header.language_ranges.size).to eq(1)
|
9
|
-
expect(header.language_ranges[0].to_s).to eq('en-gb; q=0.8')
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can parse the example from RFC 7231 § 5.3.5 with the right precedence' do
|
13
|
-
header = Xenon::Headers::AcceptLanguage.parse('da, en-gb;q=0.8, en;q=0.7')
|
14
|
-
expect(header.language_ranges.size).to eq(3)
|
15
|
-
expect(header.language_ranges[0].to_s).to eq('da')
|
16
|
-
expect(header.language_ranges[1].to_s).to eq('en-gb; q=0.8')
|
17
|
-
expect(header.language_ranges[2].to_s).to eq('en; q=0.7')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
context '#merge' do
|
22
|
-
it 'can merge two headers with the right precedence' do
|
23
|
-
h1 = Xenon::Headers::AcceptLanguage.parse('da, en;q=0.7')
|
24
|
-
h2 = Xenon::Headers::AcceptLanguage.parse('en-gb;q=0.8')
|
25
|
-
header = h1.merge(h2)
|
26
|
-
expect(header.language_ranges.size).to eq(3)
|
27
|
-
expect(header.language_ranges[0].to_s).to eq('da')
|
28
|
-
expect(header.language_ranges[1].to_s).to eq('en-gb; q=0.8')
|
29
|
-
expect(header.language_ranges[2].to_s).to eq('en; q=0.7')
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
require 'xenon/headers/accept'
|
2
|
-
|
3
|
-
describe Xenon::Headers::Accept do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
it 'can parse a basic accept range' do
|
7
|
-
header = Xenon::Headers::Accept.parse('text/plain; q=0.5')
|
8
|
-
expect(header.media_ranges.size).to eq(1)
|
9
|
-
expect(header.media_ranges[0].to_s).to eq('text/plain; q=0.5')
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can parse the first example from RFC 7231 § 5.3.2 with the right precedence' do
|
13
|
-
header = Xenon::Headers::Accept.parse('text/plain; q=0.5, text/html, text/x-dvi; q=0.8, text/x-c')
|
14
|
-
expect(header.media_ranges.size).to eq(4)
|
15
|
-
expect(header.media_ranges[0].to_s).to eq('text/html')
|
16
|
-
expect(header.media_ranges[1].to_s).to eq('text/x-c')
|
17
|
-
expect(header.media_ranges[2].to_s).to eq('text/x-dvi; q=0.8')
|
18
|
-
expect(header.media_ranges[3].to_s).to eq('text/plain; q=0.5')
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'can parse the second example from RFC 7231 § 5.3.2 with the right precedence' do
|
22
|
-
header = Xenon::Headers::Accept.parse('text/*, text/plain, text/plain;format=flowed, */*')
|
23
|
-
expect(header.media_ranges.size).to eq(4)
|
24
|
-
expect(header.media_ranges[0].to_s).to eq('text/plain; format=flowed')
|
25
|
-
expect(header.media_ranges[1].to_s).to eq('text/plain')
|
26
|
-
expect(header.media_ranges[2].to_s).to eq('text/*')
|
27
|
-
expect(header.media_ranges[3].to_s).to eq('*/*')
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'can parse the third example from RFC 7231 § 5.3.2 with the right precedence' do
|
31
|
-
header = Xenon::Headers::Accept.parse('text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5')
|
32
|
-
expect(header.media_ranges.size).to eq(5)
|
33
|
-
expect(header.media_ranges[0].to_s).to eq('text/html; level=1')
|
34
|
-
expect(header.media_ranges[1].to_s).to eq('text/html; level=2; q=0.4')
|
35
|
-
expect(header.media_ranges[2].to_s).to eq('text/html; q=0.7')
|
36
|
-
expect(header.media_ranges[3].to_s).to eq('text/*; q=0.3')
|
37
|
-
expect(header.media_ranges[4].to_s).to eq('*/*; q=0.5')
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context '#merge' do
|
42
|
-
it 'can merge two headers with the right precedence' do
|
43
|
-
h1 = Xenon::Headers::Accept.parse('text/plain; q=0.5, text/html')
|
44
|
-
h2 = Xenon::Headers::Accept.parse('text/x-c, text/x-dvi; q=0.8')
|
45
|
-
header = h1.merge(h2)
|
46
|
-
expect(header.media_ranges.size).to eq(4)
|
47
|
-
expect(header.media_ranges[0].to_s).to eq('text/html')
|
48
|
-
expect(header.media_ranges[1].to_s).to eq('text/x-c')
|
49
|
-
expect(header.media_ranges[2].to_s).to eq('text/x-dvi; q=0.8')
|
50
|
-
expect(header.media_ranges[3].to_s).to eq('text/plain; q=0.5')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
require 'xenon/headers/authorization'
|
2
|
-
|
3
|
-
describe Xenon::Headers::Authorization do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
it 'can parse Basic credentials' do
|
7
|
-
header = Xenon::Headers::Authorization.parse('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==')
|
8
|
-
expect(header.credentials.class).to eq(Xenon::BasicCredentials)
|
9
|
-
expect(header.credentials.username).to eq('Aladdin')
|
10
|
-
expect(header.credentials.password).to eq('open sesame')
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'can parse Digest credentials' do
|
14
|
-
header = Xenon::Headers::Authorization.parse('Digest username="Mufasa"' +
|
15
|
-
', realm="testrealm@host.com"' +
|
16
|
-
', nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"' +
|
17
|
-
', uri="/dir/index.html"' +
|
18
|
-
', qop=auth' +
|
19
|
-
', nc=00000001' +
|
20
|
-
', cnonce="0a4f113b"' +
|
21
|
-
', response="6629fae49393a05397450978507c4ef1"' +
|
22
|
-
', opaque="5ccc069c403ebaf9f0171e9517f40e41"')
|
23
|
-
expect(header.credentials.class).to eq(Xenon::GenericCredentials)
|
24
|
-
expect(header.credentials.scheme).to eq('Digest')
|
25
|
-
expect(header.credentials.token).to eq(nil)
|
26
|
-
expect(header.credentials.params).to eq(
|
27
|
-
'username' => 'Mufasa',
|
28
|
-
'realm' => 'testrealm@host.com',
|
29
|
-
'nonce' => 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
|
30
|
-
'uri' => '/dir/index.html',
|
31
|
-
'qop' => 'auth',
|
32
|
-
'nc' => '00000001',
|
33
|
-
'cnonce' => '0a4f113b',
|
34
|
-
'response' => '6629fae49393a05397450978507c4ef1',
|
35
|
-
'opaque' => '5ccc069c403ebaf9f0171e9517f40e41')
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'can parse Bearer credentials' do
|
39
|
-
header = Xenon::Headers::Authorization.parse('Bearer eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.')
|
40
|
-
expect(header.credentials.class).to eq(Xenon::GenericCredentials)
|
41
|
-
expect(header.credentials.scheme).to eq('Bearer')
|
42
|
-
expect(header.credentials.token).to eq('eyJhbGciOiJub25lIn0.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.')
|
43
|
-
expect(header.credentials.params).to eq({})
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
end
|
@@ -1,64 +0,0 @@
|
|
1
|
-
require 'xenon/headers/cache_control'
|
2
|
-
|
3
|
-
describe Xenon::Headers::CacheControl do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
['max-age', 'max-stale', 'min-fresh', 's-maxage'].each do |dir|
|
7
|
-
it "can parse the #{dir} directive" do
|
8
|
-
header = Xenon::Headers::CacheControl.parse("#{dir}=5")
|
9
|
-
expect(header.directives.size).to eq(1)
|
10
|
-
expect(header.directives[0].to_s).to eq("#{dir}=5")
|
11
|
-
end
|
12
|
-
|
13
|
-
it "can parse the #{dir} directive with a quoted value" do # should not be sent by clients but is permitted
|
14
|
-
header = Xenon::Headers::CacheControl.parse("#{dir}=\"5\"")
|
15
|
-
expect(header.directives.size).to eq(1)
|
16
|
-
expect(header.directives[0].to_s).to eq("#{dir}=5")
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
['no-cache', 'no-store', 'no-transform', 'only-if-cached', 'must-revalidate', 'public', 'proxy-revalidate'].each do |dir|
|
21
|
-
it "can parse the #{dir} directive" do
|
22
|
-
header = Xenon::Headers::CacheControl.parse("#{dir}")
|
23
|
-
expect(header.directives.size).to eq(1)
|
24
|
-
expect(header.directives[0].to_s).to eq("#{dir}")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
it "can parse the private directive with no field names" do
|
29
|
-
header = Xenon::Headers::CacheControl.parse('private')
|
30
|
-
expect(header.directives.size).to eq(1)
|
31
|
-
expect(header.directives[0].to_s).to eq('private')
|
32
|
-
end
|
33
|
-
|
34
|
-
# TODO: private directive with field names
|
35
|
-
|
36
|
-
it 'can parse extension directives with quoted string values' do
|
37
|
-
header = Xenon::Headers::CacheControl.parse('ext="hello \"world\""')
|
38
|
-
expect(header.directives.size).to eq(1)
|
39
|
-
expect(header.directives[0].name).to eq('ext')
|
40
|
-
expect(header.directives[0].value).to eq("hello \"world\"")
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'can parse more complex directives' do
|
44
|
-
header = Xenon::Headers::CacheControl.parse('public, max-age=3600, must-revalidate')
|
45
|
-
expect(header.directives.size).to eq(3)
|
46
|
-
expect(header.directives[0].to_s).to eq('public')
|
47
|
-
expect(header.directives[1].to_s).to eq('max-age=3600')
|
48
|
-
expect(header.directives[2].to_s).to eq('must-revalidate')
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
context '#merge' do
|
53
|
-
it 'can merge two headers and maintain directive order' do
|
54
|
-
h1 = Xenon::Headers::CacheControl.parse('public, max-age=3600')
|
55
|
-
h2 = Xenon::Headers::CacheControl.parse('must-revalidate')
|
56
|
-
header = h1.merge(h2)
|
57
|
-
expect(header.directives.size).to eq(3)
|
58
|
-
expect(header.directives[0].to_s).to eq('public')
|
59
|
-
expect(header.directives[1].to_s).to eq('max-age=3600')
|
60
|
-
expect(header.directives[2].to_s).to eq('must-revalidate')
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
end
|
@@ -1,73 +0,0 @@
|
|
1
|
-
require 'xenon/headers/if_match'
|
2
|
-
|
3
|
-
describe Xenon::Headers::IfMatch do
|
4
|
-
|
5
|
-
context '::parse' do
|
6
|
-
it 'can parse a single etag' do
|
7
|
-
header = Xenon::Headers::IfMatch.parse('"xyzzy"')
|
8
|
-
expect(header.etags.size).to eq(1)
|
9
|
-
expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'can parse multiple etags' do
|
13
|
-
header = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx", "c3piozzzz"')
|
14
|
-
expect(header.etags.size).to eq(3)
|
15
|
-
expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
|
16
|
-
expect(header.etags[1]).to eq(Xenon::ETag.new('r2d2xxxx'))
|
17
|
-
expect(header.etags[2]).to eq(Xenon::ETag.new('c3piozzzz'))
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'can parse a wildcard header' do
|
21
|
-
header = Xenon::Headers::IfMatch.parse('*')
|
22
|
-
expect(header.etags.size).to eq(0)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
context '#merge' do
|
27
|
-
it 'can merge two headers and maintain etag order' do
|
28
|
-
h1 = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx"')
|
29
|
-
h2 = Xenon::Headers::IfMatch.parse('"c3piozzzz"')
|
30
|
-
header = h1.merge(h2)
|
31
|
-
expect(header.etags.size).to eq(3)
|
32
|
-
expect(header.etags[0]).to eq(Xenon::ETag.new('xyzzy'))
|
33
|
-
expect(header.etags[1]).to eq(Xenon::ETag.new('r2d2xxxx'))
|
34
|
-
expect(header.etags[2]).to eq(Xenon::ETag.new('c3piozzzz'))
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'raises a protocol error when trying to merge into a wildcard header' do
|
38
|
-
h1 = Xenon::Headers::IfMatch.parse('*')
|
39
|
-
h2 = Xenon::Headers::IfMatch.parse('"c3piozzzz"')
|
40
|
-
expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'raises a protocol error when trying to merge a wildcard into a header' do
|
44
|
-
h1 = Xenon::Headers::IfMatch.parse('"xyzzy"')
|
45
|
-
h2 = Xenon::Headers::IfMatch.parse('*')
|
46
|
-
expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'raises a protocol error when trying to merge two wildcard headers' do
|
50
|
-
h1 = Xenon::Headers::IfMatch.parse('*')
|
51
|
-
h2 = Xenon::Headers::IfMatch.parse('*')
|
52
|
-
expect { h1.merge(h2) }.to raise_error(Xenon::ProtocolError)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context '#to_s' do
|
57
|
-
it 'returns the string representation a single etag' do
|
58
|
-
header = Xenon::Headers::IfMatch.parse('"xyzzy"')
|
59
|
-
expect(header.to_s).to eq('"xyzzy"')
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'returns the string representation of multiple etags' do
|
63
|
-
header = Xenon::Headers::IfMatch.parse('"xyzzy", "r2d2xxxx", "c3piozzzz"')
|
64
|
-
expect(header.to_s).to eq('"xyzzy", "r2d2xxxx", "c3piozzzz"')
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'returns the string representation of a wildcard header' do
|
68
|
-
header = Xenon::Headers::IfMatch.wildcard
|
69
|
-
expect(header.to_s).to eq('*')
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
end
|