hanami-router 1.2.0 → 1.3.0.beta1

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
  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