lotus-router 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/lotus/router.rb +1 -2
- data/lib/lotus/router/version.rb +1 -1
- data/lib/lotus/routing/force_ssl.rb +209 -0
- data/lib/lotus/routing/http_router.rb +76 -8
- data/lib/lotus/routing/namespace.rb +6 -0
- data/lotus-router.gemspec +1 -1
- metadata +6 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fe3bedc422dfc753499bc3b622eae9991fbb5f6d
|
4
|
+
data.tar.gz: 04092313d4a1f9c19f83e4f555b4da56394b33ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0481beec0347d4f748fddd153eefa13b7e6460bf9ce16901179d7930fcecd2a6f2196e954d84a37a8c7b3f9355da2eb3b3ba6ad46ca404534759ca7fbbabd81
|
7
|
+
data.tar.gz: cf5c52860e529475867d0f4df858df214acd206054912fa82849b2d973ecf5a46d84292609599d0496fb04270f11f0b01bfb5784fabd0d625ef7348dee0ea69d
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# Lotus::Router
|
2
2
|
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
+
## v0.4.1 - 2015-06-23
|
5
|
+
### Added
|
6
|
+
- [Alfonso Uceda Pompa] Force SSL (eg `Lotus::Router.new(force_ssl: true`).
|
7
|
+
- [Alfonso Uceda Pompa] Allow router to accept a `:prefix` option, in order to generate prefixed routes.
|
8
|
+
|
4
9
|
## v0.4.0 - 2015-05-15
|
5
10
|
### Added
|
6
11
|
- [Alfonso Uceda Pompa] Nested RESTful resource(s)
|
data/lib/lotus/router.rb
CHANGED
@@ -13,12 +13,11 @@ module Lotus
|
|
13
13
|
#
|
14
14
|
# endpoint = ->(env) { [200, {}, ['Welcome to Lotus::Router!']] }
|
15
15
|
# router = Lotus::Router.new do
|
16
|
-
# get '/', to: endpoint
|
16
|
+
# get '/', to: endpoint # => get and head requests
|
17
17
|
# post '/', to: endpoint
|
18
18
|
# put '/', to: endpoint
|
19
19
|
# patch '/', to: endpoint
|
20
20
|
# delete '/', to: endpoint
|
21
|
-
# head '/', to: endpoint
|
22
21
|
# options '/', to: endpoint
|
23
22
|
# trace '/', to: endpoint
|
24
23
|
# end
|
data/lib/lotus/router/version.rb
CHANGED
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'rack/request'
|
2
|
+
|
3
|
+
module Lotus
|
4
|
+
module Routing
|
5
|
+
# Force ssl
|
6
|
+
#
|
7
|
+
# Redirect response to the secure equivalent resource (https)
|
8
|
+
#
|
9
|
+
# @since 0.4.1
|
10
|
+
# @api private
|
11
|
+
class ForceSsl
|
12
|
+
# Https scheme
|
13
|
+
#
|
14
|
+
# @since 0.4.1
|
15
|
+
# @api private
|
16
|
+
SSL_SCHEME = 'https'.freeze
|
17
|
+
|
18
|
+
# @since 0.4.1
|
19
|
+
# @api private
|
20
|
+
HTTPS = 'HTTPS'.freeze
|
21
|
+
|
22
|
+
# @since 0.4.1
|
23
|
+
# @api private
|
24
|
+
ON = 'on'.freeze
|
25
|
+
|
26
|
+
# Location header
|
27
|
+
#
|
28
|
+
# @since 0.4.1
|
29
|
+
# @api private
|
30
|
+
LOCATION_HEADER = 'Location'.freeze
|
31
|
+
|
32
|
+
# Default http port
|
33
|
+
#
|
34
|
+
# @since 0.4.1
|
35
|
+
# @api private
|
36
|
+
DEFAULT_HTTP_PORT = 80
|
37
|
+
|
38
|
+
# Default ssl port
|
39
|
+
#
|
40
|
+
# @since 0.4.1
|
41
|
+
# @api private
|
42
|
+
DEFAULT_SSL_PORT = 443
|
43
|
+
|
44
|
+
# Moved Permanently http code
|
45
|
+
#
|
46
|
+
# @since 0.4.1
|
47
|
+
# @api private
|
48
|
+
MOVED_PERMANENTLY_HTTP_CODE = 301
|
49
|
+
|
50
|
+
# Temporary Redirect http code
|
51
|
+
#
|
52
|
+
# @since 0.4.1
|
53
|
+
# @api private
|
54
|
+
TEMPORARY_REDIRECT_HTTP_CODE = 307
|
55
|
+
|
56
|
+
# @since 0.4.1
|
57
|
+
# @api private
|
58
|
+
HTTP_X_FORWARDED_SSL = 'HTTP_X_FORWARDED_SSL'.freeze
|
59
|
+
|
60
|
+
# @since 0.4.1
|
61
|
+
# @api private
|
62
|
+
HTTP_X_FORWARDED_SCHEME = 'HTTP_X_FORWARDED_SCHEME'.freeze
|
63
|
+
|
64
|
+
# @since 0.4.1
|
65
|
+
# @api private
|
66
|
+
HTTP_X_FORWARDED_PROTO = 'HTTP_X_FORWARDED_PROTO'.freeze
|
67
|
+
|
68
|
+
# @since 0.4.1
|
69
|
+
# @api private
|
70
|
+
HTTP_X_FORWARDED_PROTO_SEPARATOR = ','.freeze
|
71
|
+
|
72
|
+
# @since 0.4.1
|
73
|
+
# @api private
|
74
|
+
RACK_URL_SCHEME = 'rack.url_scheme'.freeze
|
75
|
+
|
76
|
+
# @since 0.4.1
|
77
|
+
# @api private
|
78
|
+
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
79
|
+
|
80
|
+
# @since 0.4.1
|
81
|
+
# @api private
|
82
|
+
IDEMPOTENT_METHODS = ['GET', 'HEAD'].freeze
|
83
|
+
|
84
|
+
EMPTY_BODY = ''.freeze
|
85
|
+
|
86
|
+
# Initialize ForceSsl.
|
87
|
+
#
|
88
|
+
# @param active [Boolean] activate redirection to SSL
|
89
|
+
# @param options [Hash] set of options
|
90
|
+
# @option options [String] :host
|
91
|
+
# @option options [Integer] :port
|
92
|
+
#
|
93
|
+
# @since 0.4.1
|
94
|
+
# @api private
|
95
|
+
def initialize(active, options = {})
|
96
|
+
@active = active
|
97
|
+
@host = options[:host]
|
98
|
+
@port = options[:port]
|
99
|
+
|
100
|
+
_redefine_call
|
101
|
+
end
|
102
|
+
|
103
|
+
# Set 301 status and Location header if this feature is activated.
|
104
|
+
#
|
105
|
+
# @param env [Hash] a Rack env instance
|
106
|
+
#
|
107
|
+
# @return [Array]
|
108
|
+
#
|
109
|
+
# @see Lotus::Routing::HttpRouter#call
|
110
|
+
#
|
111
|
+
# @since 0.4.1
|
112
|
+
# @api private
|
113
|
+
def call(env)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Check if router has to force the response with ssl
|
117
|
+
#
|
118
|
+
# @return [Boolean]
|
119
|
+
#
|
120
|
+
# @since 0.4.1
|
121
|
+
# @api private
|
122
|
+
def force?(env)
|
123
|
+
!ssl?(env)
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
# @since 0.4.1
|
129
|
+
# @api private
|
130
|
+
attr_reader :host
|
131
|
+
|
132
|
+
# Return full url to redirect
|
133
|
+
#
|
134
|
+
# @param env [Hash] Rack env
|
135
|
+
#
|
136
|
+
# @return [String]
|
137
|
+
#
|
138
|
+
# @since 0.4.1
|
139
|
+
# @api private
|
140
|
+
def full_url(env)
|
141
|
+
"#{ SSL_SCHEME }://#{ host }:#{ port }#{ ::Rack::Request.new(env).fullpath }"
|
142
|
+
end
|
143
|
+
|
144
|
+
# Return redirect code
|
145
|
+
#
|
146
|
+
# @param env [Hash] Rack env
|
147
|
+
#
|
148
|
+
# @return [Integer]
|
149
|
+
#
|
150
|
+
# @since 0.4.1
|
151
|
+
# @api private
|
152
|
+
def redirect_code(env)
|
153
|
+
if IDEMPOTENT_METHODS.include?(env[REQUEST_METHOD])
|
154
|
+
MOVED_PERMANENTLY_HTTP_CODE
|
155
|
+
else
|
156
|
+
TEMPORARY_REDIRECT_HTTP_CODE
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return correct default port for full url
|
161
|
+
#
|
162
|
+
# @return [Integer]
|
163
|
+
#
|
164
|
+
# @since 0.4.1
|
165
|
+
# @api private
|
166
|
+
def port
|
167
|
+
if @port == DEFAULT_HTTP_PORT
|
168
|
+
DEFAULT_SSL_PORT
|
169
|
+
else
|
170
|
+
@port
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# @since 0.4.1
|
175
|
+
# @api private
|
176
|
+
def _redefine_call
|
177
|
+
return unless @active
|
178
|
+
|
179
|
+
define_singleton_method :call do |env|
|
180
|
+
[redirect_code(env), { LOCATION_HEADER => full_url(env) }, EMPTY_BODY] if force?(env)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Adapted from Rack::Request#scheme
|
185
|
+
#
|
186
|
+
# @since 0.4.1
|
187
|
+
# @api private
|
188
|
+
def scheme(env)
|
189
|
+
if env[HTTPS] == ON
|
190
|
+
SSL_SCHEME
|
191
|
+
elsif env[HTTP_X_FORWARDED_SSL] == ON
|
192
|
+
SSL_SCHEME
|
193
|
+
elsif env[HTTP_X_FORWARDED_SCHEME]
|
194
|
+
env[HTTP_X_FORWARDED_SCHEME]
|
195
|
+
elsif env[HTTP_X_FORWARDED_PROTO]
|
196
|
+
env[HTTP_X_FORWARDED_PROTO].split(HTTP_X_FORWARDED_PROTO_SEPARATOR)[0]
|
197
|
+
else
|
198
|
+
env[RACK_URL_SCHEME]
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
# @since 0.4.1
|
203
|
+
# @api private
|
204
|
+
def ssl?(env)
|
205
|
+
scheme(env) == SSL_SCHEME
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
@@ -3,6 +3,8 @@ require 'lotus/utils/io'
|
|
3
3
|
require 'lotus/routing/endpoint_resolver'
|
4
4
|
require 'lotus/routing/route'
|
5
5
|
require 'lotus/routing/parsers'
|
6
|
+
require 'lotus/routing/force_ssl'
|
7
|
+
require 'lotus/utils/path_prefix'
|
6
8
|
|
7
9
|
Lotus::Utils::IO.silence_warnings do
|
8
10
|
HttpRouter::Route::VALID_HTTP_VERBS = %w{GET POST PUT PATCH DELETE HEAD OPTIONS TRACE}
|
@@ -37,12 +39,14 @@ module Lotus
|
|
37
39
|
def initialize(options = {}, &blk)
|
38
40
|
super(options, &nil)
|
39
41
|
|
40
|
-
@default_scheme
|
41
|
-
@default_host
|
42
|
-
@default_port
|
43
|
-
@route_class
|
44
|
-
@resolver
|
45
|
-
@parsers
|
42
|
+
@default_scheme = options[:scheme] if options[:scheme]
|
43
|
+
@default_host = options[:host] if options[:host]
|
44
|
+
@default_port = options[:port] if options[:port]
|
45
|
+
@route_class = options[:route] || Routing::Route
|
46
|
+
@resolver = options[:resolver] || Routing::EndpointResolver.new(options)
|
47
|
+
@parsers = Routing::Parsers.new(options[:parsers])
|
48
|
+
@prefix = Utils::PathPrefix.new(options[:prefix] || '')
|
49
|
+
@force_ssl = Lotus::Routing::ForceSsl.new(!!options[:force_ssl], host: @default_host, port: @default_port)
|
46
50
|
end
|
47
51
|
|
48
52
|
# Separator between controller and action name.
|
@@ -85,6 +89,66 @@ module Lotus
|
|
85
89
|
_rescue_url_recognition { super }
|
86
90
|
end
|
87
91
|
|
92
|
+
# Support for GET HTTP verb
|
93
|
+
#
|
94
|
+
# @see Lotus::Router#options
|
95
|
+
#
|
96
|
+
# @since 0.4.1
|
97
|
+
# @api private
|
98
|
+
def get(path, options = {}, &blk)
|
99
|
+
super(@prefix.join(path), options, &blk)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Support for POST HTTP verb
|
103
|
+
#
|
104
|
+
# @see Lotus::Router#post
|
105
|
+
#
|
106
|
+
# @since 0.4.1
|
107
|
+
# @api private
|
108
|
+
def post(path, options = {}, &blk)
|
109
|
+
super(@prefix.join(path), options, &blk)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Support for PUT HTTP verb
|
113
|
+
#
|
114
|
+
# @see Lotus::Router#put
|
115
|
+
#
|
116
|
+
# @since 0.4.1
|
117
|
+
# @api private
|
118
|
+
def put(path, options = {}, &blk)
|
119
|
+
super(@prefix.join(path), options, &blk)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Support for PATCH HTTP verb
|
123
|
+
#
|
124
|
+
# @see Lotus::Router#patch
|
125
|
+
#
|
126
|
+
# @since 0.4.1
|
127
|
+
# @api private
|
128
|
+
def patch(path, options = {}, &blk)
|
129
|
+
super(@prefix.join(path), options, &blk)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Support for DELETE HTTP verb
|
133
|
+
#
|
134
|
+
# @see Lotus::Router#delete
|
135
|
+
#
|
136
|
+
# @since 0.4.1
|
137
|
+
# @api private
|
138
|
+
def delete(path, options = {}, &blk)
|
139
|
+
super(@prefix.join(path), options, &blk)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Support for TRACE HTTP verb
|
143
|
+
#
|
144
|
+
# @see Lotus::Router#trace
|
145
|
+
#
|
146
|
+
# @since 0.4.1
|
147
|
+
# @api private
|
148
|
+
def trace(path, options = {}, &blk)
|
149
|
+
super(@prefix.join(path), options, &blk)
|
150
|
+
end
|
151
|
+
|
88
152
|
# Support for OPTIONS HTTP verb
|
89
153
|
#
|
90
154
|
# @see Lotus::Router#options
|
@@ -92,7 +156,7 @@ module Lotus
|
|
92
156
|
# @since 0.1.0
|
93
157
|
# @api private
|
94
158
|
def options(path, options = {}, &blk)
|
95
|
-
add_with_request_method(path, :options, options, &blk)
|
159
|
+
add_with_request_method(@prefix.join(path), :options, options, &blk)
|
96
160
|
end
|
97
161
|
|
98
162
|
# Allow to mount a Rack app
|
@@ -109,7 +173,11 @@ module Lotus
|
|
109
173
|
|
110
174
|
# @api private
|
111
175
|
def raw_call(env, &blk)
|
112
|
-
|
176
|
+
if response = @force_ssl.call(env)
|
177
|
+
response
|
178
|
+
else
|
179
|
+
super(@parsers.call(env))
|
180
|
+
end
|
113
181
|
end
|
114
182
|
|
115
183
|
# @api private
|
@@ -57,6 +57,12 @@ module Lotus
|
|
57
57
|
super(@name.join(path), options, &endpoint)
|
58
58
|
end
|
59
59
|
|
60
|
+
# @api private
|
61
|
+
# @since 0.1.0
|
62
|
+
def options(path, options = {}, &endpoint)
|
63
|
+
super(@name.join(path), options, &endpoint)
|
64
|
+
end
|
65
|
+
|
60
66
|
# @api private
|
61
67
|
# @since 0.1.0
|
62
68
|
def resource(name, options = {})
|
data/lotus-router.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.required_ruby_version = '>= 2.0.0'
|
21
21
|
|
22
22
|
spec.add_dependency 'http_router', '~> 0.11'
|
23
|
-
spec.add_dependency 'lotus-utils', '~> 0.
|
23
|
+
spec.add_dependency 'lotus-utils', '~> 0.5'
|
24
24
|
|
25
25
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
26
26
|
spec.add_development_dependency 'minitest', '~> 5'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lotus-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http_router
|
@@ -30,20 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0.
|
34
|
-
- - ">="
|
35
|
-
- !ruby/object:Gem::Version
|
36
|
-
version: 0.4.1
|
33
|
+
version: '0.5'
|
37
34
|
type: :runtime
|
38
35
|
prerelease: false
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
40
37
|
requirements:
|
41
38
|
- - "~>"
|
42
39
|
- !ruby/object:Gem::Version
|
43
|
-
version: '0.
|
44
|
-
- - ">="
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: 0.4.1
|
40
|
+
version: '0.5'
|
47
41
|
- !ruby/object:Gem::Dependency
|
48
42
|
name: bundler
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,6 +95,7 @@ files:
|
|
101
95
|
- lib/lotus/router/version.rb
|
102
96
|
- lib/lotus/routing/endpoint.rb
|
103
97
|
- lib/lotus/routing/endpoint_resolver.rb
|
98
|
+
- lib/lotus/routing/force_ssl.rb
|
104
99
|
- lib/lotus/routing/http_router.rb
|
105
100
|
- lib/lotus/routing/namespace.rb
|
106
101
|
- lib/lotus/routing/parsers.rb
|
@@ -135,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
135
130
|
version: '0'
|
136
131
|
requirements: []
|
137
132
|
rubyforge_project:
|
138
|
-
rubygems_version: 2.4.
|
133
|
+
rubygems_version: 2.4.8
|
139
134
|
signing_key:
|
140
135
|
specification_version: 4
|
141
136
|
summary: Rack compatible HTTP router for Ruby and Lotus
|