hanami 1.3.1 → 2.0.0.alpha2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +110 -6
  3. data/FEATURES.md +9 -1
  4. data/LICENSE.md +1 -1
  5. data/README.md +4 -5
  6. data/hanami.gemspec +26 -30
  7. data/lib/hanami.rb +40 -243
  8. data/lib/hanami/application.rb +338 -174
  9. data/lib/hanami/application/autoloader/inflector_adapter.rb +22 -0
  10. data/lib/hanami/application/container/boot/inflector.rb +7 -0
  11. data/lib/hanami/application/container/boot/logger.rb +8 -0
  12. data/lib/hanami/application/container/boot/rack_logger.rb +19 -0
  13. data/lib/hanami/application/container/boot/rack_monitor.rb +12 -0
  14. data/lib/hanami/application/container/boot/settings.rb +7 -0
  15. data/lib/hanami/application/router.rb +59 -0
  16. data/lib/hanami/application/routing/middleware/stack.rb +89 -0
  17. data/lib/hanami/application/routing/resolver.rb +82 -0
  18. data/lib/hanami/application/routing/resolver/node.rb +50 -0
  19. data/lib/hanami/application/routing/resolver/trie.rb +59 -0
  20. data/lib/hanami/application/settings.rb +23 -0
  21. data/lib/hanami/application/settings/definition.rb +26 -0
  22. data/lib/hanami/application/settings/loader.rb +97 -0
  23. data/lib/hanami/application/settings/struct.rb +65 -0
  24. data/lib/hanami/boot.rb +5 -0
  25. data/lib/hanami/cli/application/cli.rb +40 -0
  26. data/lib/hanami/cli/application/command.rb +47 -0
  27. data/lib/hanami/cli/application/commands.rb +16 -0
  28. data/lib/hanami/cli/application/commands/console.rb +81 -0
  29. data/lib/hanami/cli/base_command.rb +48 -0
  30. data/lib/hanami/cli/commands.rb +6 -42
  31. data/lib/hanami/cli/commands/command.rb +20 -30
  32. data/lib/hanami/cli/commands/server.rb +63 -14
  33. data/lib/hanami/configuration.rb +248 -190
  34. data/lib/hanami/configuration/middleware.rb +8 -28
  35. data/lib/hanami/configuration/router.rb +50 -0
  36. data/lib/hanami/configuration/sessions.rb +50 -0
  37. data/lib/hanami/init.rb +5 -0
  38. data/lib/hanami/server.rb +5 -69
  39. data/lib/hanami/setup.rb +8 -2
  40. data/lib/hanami/slice.rb +138 -0
  41. data/lib/hanami/version.rb +3 -1
  42. data/lib/hanami/web/rack_logger.rb +96 -0
  43. metadata +84 -228
  44. data/bin/hanami +0 -6
  45. data/lib/hanami/action/csrf_protection.rb +0 -211
  46. data/lib/hanami/action/routing_helpers.rb +0 -40
  47. data/lib/hanami/app.rb +0 -96
  48. data/lib/hanami/application_configuration.rb +0 -1495
  49. data/lib/hanami/application_name.rb +0 -108
  50. data/lib/hanami/application_namespace.rb +0 -14
  51. data/lib/hanami/assets/asset.rb +0 -72
  52. data/lib/hanami/assets/static.rb +0 -102
  53. data/lib/hanami/cli/commands/assets.rb +0 -16
  54. data/lib/hanami/cli/commands/assets/precompile.rb +0 -42
  55. data/lib/hanami/cli/commands/console.rb +0 -95
  56. data/lib/hanami/cli/commands/db.rb +0 -32
  57. data/lib/hanami/cli/commands/db/apply.rb +0 -32
  58. data/lib/hanami/cli/commands/db/console.rb +0 -44
  59. data/lib/hanami/cli/commands/db/create.rb +0 -32
  60. data/lib/hanami/cli/commands/db/drop.rb +0 -32
  61. data/lib/hanami/cli/commands/db/migrate.rb +0 -39
  62. data/lib/hanami/cli/commands/db/prepare.rb +0 -32
  63. data/lib/hanami/cli/commands/db/rollback.rb +0 -59
  64. data/lib/hanami/cli/commands/db/version.rb +0 -32
  65. data/lib/hanami/cli/commands/destroy.rb +0 -26
  66. data/lib/hanami/cli/commands/destroy/action.rb +0 -137
  67. data/lib/hanami/cli/commands/destroy/app.rb +0 -159
  68. data/lib/hanami/cli/commands/destroy/mailer.rb +0 -74
  69. data/lib/hanami/cli/commands/destroy/migration.rb +0 -51
  70. data/lib/hanami/cli/commands/destroy/model.rb +0 -84
  71. data/lib/hanami/cli/commands/generate.rb +0 -28
  72. data/lib/hanami/cli/commands/generate/action.rb +0 -321
  73. data/lib/hanami/cli/commands/generate/action/action.erb +0 -7
  74. data/lib/hanami/cli/commands/generate/action/action_spec.minitest.erb +0 -11
  75. data/lib/hanami/cli/commands/generate/action/action_spec.rspec.erb +0 -9
  76. data/lib/hanami/cli/commands/generate/action/action_without_view.erb +0 -7
  77. data/lib/hanami/cli/commands/generate/action/view.erb +0 -7
  78. data/lib/hanami/cli/commands/generate/action/view_spec.minitest.erb +0 -12
  79. data/lib/hanami/cli/commands/generate/action/view_spec.rspec.erb +0 -10
  80. data/lib/hanami/cli/commands/generate/app.rb +0 -243
  81. data/lib/hanami/cli/commands/generate/app/application.erb +0 -313
  82. data/lib/hanami/cli/commands/generate/app/favicon.ico +0 -0
  83. data/lib/hanami/cli/commands/generate/app/gitkeep.erb +0 -0
  84. data/lib/hanami/cli/commands/generate/app/layout.erb +0 -7
  85. data/lib/hanami/cli/commands/generate/app/layout_spec.minitest.erb +0 -10
  86. data/lib/hanami/cli/commands/generate/app/layout_spec.rspec.erb +0 -10
  87. data/lib/hanami/cli/commands/generate/app/routes.erb +0 -5
  88. data/lib/hanami/cli/commands/generate/app/template.erb.erb +0 -10
  89. data/lib/hanami/cli/commands/generate/app/template.haml.erb +0 -7
  90. data/lib/hanami/cli/commands/generate/app/template.slim.erb +0 -8
  91. data/lib/hanami/cli/commands/generate/mailer.rb +0 -104
  92. data/lib/hanami/cli/commands/generate/mailer/mailer.erb +0 -9
  93. data/lib/hanami/cli/commands/generate/mailer/mailer_spec.minitest.erb +0 -7
  94. data/lib/hanami/cli/commands/generate/mailer/mailer_spec.rspec.erb +0 -5
  95. data/lib/hanami/cli/commands/generate/migration.rb +0 -41
  96. data/lib/hanami/cli/commands/generate/migration/migration.erb +0 -4
  97. data/lib/hanami/cli/commands/generate/model.rb +0 -125
  98. data/lib/hanami/cli/commands/generate/model/entity.erb +0 -2
  99. data/lib/hanami/cli/commands/generate/model/entity_spec.minitest.erb +0 -5
  100. data/lib/hanami/cli/commands/generate/model/entity_spec.rspec.erb +0 -3
  101. data/lib/hanami/cli/commands/generate/model/migration.erb +0 -10
  102. data/lib/hanami/cli/commands/generate/model/repository.erb +0 -5
  103. data/lib/hanami/cli/commands/generate/model/repository_spec.minitest.erb +0 -5
  104. data/lib/hanami/cli/commands/generate/model/repository_spec.rspec.erb +0 -3
  105. data/lib/hanami/cli/commands/generate/secret.rb +0 -48
  106. data/lib/hanami/cli/commands/new.rb +0 -578
  107. data/lib/hanami/cli/commands/new/.env.development.erb +0 -3
  108. data/lib/hanami/cli/commands/new/.env.test.erb +0 -3
  109. data/lib/hanami/cli/commands/new/.gitkeep.erb +0 -0
  110. data/lib/hanami/cli/commands/new/Gemfile.erb +0 -58
  111. data/lib/hanami/cli/commands/new/README.md.erb +0 -33
  112. data/lib/hanami/cli/commands/new/config.ru.erb +0 -3
  113. data/lib/hanami/cli/commands/new/config/boot.erb +0 -2
  114. data/lib/hanami/cli/commands/new/config/environment.erb +0 -49
  115. data/lib/hanami/cli/commands/new/gitignore.erb +0 -2
  116. data/lib/hanami/cli/commands/new/gitignore_with_sqlite.erb +0 -3
  117. data/lib/hanami/cli/commands/new/hanamirc.erb +0 -3
  118. data/lib/hanami/cli/commands/new/lib/project.erb +0 -2
  119. data/lib/hanami/cli/commands/new/minitest/Rakefile.erb +0 -12
  120. data/lib/hanami/cli/commands/new/minitest/features_helper.erb +0 -11
  121. data/lib/hanami/cli/commands/new/minitest/spec_helper.erb +0 -7
  122. data/lib/hanami/cli/commands/new/rspec/Rakefile.erb +0 -9
  123. data/lib/hanami/cli/commands/new/rspec/capybara.erb +0 -8
  124. data/lib/hanami/cli/commands/new/rspec/features_helper.erb +0 -12
  125. data/lib/hanami/cli/commands/new/rspec/rspec.erb +0 -2
  126. data/lib/hanami/cli/commands/new/rspec/spec_helper.erb +0 -103
  127. data/lib/hanami/cli/commands/new/schema.sql.erb +0 -0
  128. data/lib/hanami/cli/commands/project.rb +0 -421
  129. data/lib/hanami/cli/commands/routes.rb +0 -21
  130. data/lib/hanami/cli/commands/templates.rb +0 -31
  131. data/lib/hanami/cli/commands/version.rb +0 -19
  132. data/lib/hanami/common_logger.rb +0 -93
  133. data/lib/hanami/components.rb +0 -156
  134. data/lib/hanami/components/app/assets.rb +0 -59
  135. data/lib/hanami/components/app/controller.rb +0 -74
  136. data/lib/hanami/components/app/routes.rb +0 -59
  137. data/lib/hanami/components/app/view.rb +0 -44
  138. data/lib/hanami/components/component.rb +0 -182
  139. data/lib/hanami/components/components.rb +0 -479
  140. data/lib/hanami/components/routes_inspector.rb +0 -72
  141. data/lib/hanami/config/cookies.rb +0 -69
  142. data/lib/hanami/config/framework_configuration.rb +0 -43
  143. data/lib/hanami/config/load_paths.rb +0 -46
  144. data/lib/hanami/config/mapper.rb +0 -47
  145. data/lib/hanami/config/routes.rb +0 -20
  146. data/lib/hanami/config/security.rb +0 -110
  147. data/lib/hanami/config/sessions.rb +0 -103
  148. data/lib/hanami/configuration/app.rb +0 -18
  149. data/lib/hanami/early_hints.rb +0 -129
  150. data/lib/hanami/env.rb +0 -69
  151. data/lib/hanami/environment.rb +0 -513
  152. data/lib/hanami/environment_application_configurations.rb +0 -37
  153. data/lib/hanami/frameworks.rb +0 -22
  154. data/lib/hanami/hanamirc.rb +0 -169
  155. data/lib/hanami/mailer/glue.rb +0 -27
  156. data/lib/hanami/middleware_stack.rb +0 -172
  157. data/lib/hanami/rake_helper.rb +0 -78
  158. data/lib/hanami/rake_tasks.rb +0 -2
  159. data/lib/hanami/rendering_policy.rb +0 -95
  160. data/lib/hanami/routes.rb +0 -219
  161. data/lib/hanami/routing/default.rb +0 -32
  162. data/lib/hanami/static.rb +0 -63
  163. data/lib/hanami/templates/default.html.erb +0 -30
  164. data/lib/hanami/templates/welcome.html.erb +0 -52
  165. data/lib/hanami/views/default.rb +0 -37
  166. data/lib/hanami/views/default_template_finder.rb +0 -22
  167. data/lib/hanami/views/null_view.rb +0 -15
  168. data/lib/hanami/welcome.rb +0 -36
