hanami-router 1.2.0 → 1.3.0.beta1
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 +9 -0
- data/README.md +21 -17
- data/hanami-router.gemspec +3 -3
- data/lib/hanami/middleware/body_parser.rb +98 -0
- data/lib/hanami/middleware/body_parser/json_parser.rb +33 -0
- data/lib/hanami/middleware/body_parser/parser.rb +61 -0
- data/lib/hanami/router/version.rb +1 -1
- data/lib/hanami/routing/force_ssl.rb +3 -0
- data/lib/hanami/routing/http_router.rb +4 -0
- metadata +14 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 55265d04629210abb763c78a81bd4507cbe271cb0a5da1662bb938a3fca9d409
|
4
|
+
data.tar.gz: c11974f4d0f047d1ae21342d936faba59125080e1ce093ef9d63ce7a0cf672a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75ca87dadac5a3eb8c099aa4a1977c271f1b24dcdd55cfd16a8fdf77c4e990ac074a84e651ad347bad9d202b2bed5e53f7dc43a64feaea96a8cb09adefd9428c
|
7
|
+
data.tar.gz: 685771d96a9c584a6bfee63ee90916648bf851c94b2dd1c1be69513b2f9b8b2ab6975b321fe4454047216e05a99c6431dc0c354309812ad260f2c8af058c86f9
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,15 @@
|
|
1
1
|
# Hanami::Router
|
2
2
|
Rack compatible HTTP router for Ruby
|
3
3
|
|
4
|
+
## v1.3.0.beta1 - 2018-08-08
|
5
|
+
### Added
|
6
|
+
- [Luca Guidi] Official support for JRuby 9.2.0.0
|
7
|
+
- [Gustavo Caso] Introduce `Hanami::Middleware::BodyParser` Rack middleware to parse payload of non-GET HTTP requests.
|
8
|
+
|
9
|
+
### Deprecated
|
10
|
+
- [Alfonso Uceda] Deprecate `Hanami::Router.new(force_ssl: true)`. Use webserver (eg. Nginx), Rack middleware (eg. `rack-ssl`), or another strategy to force HTTPS connection.
|
11
|
+
- [Gustavo Caso] Deprecate `Hanami::Router.new(body_parsers: [:json])`. Use `Hanami::Middleware::BodyParser` instead.
|
12
|
+
|
4
13
|
## v1.2.0 - 2018-04-11
|
5
14
|
|
6
15
|
## v1.2.0.rc2 - 2018-04-06
|
data/README.md
CHANGED
@@ -4,12 +4,12 @@ Rack compatible, lightweight and fast HTTP Router for Ruby and [Hanami](http://h
|
|
4
4
|
|
5
5
|
## Status
|
6
6
|
|
7
|
-
[](https://badge.fury.io/rb/hanami-router)
|
8
|
+
[](https://travis-ci.org/hanami/router)
|
9
|
+
[](https://circleci.com/gh/hanami/router/tree/master)
|
10
|
+
[](https://codecov.io/gh/hanami/router)
|
11
|
+
[](https://depfu.com/github/hanami/router?project=Bundler)
|
12
|
+
[](http://inch-ci.org/github/hanami/router)
|
13
13
|
|
14
14
|
## Contact
|
15
15
|
|
@@ -594,12 +594,14 @@ It comes with a built-in JSON parser and allows to pass custom parsers.
|
|
594
594
|
|
595
595
|
```ruby
|
596
596
|
require 'hanami/router'
|
597
|
+
require 'hanami/middleware/body_parser'
|
597
598
|
|
598
|
-
|
599
|
-
|
600
|
-
router = Hanami::Router.new(parsers: [:json]) do
|
601
|
-
patch '/books/:id', to: endpoint
|
599
|
+
app = Hanami::Router.new do
|
600
|
+
patch '/books/:id', to: ->(env) { [200, {},[env['router.params'].inspect]] }
|
602
601
|
end
|
602
|
+
|
603
|
+
use Hanami::Middleware::BodyParser, :json
|
604
|
+
run app
|
603
605
|
```
|
604
606
|
|
605
607
|
```shell
|
@@ -615,7 +617,7 @@ curl http://localhost:2300/books/1 \
|
|
615
617
|
If the json can't be parsed an exception is raised:
|
616
618
|
|
617
619
|
```ruby
|
618
|
-
Hanami::
|
620
|
+
Hanami::Middleware::BodyParser::BodyParsingError
|
619
621
|
```
|
620
622
|
|
621
623
|
##### `multi_json`
|
@@ -626,9 +628,10 @@ If you want to use a different JSON backend, include `multi_json` in your `Gemfi
|
|
626
628
|
|
627
629
|
```ruby
|
628
630
|
require 'hanami/router'
|
631
|
+
require 'hanami/middleware/body_parser'
|
629
632
|
|
630
633
|
# See Hanami::Routing::Parsing::Parser
|
631
|
-
class XmlParser
|
634
|
+
class XmlParser < Hanami::Middleware::BodyParser::Parser
|
632
635
|
def mime_types
|
633
636
|
['application/xml', 'text/xml']
|
634
637
|
end
|
@@ -637,15 +640,16 @@ class XmlParser
|
|
637
640
|
def parse(body)
|
638
641
|
# parse xml
|
639
642
|
rescue SomeXmlParsingError => e
|
640
|
-
raise Hanami::
|
643
|
+
raise Hanami::Middleware::BodyParser::BodyParsingError.new(e)
|
641
644
|
end
|
642
645
|
end
|
643
646
|
|
644
|
-
|
645
|
-
|
646
|
-
router = Hanami::Router.new(parsers: [XmlParser.new]) do
|
647
|
-
patch '/authors/:id', to: endpoint
|
647
|
+
app = Hanami::Router.new do
|
648
|
+
patch '/authors/:id', to: ->(env) { [200, {},[env['router.params'].inspect]] }
|
648
649
|
end
|
650
|
+
|
651
|
+
use Hanami::Middleware::BodyParser, XmlParser
|
652
|
+
run app
|
649
653
|
```
|
650
654
|
|
651
655
|
```shell
|
data/hanami-router.gemspec
CHANGED
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
|
|
21
21
|
|
22
22
|
spec.add_dependency 'rack', '~> 2.0'
|
23
23
|
spec.add_dependency 'http_router', '0.11.2'
|
24
|
-
spec.add_dependency 'hanami-utils', '~> 1.
|
24
|
+
spec.add_dependency 'hanami-utils', '~> 1.3.beta'
|
25
25
|
|
26
26
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
27
|
-
spec.add_development_dependency 'rake', '~>
|
28
|
-
spec.add_development_dependency 'rack-test', '~> 0
|
27
|
+
spec.add_development_dependency 'rake', '~> 12'
|
28
|
+
spec.add_development_dependency 'rack-test', '~> 1.0'
|
29
29
|
spec.add_development_dependency 'rspec', '~> 3.7'
|
30
30
|
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'hanami/middleware/body_parser/parser'
|
2
|
+
require 'hanami/utils/hash'
|
3
|
+
|
4
|
+
module Hanami
|
5
|
+
module Middleware
|
6
|
+
# @since 1.3.0
|
7
|
+
# @api private
|
8
|
+
class BodyParser
|
9
|
+
# @since 1.3.0
|
10
|
+
# @api private
|
11
|
+
CONTENT_TYPE = 'CONTENT_TYPE'.freeze
|
12
|
+
|
13
|
+
# @since 1.3.0
|
14
|
+
# @api private
|
15
|
+
MEDIA_TYPE_MATCHER = /\s*[;,]\s*/.freeze
|
16
|
+
|
17
|
+
# @since 1.3.0
|
18
|
+
# @api private
|
19
|
+
RACK_INPUT = 'rack.input'.freeze
|
20
|
+
|
21
|
+
# @since 1.3.0
|
22
|
+
# @api private
|
23
|
+
ROUTER_PARAMS = 'router.params'.freeze
|
24
|
+
|
25
|
+
# @api private
|
26
|
+
ROUTER_PARSED_BODY = 'router.parsed_body'.freeze
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
FALLBACK_KEY = '_'.freeze
|
30
|
+
|
31
|
+
def initialize(app, parsers)
|
32
|
+
@app = app
|
33
|
+
@parsers = build_parsers(parsers)
|
34
|
+
end
|
35
|
+
|
36
|
+
def call(env)
|
37
|
+
body = env[RACK_INPUT].read
|
38
|
+
return @app.call(env) if body.empty?
|
39
|
+
|
40
|
+
env[RACK_INPUT].rewind # somebody might try to read this stream
|
41
|
+
|
42
|
+
env[ROUTER_PARAMS] ||= {} # prepare params
|
43
|
+
env[ROUTER_PARSED_BODY] = _parse(env, body)
|
44
|
+
env[ROUTER_PARAMS] = _symbolize(env[ROUTER_PARSED_BODY]).merge(env[ROUTER_PARAMS])
|
45
|
+
|
46
|
+
@app.call(env)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def build_parsers(parsers)
|
52
|
+
result = Hash.new
|
53
|
+
args = Array(parsers)
|
54
|
+
return result if args.empty?
|
55
|
+
|
56
|
+
args.each do |arg|
|
57
|
+
parser = Parser.for(arg)
|
58
|
+
|
59
|
+
parser.mime_types.each do |mime|
|
60
|
+
result[mime] = parser
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
result.default = Parser.new
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
# @api private
|
69
|
+
def _symbolize(body)
|
70
|
+
if body.is_a?(Hash)
|
71
|
+
Utils::Hash.deep_symbolize(body)
|
72
|
+
else
|
73
|
+
{ FALLBACK_KEY => body }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# @api private
|
78
|
+
def _parse(env, body)
|
79
|
+
@parsers[
|
80
|
+
media_type(env)
|
81
|
+
].parse(body)
|
82
|
+
end
|
83
|
+
|
84
|
+
# @api private
|
85
|
+
def media_type(env)
|
86
|
+
if ct = content_type(env)
|
87
|
+
ct.split(MEDIA_TYPE_MATCHER, 2).first.downcase
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# @api private
|
92
|
+
def content_type(env)
|
93
|
+
content_type = env[CONTENT_TYPE]
|
94
|
+
content_type.nil? || content_type.empty? ? nil : content_type
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'hanami/utils/json'
|
2
|
+
|
3
|
+
module Hanami
|
4
|
+
module Middleware
|
5
|
+
class BodyParser
|
6
|
+
# @since 1.3.0
|
7
|
+
# @api private
|
8
|
+
class JsonParser < Parser
|
9
|
+
# @since 1.3.0
|
10
|
+
# @api private
|
11
|
+
def mime_types
|
12
|
+
['application/json', 'application/vnd.api+json']
|
13
|
+
end
|
14
|
+
|
15
|
+
# Parse a json string
|
16
|
+
#
|
17
|
+
# @param body [String] a json string
|
18
|
+
#
|
19
|
+
# @return [Hash] the parsed json
|
20
|
+
#
|
21
|
+
# @raise [Hanami::Middleware::BodyParser::BodyParsingError] when the body can't be parsed.
|
22
|
+
#
|
23
|
+
# @since 1.3.0
|
24
|
+
# @api private
|
25
|
+
def parse(body)
|
26
|
+
Hanami::Utils::Json.parse(body)
|
27
|
+
rescue Hanami::Utils::Json::ParserError => e
|
28
|
+
raise BodyParsingError.new(e.message)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'hanami/utils/class'
|
2
|
+
require 'hanami/utils/string'
|
3
|
+
require 'hanami/routing/parsing/parser'
|
4
|
+
|
5
|
+
module Hanami
|
6
|
+
module Middleware
|
7
|
+
class BodyParser
|
8
|
+
# Body parsing error
|
9
|
+
# This is raised when parser fails to parse the body
|
10
|
+
#
|
11
|
+
# @since 1.3.0
|
12
|
+
class BodyParsingError < Hanami::Routing::Parsing::BodyParsingError
|
13
|
+
end
|
14
|
+
|
15
|
+
# @since 1.3.0
|
16
|
+
class UnknownParserError < Hanami::Routing::Parsing::UnknownParserError
|
17
|
+
end
|
18
|
+
|
19
|
+
# @since 1.3.0
|
20
|
+
class Parser
|
21
|
+
# @since 1.3.0
|
22
|
+
# @api private
|
23
|
+
def self.for(parser)
|
24
|
+
case parser
|
25
|
+
when String, Symbol
|
26
|
+
require_parser(parser)
|
27
|
+
else
|
28
|
+
raise UnknownParserError.new(parser) unless parser?(parser)
|
29
|
+
parser.new
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# @since 1.3.0
|
34
|
+
def mime_types
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
# @since 1.3.0
|
39
|
+
def parse(body)
|
40
|
+
body
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
# @since 1.3.0
|
45
|
+
# @api private
|
46
|
+
def self.require_parser(parser)
|
47
|
+
require "hanami/middleware/body_parser/#{ parser }_parser"
|
48
|
+
|
49
|
+
parser = Utils::String.classify(parser)
|
50
|
+
Utils::Class.load!("Hanami::Middleware::BodyParser::#{ parser }Parser").new
|
51
|
+
rescue LoadError, NameError
|
52
|
+
raise UnknownParserError.new(parser)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.parser?(parser)
|
56
|
+
parser.is_a?(Class) && parser < Parser
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rack/request'
|
2
|
+
require 'hanami/utils/deprecation'
|
2
3
|
|
3
4
|
module Hanami
|
4
5
|
module Routing
|
@@ -176,6 +177,8 @@ module Hanami
|
|
176
177
|
def _redefine_call
|
177
178
|
return unless @active
|
178
179
|
|
180
|
+
Hanami::Utils::Deprecation.new('force_ssl option is deprecated, please delegate this behaviour to Nginx/Apache or use a Rack middleware like `rack-ssl`')
|
181
|
+
|
179
182
|
define_singleton_method :call do |env|
|
180
183
|
[redirect_code(env), { LOCATION_HEADER => full_url(env) }, EMPTY_BODY] if force?(env)
|
181
184
|
end
|
@@ -67,6 +67,10 @@ module Hanami
|
|
67
67
|
# @since 0.1.0
|
68
68
|
# @api private
|
69
69
|
def initialize(options = {}, &blk)
|
70
|
+
if options[:parsers]
|
71
|
+
depecration_message = 'Hanami::Router options[:parsers] is deprecated and it will be removed in future versions'
|
72
|
+
Hanami::Utils::Deprecation.new(depecration_message)
|
73
|
+
end
|
70
74
|
@compiled = false
|
71
75
|
@uri_parser = URI::Parser.new
|
72
76
|
super(options, &nil)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami-router
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 1.3.beta
|
48
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
|
-
version:
|
54
|
+
version: 1.3.beta
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,28 +72,28 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
75
|
+
version: '12'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
82
|
+
version: '12'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rack-test
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
89
|
+
version: '1.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
96
|
+
version: '1.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: rspec
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -120,6 +120,9 @@ files:
|
|
120
120
|
- README.md
|
121
121
|
- hanami-router.gemspec
|
122
122
|
- lib/hanami-router.rb
|
123
|
+
- lib/hanami/middleware/body_parser.rb
|
124
|
+
- lib/hanami/middleware/body_parser/json_parser.rb
|
125
|
+
- lib/hanami/middleware/body_parser/parser.rb
|
123
126
|
- lib/hanami/router.rb
|
124
127
|
- lib/hanami/router/version.rb
|
125
128
|
- lib/hanami/routing/endpoint.rb
|
@@ -156,12 +159,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
159
|
version: 2.3.0
|
157
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
161
|
requirements:
|
159
|
-
- - "
|
162
|
+
- - ">"
|
160
163
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
164
|
+
version: 1.3.1
|
162
165
|
requirements: []
|
163
166
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.7.
|
167
|
+
rubygems_version: 2.7.7
|
165
168
|
signing_key:
|
166
169
|
specification_version: 4
|
167
170
|
summary: Rack compatible HTTP router for Ruby and Hanami
|