lotus-router 0.4.0 → 0.4.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.
- 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
|