xenon 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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +18 -0
- data/.gitignore +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +10 -0
- data/Guardfile +0 -32
- data/README.md +59 -5
- data/examples/hello_world/config.ru +3 -0
- data/examples/hello_world/hello_world.rb +17 -0
- data/lib/xenon.rb +62 -49
- data/lib/xenon/auth.rb +63 -0
- data/lib/xenon/errors.rb +1 -0
- data/lib/xenon/etag.rb +48 -0
- data/lib/xenon/headers.rb +2 -4
- data/lib/xenon/headers/accept.rb +3 -2
- data/lib/xenon/headers/accept_charset.rb +5 -5
- data/lib/xenon/headers/accept_encoding.rb +5 -5
- data/lib/xenon/headers/accept_language.rb +5 -5
- data/lib/xenon/headers/authorization.rb +7 -53
- data/lib/xenon/headers/cache_control.rb +3 -3
- data/lib/xenon/headers/content_type.rb +1 -1
- data/lib/xenon/headers/if_match.rb +53 -0
- data/lib/xenon/headers/if_modified_since.rb +22 -0
- data/lib/xenon/headers/if_none_match.rb +53 -0
- data/lib/xenon/headers/if_range.rb +45 -0
- data/lib/xenon/headers/if_unmodified_since.rb +22 -0
- data/lib/xenon/headers/user_agent.rb +65 -0
- data/lib/xenon/headers/www_authenticate.rb +70 -0
- data/lib/xenon/media_type.rb +24 -2
- data/lib/xenon/parsers/basic_rules.rb +38 -7
- data/lib/xenon/parsers/header_rules.rb +49 -3
- data/lib/xenon/parsers/media_type.rb +4 -3
- data/lib/xenon/quoted_string.rb +11 -1
- data/lib/xenon/routing/directives.rb +14 -0
- data/lib/xenon/routing/header_directives.rb +32 -0
- data/lib/xenon/routing/method_directives.rb +26 -0
- data/lib/xenon/routing/param_directives.rb +22 -0
- data/lib/xenon/routing/path_directives.rb +37 -0
- data/lib/xenon/routing/route_directives.rb +51 -0
- data/lib/xenon/routing/security_directives.rb +20 -0
- data/lib/xenon/version.rb +1 -1
- data/spec/spec_helper.rb +3 -0
- data/spec/xenon/etag_spec.rb +19 -0
- data/spec/xenon/headers/if_match_spec.rb +73 -0
- data/spec/xenon/headers/if_modified_since_spec.rb +19 -0
- data/spec/xenon/headers/if_none_match_spec.rb +79 -0
- data/spec/xenon/headers/if_range_spec.rb +45 -0
- data/spec/xenon/headers/if_unmodified_since_spec.rb +19 -0
- data/spec/xenon/headers/user_agent_spec.rb +67 -0
- data/spec/xenon/headers/www_authenticate_spec.rb +43 -0
- data/xenon.gemspec +4 -3
- metadata +60 -10
- data/lib/xenon/routing.rb +0 -133
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'xenon/headers/www_authenticate'
|
2
|
+
|
3
|
+
describe Xenon::Headers::WWWAuthenticate do
|
4
|
+
|
5
|
+
context '::parse' do
|
6
|
+
|
7
|
+
it 'can parse a Basic challenge with a realm' do
|
8
|
+
header = Xenon::Headers::WWWAuthenticate.parse('Basic realm="simple"')
|
9
|
+
expect(header.challenges.size).to eq(1)
|
10
|
+
expect(header.challenges[0].auth_scheme).to eq('Basic')
|
11
|
+
expect(header.challenges[0].realm).to eq('simple')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'can parse a Digest challenge with a realm' do
|
15
|
+
header = Xenon::Headers::WWWAuthenticate.parse('Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41"')
|
16
|
+
expect(header.challenges.size).to eq(1)
|
17
|
+
expect(header.challenges[0].auth_scheme).to eq('Digest')
|
18
|
+
expect(header.challenges[0].realm).to eq('testrealm@host.com')
|
19
|
+
expect(header.challenges[0].qop).to eq('auth,auth-int')
|
20
|
+
expect(header.challenges[0].nonce).to eq('dcd98b7102dd2f0e8b11d0f600bfb0c093')
|
21
|
+
expect(header.challenges[0].opaque).to eq('5ccc069c403ebaf9f0171e9517f40e41')
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'can parse a custom challenge' do
|
25
|
+
header = Xenon::Headers::WWWAuthenticate.parse('Newauth realm="apps", type=1, title="Login to \"apps\""')
|
26
|
+
expect(header.challenges.size).to eq(1)
|
27
|
+
expect(header.challenges[0].auth_scheme).to eq('Newauth')
|
28
|
+
expect(header.challenges[0].realm).to eq('apps')
|
29
|
+
expect(header.challenges[0].type).to eq('1')
|
30
|
+
expect(header.challenges[0].title).to eq('Login to "apps"')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'can parse multiple challenges' do
|
34
|
+
header = Xenon::Headers::WWWAuthenticate.parse('Digest realm="testrealm@host.com", qop="auth,auth-int", nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", opaque="5ccc069c403ebaf9f0171e9517f40e41", Basic realm="simple", Newauth realm="apps", type=1, title="Login to \"apps\""')
|
35
|
+
expect(header.challenges.size).to eq(3)
|
36
|
+
expect(header.challenges[0].auth_scheme).to eq('Digest')
|
37
|
+
expect(header.challenges[1].auth_scheme).to eq('Basic')
|
38
|
+
expect(header.challenges[2].auth_scheme).to eq('Newauth')
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/xenon.gemspec
CHANGED
@@ -22,8 +22,9 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_runtime_dependency 'activesupport', '~> 4.0'
|
24
24
|
spec.add_runtime_dependency 'parslet', '~> 1.7'
|
25
|
+
spec.add_runtime_dependency 'rack', '~> 1.6'
|
25
26
|
|
26
|
-
spec.add_development_dependency 'bundler', '~> 1.
|
27
|
-
spec.add_development_dependency 'rake', '~> 10.
|
28
|
-
spec.add_development_dependency 'rspec', '~> 3.
|
27
|
+
spec.add_development_dependency 'bundler', '~> 1.10'
|
28
|
+
spec.add_development_dependency 'rake', '~> 10.4'
|
29
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xenon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Beech
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -39,47 +39,61 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rack
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '1.6'
|
48
|
-
type: :
|
48
|
+
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: bundler
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.10'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.10'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rake
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - "~>"
|
60
74
|
- !ruby/object:Gem::Version
|
61
|
-
version: '10.
|
75
|
+
version: '10.4'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
80
|
- - "~>"
|
67
81
|
- !ruby/object:Gem::Version
|
68
|
-
version: '10.
|
82
|
+
version: '10.4'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - "~>"
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '3.
|
89
|
+
version: '3.3'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - "~>"
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '3.
|
96
|
+
version: '3.3'
|
83
97
|
description: Provides a model for the HTTP protocol and a tree-based routing syntax.
|
84
98
|
email:
|
85
99
|
- greg@gregbeech.com
|
@@ -87,15 +101,21 @@ executables: []
|
|
87
101
|
extensions: []
|
88
102
|
extra_rdoc_files: []
|
89
103
|
files:
|
104
|
+
- ".codeclimate.yml"
|
90
105
|
- ".gitignore"
|
91
106
|
- ".rspec"
|
107
|
+
- ".travis.yml"
|
92
108
|
- Gemfile
|
93
109
|
- Guardfile
|
94
110
|
- LICENSE
|
95
111
|
- README.md
|
96
112
|
- Rakefile
|
113
|
+
- examples/hello_world/config.ru
|
114
|
+
- examples/hello_world/hello_world.rb
|
97
115
|
- lib/xenon.rb
|
116
|
+
- lib/xenon/auth.rb
|
98
117
|
- lib/xenon/errors.rb
|
118
|
+
- lib/xenon/etag.rb
|
99
119
|
- lib/xenon/headers.rb
|
100
120
|
- lib/xenon/headers/accept.rb
|
101
121
|
- lib/xenon/headers/accept_charset.rb
|
@@ -104,20 +124,41 @@ files:
|
|
104
124
|
- lib/xenon/headers/authorization.rb
|
105
125
|
- lib/xenon/headers/cache_control.rb
|
106
126
|
- lib/xenon/headers/content_type.rb
|
127
|
+
- lib/xenon/headers/if_match.rb
|
128
|
+
- lib/xenon/headers/if_modified_since.rb
|
129
|
+
- lib/xenon/headers/if_none_match.rb
|
130
|
+
- lib/xenon/headers/if_range.rb
|
131
|
+
- lib/xenon/headers/if_unmodified_since.rb
|
132
|
+
- lib/xenon/headers/user_agent.rb
|
133
|
+
- lib/xenon/headers/www_authenticate.rb
|
107
134
|
- lib/xenon/media_type.rb
|
108
135
|
- lib/xenon/parsers/basic_rules.rb
|
109
136
|
- lib/xenon/parsers/header_rules.rb
|
110
137
|
- lib/xenon/parsers/media_type.rb
|
111
138
|
- lib/xenon/quoted_string.rb
|
112
|
-
- lib/xenon/routing.rb
|
139
|
+
- lib/xenon/routing/directives.rb
|
140
|
+
- lib/xenon/routing/header_directives.rb
|
141
|
+
- lib/xenon/routing/method_directives.rb
|
142
|
+
- lib/xenon/routing/param_directives.rb
|
143
|
+
- lib/xenon/routing/path_directives.rb
|
144
|
+
- lib/xenon/routing/route_directives.rb
|
145
|
+
- lib/xenon/routing/security_directives.rb
|
113
146
|
- lib/xenon/version.rb
|
114
147
|
- spec/spec_helper.rb
|
148
|
+
- spec/xenon/etag_spec.rb
|
115
149
|
- spec/xenon/headers/accept_charset_spec.rb
|
116
150
|
- spec/xenon/headers/accept_encoding_spec.rb
|
117
151
|
- spec/xenon/headers/accept_language_spec.rb
|
118
152
|
- spec/xenon/headers/accept_spec.rb
|
119
153
|
- spec/xenon/headers/authorization_spec.rb
|
120
154
|
- spec/xenon/headers/cache_control_spec.rb
|
155
|
+
- spec/xenon/headers/if_match_spec.rb
|
156
|
+
- spec/xenon/headers/if_modified_since_spec.rb
|
157
|
+
- spec/xenon/headers/if_none_match_spec.rb
|
158
|
+
- spec/xenon/headers/if_range_spec.rb
|
159
|
+
- spec/xenon/headers/if_unmodified_since_spec.rb
|
160
|
+
- spec/xenon/headers/user_agent_spec.rb
|
161
|
+
- spec/xenon/headers/www_authenticate_spec.rb
|
121
162
|
- spec/xenon/media_type_spec.rb
|
122
163
|
- xenon.gemspec
|
123
164
|
homepage: https://github.com/gregbeech/xenon
|
@@ -140,16 +181,25 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
181
|
version: '0'
|
141
182
|
requirements: []
|
142
183
|
rubyforge_project:
|
143
|
-
rubygems_version: 2.4.
|
184
|
+
rubygems_version: 2.4.8
|
144
185
|
signing_key:
|
145
186
|
specification_version: 4
|
146
187
|
summary: An HTTP framework for building RESTful APIs.
|
147
188
|
test_files:
|
148
189
|
- spec/spec_helper.rb
|
190
|
+
- spec/xenon/etag_spec.rb
|
149
191
|
- spec/xenon/headers/accept_charset_spec.rb
|
150
192
|
- spec/xenon/headers/accept_encoding_spec.rb
|
151
193
|
- spec/xenon/headers/accept_language_spec.rb
|
152
194
|
- spec/xenon/headers/accept_spec.rb
|
153
195
|
- spec/xenon/headers/authorization_spec.rb
|
154
196
|
- spec/xenon/headers/cache_control_spec.rb
|
197
|
+
- spec/xenon/headers/if_match_spec.rb
|
198
|
+
- spec/xenon/headers/if_modified_since_spec.rb
|
199
|
+
- spec/xenon/headers/if_none_match_spec.rb
|
200
|
+
- spec/xenon/headers/if_range_spec.rb
|
201
|
+
- spec/xenon/headers/if_unmodified_since_spec.rb
|
202
|
+
- spec/xenon/headers/user_agent_spec.rb
|
203
|
+
- spec/xenon/headers/www_authenticate_spec.rb
|
155
204
|
- spec/xenon/media_type_spec.rb
|
205
|
+
has_rdoc:
|
data/lib/xenon/routing.rb
DELETED
@@ -1,133 +0,0 @@
|
|
1
|
-
module Xenon
|
2
|
-
module Routing
|
3
|
-
|
4
|
-
module RouteDirectives
|
5
|
-
def map_request(map)
|
6
|
-
context.branch do
|
7
|
-
context.request = map.respond_to?(:call) ? map.call(context.request) : context.request.copy(map)
|
8
|
-
yield
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
def map_response(map)
|
13
|
-
context.branch do
|
14
|
-
context.response = map.respond_to?(:call) ? map.call(context.response) : context.response.copy(map)
|
15
|
-
yield
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def complete(status, body)
|
20
|
-
map_response complete: true, status: status, body: body do
|
21
|
-
throw :complete
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def reject(rejection)
|
26
|
-
context.rejections << rejection unless rejection.nil?
|
27
|
-
end
|
28
|
-
|
29
|
-
def extract(lambda)
|
30
|
-
yield lambda.call(context)
|
31
|
-
end
|
32
|
-
|
33
|
-
def extract_request(lambda = nil)
|
34
|
-
yield lambda ? lambda.call(context.request) : context.request
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
module HeaderDirectives
|
39
|
-
def optional_header(name)
|
40
|
-
extract_request do |request|
|
41
|
-
yield request.header(name)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def header(name)
|
46
|
-
optional_header(name) do |value|
|
47
|
-
if value
|
48
|
-
yield value
|
49
|
-
else
|
50
|
-
reject Rejection.new(Rejection::HEADER, { required: name })
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
def respond_with_header(header)
|
56
|
-
map_response -> r { r.copy(headers: r.headers.add(header)) } do
|
57
|
-
yield
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
module MethodDirectives
|
63
|
-
include RouteDirectives
|
64
|
-
|
65
|
-
def request_method(method)
|
66
|
-
extract_request do |request|
|
67
|
-
if request.request_method == method
|
68
|
-
yield
|
69
|
-
else
|
70
|
-
reject Rejection.new(Rejection::METHOD, { supported: method })
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
%i(delete get head options patch post put).each do |method|
|
76
|
-
define_method(method) do |&inner|
|
77
|
-
request_method(method, &inner)
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
module ParamDirectives
|
83
|
-
def form_hash
|
84
|
-
extract_request do |request|
|
85
|
-
yield request.form_hash
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
def query_hash
|
90
|
-
extract_request do |request|
|
91
|
-
yield request.query_hash
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
module PathDirectives
|
97
|
-
include RouteDirectives
|
98
|
-
|
99
|
-
def path_prefix(pattern)
|
100
|
-
extract_request do |request|
|
101
|
-
match = request.unmatched_path.match(pattern)
|
102
|
-
if match && match.pre_match == ''
|
103
|
-
map_request unmatched_path: match.post_match do
|
104
|
-
yield *match.captures
|
105
|
-
end
|
106
|
-
else
|
107
|
-
reject nil # path rejections are nil to allow more specific rejections to be seen
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def path_end(&inner)
|
113
|
-
path_prefix(/\Z/, &inner)
|
114
|
-
end
|
115
|
-
|
116
|
-
def path(pattern, &inner)
|
117
|
-
path_prefix(pattern) do |*captures|
|
118
|
-
path_end do
|
119
|
-
inner.call(*captures)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
module Directives
|
126
|
-
include HeaderDirectives
|
127
|
-
include MethodDirectives
|
128
|
-
include ParamDirectives
|
129
|
-
include PathDirectives
|
130
|
-
end
|
131
|
-
|
132
|
-
end
|
133
|
-
end
|