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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5d3df0ce6e2386faecda80095ebba0e81e5fd30737999c2e0446ae922f1c3df1
4
- data.tar.gz: d66331f4966e8deaae7adbccd8efe93295e3a11355cd86464bc542d0495b5a25
3
+ metadata.gz: 55265d04629210abb763c78a81bd4507cbe271cb0a5da1662bb938a3fca9d409
4
+ data.tar.gz: c11974f4d0f047d1ae21342d936faba59125080e1ce093ef9d63ce7a0cf672a9
5
5
  SHA512:
6
- metadata.gz: 57e694cbe56d1cbe8eafa82228000258fa04d9c597643e3b04c619308921c8df3841915348b6206f8e463b68e45760f308e3efc54fb6e6cc019f09da76b94489
7
- data.tar.gz: 157f72c97b99dfed376107a6d7e2e4d4d51f21654e58bf2ac9c3b316708666f41032b3f904d37ffe28b2405580e4863abe449f2ea0d29ecf221a908b6c574370
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
- [![Gem Version](http://img.shields.io/gem/v/hanami-router.svg)](https://badge.fury.io/rb/hanami-router)
8
- [![Build Status](http://img.shields.io/travis/hanami/router/master.svg)](https://travis-ci.org/hanami/router?branch=master)
9
- [![Coverage](http://img.shields.io/coveralls/hanami/router/master.svg)](https://coveralls.io/r/hanami/router)
10
- [![Code Climate](http://img.shields.io/codeclimate/github/hanami/router.svg)](https://codeclimate.com/github/hanami/router)
11
- [![Dependencies](http://img.shields.io/gemnasium/hanami/router.svg)](https://gemnasium.com/hanami/router)
12
- [![Inline docs](http://inch-ci.org/github/hanami/router.png)](http://inch-ci.org/github/hanami/router)
7
+ [![Gem Version](https://badge.fury.io/rb/hanami-router.svg)](https://badge.fury.io/rb/hanami-router)
8
+ [![TravisCI](https://travis-ci.org/hanami/router.svg?branch=master)](https://travis-ci.org/hanami/router)
9
+ [![CircleCI](https://circleci.com/gh/hanami/router/tree/master.svg?style=svg)](https://circleci.com/gh/hanami/router/tree/master)
10
+ [![Test Coverage](https://codecov.io/gh/hanami/router/branch/master/graph/badge.svg)](https://codecov.io/gh/hanami/router)
11
+ [![Depfu](https://badges.depfu.com/badges/5f6b8e8fa3b0d082539f0b0f84d55960/overview.svg)](https://depfu.com/github/hanami/router?project=Bundler)
12
+ [![Inline Docs](http://inch-ci.org/github/hanami/router.svg)](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
- endpoint = ->(env) { [200, {},[env['router.params'].inspect]] }
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::Routing::Parsing::BodyParsingError
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::Routing::Parsing::BodyParsingError.new(e)
643
+ raise Hanami::Middleware::BodyParser::BodyParsingError.new(e)
641
644
  end
642
645
  end
643
646
 
644
- endpoint = ->(env) { [200, {},[env['router.params'].inspect]] }
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
@@ -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.2'
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', '~> 11'
28
- spec.add_development_dependency 'rack-test', '~> 0.6'
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,6 +1,6 @@
1
1
  module Hanami
2
2
  class Router
3
3
  # @since 0.1.0
4
- VERSION = '1.2.0'.freeze
4
+ VERSION = '1.3.0.beta1'.freeze
5
5
  end
6
6
  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.2.0
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-04-11 00:00:00.000000000 Z
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: '1.2'
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: '1.2'
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: '11'
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: '11'
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.6'
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.6'
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: '0'
164
+ version: 1.3.1
162
165
  requirements: []
163
166
  rubyforge_project:
164
- rubygems_version: 2.7.6
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