@@ -1,40 +1,20 @@
1
- require "concurrent"
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Hanami
4
- # @api private
5
4
  class Configuration
6
- # Middleware configuration
7
- # @since 1.2.0
5
+ # Hanami application configured Rack middleware
6
+ #
7
+ # @since 2.0.0
8
8
  class Middleware
9
- # @api private
10
- # @since 1.2.0
11
9
  def initialize
12
- @middleware = Concurrent::Array.new
10
+ @stack = []
13
11
  end
14
12
 
15
- # Use a Rack middleware
16
- #
17
- # @param middleware [#call] a Rack middleware
18
- # @param args [Array<Object>] an optional set of options
19
- # @param blk [Proc] an optional block to pass to the middleware
20
- #
21
- # @since 1.2.0
22
- #
23
- # @example
24
- # # config/environment.rb
25
- # # ...
26
- # Hanami.configure do
27
- # middleware.use MyRackMiddleware
28
- # end
29
- def use(middleware, *args, &blk)
30
- @middleware.push([middleware, args, blk])
13
+ def use(middleware, *args, &block)
14
+ stack.push([middleware, *args, block].compact)
31
15
  end
32
16
 
33
- # @api private
34
- # @since 1.2.0
35
- def each(&blk)
36
- @middleware.each(&blk)
37
- end
17
+ attr_reader :stack
38
18
  end
