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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3fcb5db6c1bdb046aeb93c5d0950301d5ed551d
4
- data.tar.gz: 577b5c170f3d469369ce4c43c11782f6f9d6ea3c
3
+ metadata.gz: fe3bedc422dfc753499bc3b622eae9991fbb5f6d
4
+ data.tar.gz: 04092313d4a1f9c19f83e4f555b4da56394b33ba
5
5
  SHA512:
6
- metadata.gz: 189025ab49239109b74a6f939585d2cdc56b7568a9864c0a82af39fc166a36b8f4f4ae7e5335a53b5ca3bcadd2120b75705ca6dc8d12a1b9bf05501aaa45f652
7
- data.tar.gz: 339c1ac13cb39971e7594675646b2c7f2a0baafa96a5bd7b44c16be0ce291d089857abbd797ab6fa6be44fa1b7a279c1d159562acd1d46c60ba97c43779d102f
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
@@ -1,6 +1,6 @@
1
1
  module Lotus
2
2
  class Router
3
3
  # @since 0.1.0
4
- VERSION = '0.4.0'.freeze
4
+ VERSION = '0.4.1'.freeze
5
5
  end
6
6
  end
@@ -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 = options[:scheme] if options[:scheme]
41
- @default_host = options[:host] if options[:host]
42
- @default_port = options[:port] if options[:port]
43
- @route_class = options[:route] || Routing::Route
44
- @resolver = options[:resolver] || Routing::EndpointResolver.new(options)
45
- @parsers = Routing::Parsers.new(options[: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
- super(@parsers.call(env))
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.4', '>= 0.4.1'
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.0
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-05-15 00:00:00.000000000 Z
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.4'
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.4'
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.5
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