39
19
  end
40
20
  end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hanami
4
+ class Configuration
5
+ # Hanami router configuration
6
+ #
7
+ # @since 2.0.0
8
+ # @api private
9
+ class Router
10
+ # @api private
11
+ # @since 2.0.0
12
+ attr_writer :routes
13
+
14
+ # @api private
15
+ # @since 2.0.0
16
+ attr_reader :routes
17
+
18
+ # @api private
19
+ # @since 2.0.0
20
+ attr_writer :resolver
21
+
22
+ # @api private
23
+ # @since 2.0.0
24
+ def initialize(base_url, routes: DEFAULT_ROUTES)
25
+ @base_url = base_url
26
+ @routes = routes
27
+ end
28
+
29
+ # @api private
30
+ # @since 2.0.0
31
+ def resolver
32
+ @resolver ||= begin
33
+ require_relative "../application/routing/resolver"
34
+ Application::Routing::Resolver
35
+ end
36
+ end
37
+
38
+ # @api private
39
+ # @since 2.0.0
40
+ def options
41
+ { base_url: @base_url }
42
+ end
43
+
44
+ # @api private
45
+ # @since 2.0.0
46
+ DEFAULT_ROUTES = File.join("config", "routes")
47
+ private_constant :DEFAULT_ROUTES
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami/utils/string"
4
+ require "hanami/utils/class"
5
+
6
+ module Hanami
7
+ class Configuration
8
+ # Hanami configuration for HTTP sessions
9
+ #
10
+ # @since 2.0.0
11
+ class Sessions
12
+ def self.null
13
+ NULL_STORAGE
14
+ end
15
+
16
+ attr_reader :storage, :options
17
+
18
+ def initialize(*args)
19
+ storage, options, = Array(args.dup).flatten
20
+
21
+ @storage = storage
22
+ @options = options || {}
23
+ end
24
+
25
+ def enabled?
26
+ storage != NULL_STORAGE
27
+ end
28
+
29
+ def middleware
30
+ [[storage_middleware, options]]
31
+ end
32
+
33
+ private
34
+
35
+ NULL_STORAGE = :null
36
+ private_constant :NULL_STORAGE
37
+
38
+ def storage_middleware
39
+ require_storage
40
+
41
+ name = Utils::String.classify(storage)
42
+ Utils::Class.load!(name, Rack::Session)
43
+ end
44
+
45
+ def require_storage
46
+ require "rack/session/#{storage}"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "setup"
4
+
5
+ Hanami.init
data/lib/hanami/server.rb CHANGED
@@ -1,4 +1,7 @@
1
- require 'rack'
1
+ # frozen_string_literal: true
2
+
3
+ require "hanami"
4
+ require "rack"
2
5
 
3
6
  module Hanami
4
7
  # Rack compatible server.
@@ -13,81 +16,14 @@ module Hanami
13
16
  # @since 0.8.0
14
17
  # @api private
15
18
  class Server < ::Rack::Server
16
- # @api private
17
- attr_reader :options
18
-
19
- # @since 0.8.0
20
- # @api private
21
- #
22
- # @see Hanami::Environment#initialize
23
- def initialize
24
- @options = _extract_options
25
- setup
26
- end
27
-
28
19
  # Primarily this removes the ::Rack::Chunked middleware
29
20
  # which is the cause of Safari content-length bugs.
30
21
  #
31
22
  # @since 0.8.0
32
23
  def middleware
33
- mw = Hash.new { |e, m| e[m] = [] }
24
+ mw = ::Hash.new { |e, m| e[m] = [] }
34
25
  mw["development"].concat([::Rack::ShowExceptions, ::Rack::Lint])
35
- require 'hanami/assets/static'
36
- mw["development"].push(::Hanami::Assets::Static)
37
26
  mw
38
27
  end
39
-
40
- # @api private
41
- def start
42
- preload
43
- super
44
- end
45
-
46
- private
47
-
48
- # @api private
49
- def setup
50
- return unless code_reloading?
51
- @app = Shotgun::Loader.new(rackup)
52
- end
53
-
54
- # @api private
55
- def environment
56
- Components['environment']
57
- end
58
-
59
- # @since 0.8.0
60
- # @api private
61
- def code_reloading?
62
- Hanami.code_reloading?
63
- end
64
-
65
- # @api private
66
- def rackup
67
- environment.rackup.to_s
68
- end
69
-
70
- # @api private
71
- def preload
72
- if code_reloading?
73
- Shotgun.enable_copy_on_write
74
- Shotgun.preload
75
- else
76
- Hanami.boot
77
- end
78
- end
79
-
80
- # Options for Rack::Server superclass
81
- #
82
- # @since 0.8.0
83
- # @api private
84
- def _extract_options
85
- environment.to_options.merge(
86
- config: rackup,
87
- Host: environment.host,
88
- Port: environment.port,
89
- AccessLog: []
90
- )
91
- end
92
28
  end
93
29
  end
data/lib/hanami/setup.rb CHANGED
@@ -1,3 +1,9 @@
1
- require 'hanami'
1
+ # frozen_string_literal: true
2
2
 
3
- Bundler.require(*Hanami::Environment.new.bundler_groups)
3
+ require "bundler/setup"
4
+ require "hanami"
5
+
6
+ begin
7
+ require File.join(Dir.pwd, "config/application")
8
+ rescue LoadError # rubocop:disable Lint/SuppressedException
9
+ end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry/system/container"
4
+ require "pathname"
5
+
6
+ module Hanami
7
+ # Distinct area of concern within an Hanami application
8
+ #
9
+ # @since 2.0.0
10
+ class Slice
11
+ attr_reader :application, :name, :namespace, :root
12
+
13
+ def initialize(application, name:, namespace: nil, root: nil, container: nil)
14
+ @application = application
15
+ @name = name.to_sym
16
+ @namespace = namespace
17
+ @root = root ? Pathname(root) : root
18
+ @container = container || define_container
19
+ end
20
+
21
+ def inflector
22
+ application.inflector
23
+ end
24
+
25
+ def namespace_path
26
+ @namespace_path ||= inflector.underscore(namespace.to_s)
27
+ end
28
+
29
+ def init
30
+ container.import application: application.container
31
+
32
+ slice_block = application.configuration.slices[name]
33
+ instance_eval(&slice_block) if slice_block
34
+ end
35
+
36
+ def boot
37
+ container.finalize! do
38
+ container.config.env = application.container.config.env
39
+ end
40
+
41
+ @booted = true
42
+ self
43
+ end
44
+
45
+ # rubocop:disable Style/DoubleNegation
46
+ def booted?
47
+ !!@booted
48
+ end
49
+ # rubocop:enable Style/DoubleNegation
50
+
51
+ def container
52
+ @container ||= define_container
53
+ end
54
+
55
+ def import(*slice_names)
56
+ raise "Cannot import after booting" if booted?
57
+
58
+ slice_names.each do |slice_name|
59
+ container.import slice_name.to_sym => application.slices.fetch(slice_name.to_sym).container
60
+ end
61
+ end
62
+
63
+ def register(*args, &block)
64
+ container.register(*args, &block)
65
+ end
66
+
67
+ def register_bootable(*args, &block)
68
+ container.boot(*args, &block)
69
+ end
70
+
71
+ def init_bootable(*args)
72
+ container.init(*args)
73
+ end
74
+
75
+ def start_bootable(*args)
76
+ container.start(*args)
77
+ end
78
+
79
+ def key?(*args)
80
+ container.key?(*args)
81
+ end
82
+
83
+ def keys
84
+ container.keys
85
+ end
86
+
87
+ def [](*args)
88
+ container[*args]
89
+ end
90
+
91
+ def resolve(*args)
92
+ container.resolve(*args)
93
+ end
94
+
95
+ private
96
+
97
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
98
+ def define_container
99
+ container = Class.new(Dry::System::Container)
100
+ container.use :env
101
+
102
+ container.configure do |config|
103
+ config.name = name
104
+ config.inflector = application.configuration.inflector
105
+
106
+ if application.configuration.autoloader
107
+ require "dry/system/loader/autoloading"
108
+ config.component_dirs.loader = Dry::System::Loader::Autoloading
109
+ config.component_dirs.add_to_load_path = false
110
+ end
111
+
112
+ if root&.directory?
113
+ config.root = root
114
+ config.bootable_dirs = ["config/boot"]
115
+
116
+ if root.join("lib").directory?
117
+ config.component_dirs.add "lib" do |dir|
118
+ dir.default_namespace = namespace_path.tr(File::SEPARATOR, config.namespace_separator)
119
+ end
120
+
121
+ application.configuration.autoloader&.push_dir(root.join("lib"))
122
+ end
123
+ end
124
+ end
125
+
126
+ # Force after configure hook to run
127
+ container.configure do; end
128
+
129
+ if namespace
130
+ namespace.const_set :Container, container
131
+ namespace.const_set :Deps, container.injector
132
+ end
133
+
134
+ container
135
+ end
136
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
137
+ end
138
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Hanami
2
4
  # Hanami version
3
5
  #
@@ -6,7 +8,7 @@ module Hanami
6
8
  module Version
7
9
  # @since 0.9.0
8
10
  # @api private
9
- VERSION = '1.3.1'.freeze
11
+ VERSION = "2.0.0.alpha2"
10
12
 
11
13
  # @since 0.9.0
12
14
  # @api private
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+ require "rack/request"
5
+ require "hanami/utils/hash"
6
+
7
+ module Hanami
8
+ module Web
9
+ # Rack logger for Hanami applications
10
+ class RackLogger
11
+ attr_reader :logger
12
+ attr_reader :filter_params
13
+
14
+ def initialize(logger, filter_params: [])
15
+ @logger = logger
16
+ @filter_params = filter_params
17
+ end
18
+
19
+ def attach(rack_monitor)
20
+ rack_monitor.on :stop do |event|
21
+ log_request event[:env], event[:status], event[:time]
22
+ end
23
+
24
+ rack_monitor.on :error do |event|
25
+ log_exception event[:exception]
26
+ end
27
+ end
28
+
29
+ # rubocop:disable Metrics/MethodLength
30
+ def log_request(env, status, time)
31
+ data = {
32
+ http: env[HTTP_VERSION],
33
+ verb: env[REQUEST_METHOD],
34
+ status: status,
35
+ ip: env[HTTP_X_FORWARDED_FOR] || env[REMOTE_ADDR],
36
+ path: env[SCRIPT_NAME] + env[PATH_INFO].to_s,
37
+ length: extract_content_length(env),
38
+ params: extract_params(env),
39
+ elapsed: time,
40
+ }
41
+
42
+ logger.info JSON.generate(data)
43
+ end
44
+ # rubocop:enable Metrics/MethodLength
45
+
46
+ def log_exception(exception)
47
+ logger.error exception.message
48
+ logger.error exception.backtrace.join("\n")
49
+ end
50
+
51
+ private
52
+
53
+ HTTP_VERSION = "HTTP_VERSION"
54
+ REQUEST_METHOD = "REQUEST_METHOD"
55
+ HTTP_X_FORWARDED_FOR = "HTTP_X_FORWARDED_FOR"
56
+ REMOTE_ADDR = "REMOTE_ADDR"
57
+ SCRIPT_NAME = "SCRIPT_NAME"
58
+ PATH_INFO = "PATH_INFO"
59
+ RACK_ERRORS = "rack.errors"
60
+ QUERY_HASH = "rack.request.query_hash"
61
+ FORM_HASH = "rack.request.form_hash"
62
+ ROUTER_PARAMS = "router.params"
63
+ CONTENT_LENGTH = "Content-Length"
64
+
65
+ def extract_content_length(env)
66
+ value = env[CONTENT_LENGTH]
67
+ !value || value.to_s == "0" ? "-" : value
68
+ end
69
+
70
+ def extract_params(env)
71
+ result = env.fetch(QUERY_HASH, {})
72
+ result.merge!(env.fetch(FORM_HASH, {}))
73
+ result.merge!(Hanami::Utils::Hash.deep_stringify(env.fetch(ROUTER_PARAMS, {})))
74
+ result
75
+ end
76
+
77
+ FILTERED = "[FILTERED]"
78
+
79
+ # rubocop:disable Metrics/MethodLength
80
+ def filter(params)
81
+ params.each_with_object({}) do |(k, v), h|
82
+ if filter_params.include?(k)
83
+ h.update(k => FILTERED)
84
+ elsif v.is_a?(Hash)
85
+ h.update(k => filter(v))
86
+ elsif v.is_a?(Array)
87
+ h.update(k => v.map { |m| m.is_a?(Hash) ? filter(m) : m })
88
+ else
89
+ h[k] = v
90
+ end
91
+ end
92
+ end
93
+ # rubocop:enable Metrics/MethodLength
94
+ end
95
+ end
96
+ end