puma 5.6.4 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puma might be problematic. Click here for more details.

Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +136 -3
  3. data/README.md +21 -17
  4. data/bin/puma-wild +1 -1
  5. data/docs/compile_options.md +34 -0
  6. data/docs/fork_worker.md +1 -3
  7. data/docs/testing_benchmarks_local_files.md +150 -0
  8. data/docs/testing_test_rackup_ci_files.md +36 -0
  9. data/ext/puma_http11/extconf.rb +18 -10
  10. data/ext/puma_http11/http11_parser.c +1 -1
  11. data/ext/puma_http11/http11_parser.h +1 -1
  12. data/ext/puma_http11/http11_parser.java.rl +2 -2
  13. data/ext/puma_http11/http11_parser.rl +2 -2
  14. data/ext/puma_http11/http11_parser_common.rl +2 -2
  15. data/ext/puma_http11/mini_ssl.c +63 -24
  16. data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
  17. data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
  18. data/ext/puma_http11/org/jruby/puma/MiniSSL.java +166 -65
  19. data/ext/puma_http11/puma_http11.c +17 -9
  20. data/lib/puma/app/status.rb +6 -3
  21. data/lib/puma/binder.rb +37 -43
  22. data/lib/puma/cli.rb +11 -17
  23. data/lib/puma/client.rb +22 -12
  24. data/lib/puma/cluster/worker.rb +13 -11
  25. data/lib/puma/cluster/worker_handle.rb +4 -1
  26. data/lib/puma/cluster.rb +28 -25
  27. data/lib/puma/configuration.rb +74 -58
  28. data/lib/puma/const.rb +14 -18
  29. data/lib/puma/control_cli.rb +21 -18
  30. data/lib/puma/detect.rb +2 -0
  31. data/lib/puma/dsl.rb +94 -49
  32. data/lib/puma/error_logger.rb +17 -9
  33. data/lib/puma/events.rb +6 -126
  34. data/lib/puma/io_buffer.rb +29 -4
  35. data/lib/puma/jruby_restart.rb +2 -1
  36. data/lib/puma/launcher/bundle_pruner.rb +104 -0
  37. data/lib/puma/launcher.rb +107 -156
  38. data/lib/puma/log_writer.rb +137 -0
  39. data/lib/puma/minissl/context_builder.rb +23 -12
  40. data/lib/puma/minissl.rb +91 -15
  41. data/lib/puma/null_io.rb +5 -0
  42. data/lib/puma/plugin/tmp_restart.rb +1 -1
  43. data/lib/puma/rack/builder.rb +4 -4
  44. data/lib/puma/rack_default.rb +1 -1
  45. data/lib/puma/reactor.rb +3 -3
  46. data/lib/puma/request.rb +291 -156
  47. data/lib/puma/runner.rb +41 -20
  48. data/lib/puma/server.rb +53 -64
  49. data/lib/puma/single.rb +10 -10
  50. data/lib/puma/state_file.rb +2 -4
  51. data/lib/puma/systemd.rb +3 -2
  52. data/lib/puma/thread_pool.rb +16 -13
  53. data/lib/puma/util.rb +12 -14
  54. data/lib/puma.rb +11 -8
  55. data/lib/rack/handler/puma.rb +9 -9
  56. metadata +7 -3
  57. data/lib/puma/queue_close.rb +0 -26
data/lib/puma/runner.rb CHANGED
@@ -1,23 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'puma/server'
4
- require 'puma/const'
3
+ require_relative 'server'
4
+ require_relative 'const'
5
5
 
6
6
  module Puma
7
7
  # Generic class that is used by `Puma::Cluster` and `Puma::Single` to
8
8
  # serve requests. This class spawns a new instance of `Puma::Server` via
9
9
  # a call to `start_server`.
10
10
  class Runner
11
- def initialize(cli, events)
12
- @launcher = cli
13
- @events = events
14
- @options = cli.options
11
+ def initialize(launcher)
12
+ @launcher = launcher
13
+ @log_writer = launcher.log_writer
14
+ @events = launcher.events
15
+ @config = launcher.config
16
+ @options = launcher.options
15
17
  @app = nil
16
18
  @control = nil
17
19
  @started_at = Time.now
18
20
  @wakeup = nil
19
21
  end
20
22
 
23
+ # Returns the hash of configuration options.
24
+ # @return [Puma::UserFileDefaultOptions]
25
+ attr_reader :options
26
+
21
27
  def wakeup!
22
28
  return unless @wakeup
23
29
 
@@ -36,27 +42,27 @@ module Puma
36
42
  end
37
43
 
38
44
  def log(str)
39
- @events.log str
45
+ @log_writer.log str
40
46
  end
41
47
 
42
48
  # @version 5.0.0
43
49
  def stop_control
44
- @control.stop(true) if @control
50
+ @control&.stop true
45
51
  end
46
52
 
47
53
  def error(str)
48
- @events.error str
54
+ @log_writer.error str
49
55
  end
50
56
 
51
57
  def debug(str)
52
- @events.log "- #{str}" if @options[:debug]
58
+ @log_writer.log "- #{str}" if @options[:debug]
53
59
  end
54
60
 
55
61
  def start_control
56
62
  str = @options[:control_url]
57
63
  return unless str
58
64
 
59
- require 'puma/app/status'
65
+ require_relative 'app/status'
60
66
 
61
67
  if token = @options[:control_auth_token]
62
68
  token = nil if token.empty? || token == 'none'
@@ -64,10 +70,12 @@ module Puma
64
70
 
65
71
  app = Puma::App::Status.new @launcher, token
66
72
 
67
- control = Puma::Server.new app, @launcher.events,
68
- { min_threads: 0, max_threads: 1, queue_requests: false }
73
+ # A Reactor is not created aand nio4r is not loaded when 'queue_requests: false'
74
+ # Use `nil` for events, no hooks in control server
75
+ control = Puma::Server.new app, nil,
76
+ { min_threads: 0, max_threads: 1, queue_requests: false, log_writer: @log_writer }
69
77
 
70
- control.binder.parse [str], self, 'Starting control server'
78
+ control.binder.parse [str], nil, 'Starting control server'
71
79
 
72
80
  control.run thread_name: 'ctl'
73
81
  @control = control
@@ -141,29 +149,29 @@ module Puma
141
149
  end
142
150
 
143
151
  def load_and_bind
144
- unless @launcher.config.app_configured?
152
+ unless @config.app_configured?
145
153
  error "No application configured, nothing to run"
146
154
  exit 1
147
155
  end
148
156
 
149
157
  begin
150
- @app = @launcher.config.app
158
+ @app = @config.app
151
159
  rescue Exception => e
152
160
  log "! Unable to load application: #{e.class}: #{e.message}"
153
161
  raise e
154
162
  end
155
163
 
156
- @launcher.binder.parse @options[:binds], self
164
+ @launcher.binder.parse @options[:binds]
157
165
  end
158
166
 
159
167
  # @!attribute [r] app
160
168
  def app
161
- @app ||= @launcher.config.app
169
+ @app ||= @config.app
162
170
  end
163
171
 
164
172
  def start_server
165
- server = Puma::Server.new app, @launcher.events, @options
166
- server.inherit_binder @launcher.binder
173
+ server = Puma::Server.new(app, @events, @options)
174
+ server.inherit_binder(@launcher.binder)
167
175
  server
168
176
  end
169
177
 
@@ -173,5 +181,18 @@ module Puma
173
181
  raise "Cannot redirect #{io_name} to #{path}"
174
182
  end
175
183
  end
184
+
185
+ def stats
186
+ {
187
+ versions: {
188
+ puma: Puma::Const::PUMA_VERSION,
189
+ ruby: {
190
+ engine: RUBY_ENGINE,
191
+ version: RUBY_VERSION,
192
+ patchlevel: RUBY_PATCHLEVEL
193
+ }
194
+ }
195
+ }
196
+ end
176
197
  end
177
198
  end
data/lib/puma/server.rb CHANGED
@@ -2,19 +2,20 @@
2
2
 
3
3
  require 'stringio'
4
4
 
5
- require 'puma/thread_pool'
6
- require 'puma/const'
7
- require 'puma/events'
8
- require 'puma/null_io'
9
- require 'puma/reactor'
10
- require 'puma/client'
11
- require 'puma/binder'
12
- require 'puma/util'
13
- require 'puma/io_buffer'
14
- require 'puma/request'
5
+ require_relative 'thread_pool'
6
+ require_relative 'const'
7
+ require_relative 'log_writer'
8
+ require_relative 'events'
9
+ require_relative 'null_io'
10
+ require_relative 'reactor'
11
+ require_relative 'client'
12
+ require_relative 'binder'
13
+ require_relative 'util'
14
+ require_relative 'io_buffer'
15
+ require_relative 'request'
15
16
 
16
17
  require 'socket'
17
- require 'io/wait'
18
+ require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
18
19
  require 'forwardable'
19
20
 
20
21
  module Puma
@@ -30,12 +31,12 @@ module Puma
30
31
  #
31
32
  # Each `Puma::Server` will have one reactor and one thread pool.
32
33
  class Server
33
-
34
34
  include Puma::Const
35
35
  include Request
36
36
  extend Forwardable
37
37
 
38
38
  attr_reader :thread
39
+ attr_reader :log_writer
39
40
  attr_reader :events
40
41
  attr_reader :min_threads, :max_threads # for #stats
41
42
  attr_reader :requests_count # @version 5.0.0
@@ -45,11 +46,6 @@ module Puma
45
46
  :leak_stack_on_error,
46
47
  :persistent_timeout, :reaping_time
47
48
 
48
- # @deprecated v6.0.0
49
- attr_writer :auto_trim_time, :early_hints, :first_data_timeout,
50
- :leak_stack_on_error, :min_threads, :max_threads,
51
- :persistent_timeout, :reaping_time
52
-
53
49
  attr_accessor :app
54
50
  attr_accessor :binder
55
51
 
@@ -60,8 +56,9 @@ module Puma
60
56
 
61
57
  # Create a server for the rack app +app+.
62
58
  #
63
- # +events+ is an object which will be called when certain error events occur
64
- # to be handled. See Puma::Events for the list of current methods to implement.
59
+ # +log_writer+ is a Puma::LogWriter object used to log info and error messages.
60
+ #
61
+ # +events+ is a Puma::Events object used to notify application status events.
65
62
  #
66
63
  # Server#run returns a thread that you can join on to wait for the server
67
64
  # to do its work.
@@ -70,34 +67,40 @@ module Puma
70
67
  # and have default values set via +fetch+. Normally the values are set via
71
68
  # `::Puma::Configuration.puma_default_options`.
72
69
  #
73
- def initialize(app, events=Events.stdio, options={})
70
+ # @note The `events` parameter is set to nil, and set to `Events.new` in code.
71
+ # Often `options` needs to be passed, but `events` does not. Using nil allows
72
+ # calling code to not require events.rb.
73
+ #
74
+ def initialize(app, events = nil, options = {})
74
75
  @app = app
75
- @events = events
76
+ @events = events || Events.new
76
77
 
77
78
  @check, @notify = nil
78
79
  @status = :stop
79
80
 
80
- @auto_trim_time = 30
81
- @reaping_time = 1
82
-
83
81
  @thread = nil
84
82
  @thread_pool = nil
85
83
 
86
- @options = options
84
+ @options = if options.is_a?(UserFileDefaultOptions)
85
+ options
86
+ else
87
+ UserFileDefaultOptions.new(options, Configuration::DEFAULTS)
88
+ end
87
89
 
88
- @early_hints = options.fetch :early_hints, nil
89
- @first_data_timeout = options.fetch :first_data_timeout, FIRST_DATA_TIMEOUT
90
- @min_threads = options.fetch :min_threads, 0
91
- @max_threads = options.fetch :max_threads , (Puma.mri? ? 5 : 16)
92
- @persistent_timeout = options.fetch :persistent_timeout, PERSISTENT_TIMEOUT
93
- @queue_requests = options.fetch :queue_requests, true
94
- @max_fast_inline = options.fetch :max_fast_inline, MAX_FAST_INLINE
95
- @io_selector_backend = options.fetch :io_selector_backend, :auto
90
+ @log_writer = @options.fetch :log_writer, LogWriter.stdio
91
+ @early_hints = @options[:early_hints]
92
+ @first_data_timeout = @options[:first_data_timeout]
93
+ @min_threads = @options[:min_threads]
94
+ @max_threads = @options[:max_threads]
95
+ @persistent_timeout = @options[:persistent_timeout]
96
+ @queue_requests = @options[:queue_requests]
97
+ @max_fast_inline = @options[:max_fast_inline]
98
+ @io_selector_backend = @options[:io_selector_backend]
96
99
 
97
100
  temp = !!(@options[:environment] =~ /\A(development|test)\z/)
98
101
  @leak_stack_on_error = @options[:environment] ? temp : true
99
102
 
100
- @binder = Binder.new(events)
103
+ @binder = Binder.new(log_writer)
101
104
 
102
105
  ENV['RACK_ENV'] ||= "development"
103
106
 
@@ -193,12 +196,12 @@ module Puma
193
196
 
194
197
  # @!attribute [r] backlog
195
198
  def backlog
196
- @thread_pool and @thread_pool.backlog
199
+ @thread_pool&.backlog
197
200
  end
198
201
 
199
202
  # @!attribute [r] running
200
203
  def running
201
- @thread_pool and @thread_pool.spawned
204
+ @thread_pool&.spawned
202
205
  end
203
206
 
204
207
 
@@ -211,7 +214,7 @@ module Puma
211
214
  # value would be 4 until it finishes processing.
212
215
  # @!attribute [r] pool_capacity
213
216
  def pool_capacity
214
- @thread_pool and @thread_pool.pool_capacity
217
+ @thread_pool&.pool_capacity
215
218
  end
216
219
 
217
220
  # Runs the server.
@@ -227,29 +230,16 @@ module Puma
227
230
 
228
231
  @status = :run
229
232
 
230
- @thread_pool = ThreadPool.new(
231
- thread_name,
232
- @min_threads,
233
- @max_threads,
234
- ::Puma::IOBuffer,
235
- &method(:process_client)
236
- )
237
-
238
- @thread_pool.out_of_band_hook = @options[:out_of_band]
239
- @thread_pool.clean_thread_locals = @options[:clean_thread_locals]
233
+ @thread_pool = ThreadPool.new(thread_name, @options) { |a, b| process_client a, b }
240
234
 
241
235
  if @queue_requests
242
- @reactor = Reactor.new(@io_selector_backend, &method(:reactor_wakeup))
236
+ @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
243
237
  @reactor.run
244
238
  end
245
239
 
246
- if @reaping_time
247
- @thread_pool.auto_reap!(@reaping_time)
248
- end
249
240
 
250
- if @auto_trim_time
251
- @thread_pool.auto_trim!(@auto_trim_time)
252
- end
241
+ @thread_pool.auto_reap! if @options[:reaping_time]
242
+ @thread_pool.auto_trim! if @options[:auto_trim_time]
253
243
 
254
244
  @check, @notify = Puma::Util.pipe unless @notify
255
245
 
@@ -353,11 +343,11 @@ module Puma
353
343
  # In the case that any of the sockets are unexpectedly close.
354
344
  raise
355
345
  rescue StandardError => e
356
- @events.unknown_error e, nil, "Listen loop"
346
+ @log_writer.unknown_error e, nil, "Listen loop"
357
347
  end
358
348
  end
359
349
 
360
- @events.debug "Drained #{drain} additional connections." if drain
350
+ @log_writer.debug "Drained #{drain} additional connections." if drain
361
351
  @events.fire :state, @status
362
352
 
363
353
  if queue_requests
@@ -366,14 +356,13 @@ module Puma
366
356
  end
367
357
  graceful_shutdown if @status == :stop || @status == :restart
368
358
  rescue Exception => e
369
- @events.unknown_error e, nil, "Exception handling servers"
359
+ @log_writer.unknown_error e, nil, "Exception handling servers"
370
360
  ensure
371
- # RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
372
361
  # Errno::EBADF is infrequently raised
373
362
  [@check, @notify].each do |io|
374
363
  begin
375
364
  io.close unless io.closed?
376
- rescue Errno::EBADF, RuntimeError
365
+ rescue Errno::EBADF
377
366
  end
378
367
  end
379
368
  @notify = nil
@@ -488,7 +477,7 @@ module Puma
488
477
  Puma::Util.purge_interrupt_queue
489
478
  # Already closed
490
479
  rescue StandardError => e
491
- @events.unknown_error e, nil, "Client"
480
+ @log_writer.unknown_error e, nil, "Client"
492
481
  end
493
482
  end
494
483
  end
@@ -511,16 +500,16 @@ module Puma
511
500
  lowlevel_error(e, client.env)
512
501
  case e
513
502
  when MiniSSL::SSLError
514
- @events.ssl_error e, client.io
503
+ @log_writer.ssl_error e, client.io
515
504
  when HttpParserError
516
505
  client.write_error(400)
517
- @events.parse_error e, client
506
+ @log_writer.parse_error e, client
518
507
  when HttpParserError501
519
508
  client.write_error(501)
520
- @events.parse_error e, client
509
+ @log_writer.parse_error e, client
521
510
  else
522
511
  client.write_error(500)
523
- @events.unknown_error e, nil, "Read"
512
+ @log_writer.unknown_error e, nil, "Read"
524
513
  end
525
514
  end
526
515
 
data/lib/puma/single.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'puma/runner'
4
- require 'puma/detect'
5
- require 'puma/plugin'
3
+ require_relative 'runner'
4
+ require_relative 'detect'
5
+ require_relative 'plugin'
6
6
 
7
7
  module Puma
8
8
  # This class is instantiated by the `Puma::Launcher` and used
@@ -17,25 +17,25 @@ module Puma
17
17
  def stats
18
18
  {
19
19
  started_at: @started_at.utc.iso8601
20
- }.merge(@server.stats)
20
+ }.merge(@server.stats).merge(super)
21
21
  end
22
22
 
23
23
  def restart
24
- @server.begin_restart
24
+ @server&.begin_restart
25
25
  end
26
26
 
27
27
  def stop
28
- @server.stop(false) if @server
28
+ @server&.stop false
29
29
  end
30
30
 
31
31
  def halt
32
- @server.halt
32
+ @server&.halt
33
33
  end
34
34
 
35
35
  def stop_blocked
36
36
  log "- Gracefully stopping, waiting for requests to finish"
37
- @control.stop(true) if @control
38
- @server.stop(true) if @server
37
+ @control&.stop true
38
+ @server&.stop true
39
39
  end
40
40
 
41
41
  def run
@@ -55,7 +55,7 @@ module Puma
55
55
  log "Use Ctrl-C to stop"
56
56
  redirect_io
57
57
 
58
- @launcher.events.fire_on_booted!
58
+ @events.fire_on_booted!
59
59
 
60
60
  begin
61
61
  server_thread.join
@@ -15,15 +15,12 @@ module Puma
15
15
 
16
16
  ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from!
17
17
 
18
- # @deprecated 6.0.0
19
- FIELDS = ALLOWED_FIELDS
20
-
21
18
  def initialize
22
19
  @options = {}
23
20
  end
24
21
 
25
22
  def save(path, permission = nil)
26
- contents = "---\n".dup
23
+ contents = +"---\n"
27
24
  @options.each do |k,v|
28
25
  next unless ALLOWED_FIELDS.include? k
29
26
  case v
@@ -50,6 +47,7 @@ module Puma
50
47
  v = v.strip
51
48
  @options[k] =
52
49
  case v
50
+ when '' then nil
53
51
  when /\A\d+\z/ then v.to_i
54
52
  when /\A\d+\.\d+\z/ then v.to_f
55
53
  else v.gsub(/\A"|"\z/, '')
data/lib/puma/systemd.rb CHANGED
@@ -4,7 +4,8 @@ require 'sd_notify'
4
4
 
5
5
  module Puma
6
6
  class Systemd
7
- def initialize(events)
7
+ def initialize(log_writer, events)
8
+ @log_writer = log_writer
8
9
  @events = events
9
10
  end
10
11
 
@@ -40,7 +41,7 @@ module Puma
40
41
  end
41
42
 
42
43
  def log(str)
43
- @events.log str
44
+ @log_writer.log(str)
44
45
  end
45
46
  end
46
47
  end
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'thread'
4
4
 
5
+ require_relative 'io_buffer'
6
+
5
7
  module Puma
6
8
  # Internal Docs for A simple thread pool management object.
7
9
  #
@@ -29,7 +31,7 @@ module Puma
29
31
  # The block passed is the work that will be performed in each
30
32
  # thread.
31
33
  #
32
- def initialize(name, min, max, *extra, &block)
34
+ def initialize(name, options = {}, &block)
33
35
  @not_empty = ConditionVariable.new
34
36
  @not_full = ConditionVariable.new
35
37
  @mutex = Mutex.new
@@ -40,10 +42,14 @@ module Puma
40
42
  @waiting = 0
41
43
 
42
44
  @name = name
43
- @min = Integer(min)
44
- @max = Integer(max)
45
+ @min = Integer(options[:min_threads])
46
+ @max = Integer(options[:max_threads])
45
47
  @block = block
46
- @extra = extra
48
+ @extra = [::Puma::IOBuffer]
49
+ @out_of_band = options[:out_of_band]
50
+ @clean_thread_locals = options[:clean_thread_locals]
51
+ @reaping_time = options[:reaping_time]
52
+ @auto_trim_time = options[:auto_trim_time]
47
53
 
48
54
  @shutdown = false
49
55
 
@@ -62,14 +68,11 @@ module Puma
62
68
  end
63
69
  end
64
70
 
65
- @clean_thread_locals = false
66
71
  @force_shutdown = false
67
72
  @shutdown_mutex = Mutex.new
68
73
  end
69
74
 
70
75
  attr_reader :spawned, :trim_requested, :waiting
71
- attr_accessor :clean_thread_locals
72
- attr_accessor :out_of_band_hook # @version 5.0.0
73
76
 
74
77
  def self.clean_thread_locals
75
78
  Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
@@ -160,12 +163,12 @@ module Puma
160
163
 
161
164
  # @version 5.0.0
162
165
  def trigger_out_of_band_hook
163
- return false unless out_of_band_hook && out_of_band_hook.any?
166
+ return false unless @out_of_band&.any?
164
167
 
165
168
  # we execute on idle hook when all threads are free
166
169
  return false unless @spawned == @waiting
167
170
 
168
- out_of_band_hook.each(&:call)
171
+ @out_of_band.each(&:call)
169
172
  true
170
173
  rescue Exception => e
171
174
  STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
@@ -319,12 +322,12 @@ module Puma
319
322
  end
320
323
  end
321
324
 
322
- def auto_trim!(timeout=30)
325
+ def auto_trim!(timeout=@auto_trim_time)
323
326
  @auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
324
327
  @auto_trim.start!
325
328
  end
326
329
 
327
- def auto_reap!(timeout=5)
330
+ def auto_reap!(timeout=@reaping_time)
328
331
  @reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
329
332
  @reaper.start!
330
333
  end
@@ -354,8 +357,8 @@ module Puma
354
357
  @not_empty.broadcast
355
358
  @not_full.broadcast
356
359
 
357
- @auto_trim.stop if @auto_trim
358
- @reaper.stop if @reaper
360
+ @auto_trim&.stop
361
+ @reaper&.stop
359
362
  # dup workers so that we join them all safely
360
363
  @workers.dup
361
364
  end
data/lib/puma/util.rb CHANGED
@@ -17,29 +17,27 @@ module Puma
17
17
  Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
18
18
  end
19
19
 
20
- # Unescapes a URI escaped string with +encoding+. +encoding+ will be the
21
- # target encoding of the string returned, and it defaults to UTF-8
20
+ # Escapes and unescapes a URI escaped string with
21
+ # +encoding+. +encoding+ will be the target encoding of the string
22
+ # returned, and it defaults to UTF-8
22
23
  if defined?(::Encoding)
24
+ def escape(s, encoding = Encoding::UTF_8)
25
+ URI.encode_www_form_component(s, encoding)
26
+ end
27
+
23
28
  def unescape(s, encoding = Encoding::UTF_8)
24
29
  URI.decode_www_form_component(s, encoding)
25
30
  end
26
31
  else
27
- def unescape(s, encoding = nil)
28
- URI.decode_www_form_component(s, encoding)
32
+ def escape(s, encoding = nil)
33
+ URI.encode_www_form_component(s, encoding)
29
34
  end
30
- end
31
- module_function :unescape
32
35
 
33
- # @version 5.0.0
34
- def nakayoshi_gc(events)
35
- events.log "! Promoting existing objects to old generation..."
36
- 4.times { GC.start(full_mark: false) }
37
- if GC.respond_to?(:compact)
38
- events.log "! Compacting..."
39
- GC.compact
36
+ def unescape(s, encoding = nil)
37
+ URI.decode_www_form_component(s, encoding)
40
38
  end
41
- events.log "! Friendly fork preparation complete."
42
39
  end
40
+ module_function :unescape, :escape
43
41
 
44
42
  DEFAULT_SEP = /[&;] */n
45
43
 
data/lib/puma.rb CHANGED
@@ -10,14 +10,19 @@ require 'stringio'
10
10
 
11
11
  require 'thread'
12
12
 
13
+ # use require, see https://github.com/puma/puma/pull/2381
13
14
  require 'puma/puma_http11'
14
- require 'puma/detect'
15
- require 'puma/json_serialization'
15
+
16
+ require_relative 'puma/detect'
17
+ require_relative 'puma/json_serialization'
16
18
 
17
19
  module Puma
18
- autoload :Const, 'puma/const'
19
- autoload :Server, 'puma/server'
20
- autoload :Launcher, 'puma/launcher'
20
+ # when Puma is loaded via `Puma::CLI`, all files are loaded via
21
+ # `require_relative`. The below are for non-standard loading
22
+ autoload :Const, "#{__dir__}/puma/const"
23
+ autoload :Server, "#{__dir__}/puma/server"
24
+ autoload :Launcher, "#{__dir__}/puma/launcher"
25
+ autoload :LogWriter, "#{__dir__}/puma/log_writer"
21
26
 
22
27
  # at present, MiniSSL::Engine is only defined in extension code (puma_http11),
23
28
  # not in minissl.rb
@@ -26,7 +31,7 @@ module Puma
26
31
  HAS_UNIX_SOCKET = Object.const_defined? :UNIXSocket
27
32
 
28
33
  if HAS_SSL
29
- require 'puma/minissl'
34
+ require_relative 'puma/minissl'
30
35
  else
31
36
  module MiniSSL
32
37
  # this class is defined so that it exists when Puma is compiled
@@ -69,9 +74,7 @@ module Puma
69
74
  @get_stats.stats
70
75
  end
71
76
 
72
- # Thread name is new in Ruby 2.3
73
77
  def self.set_thread_name(name)
74
- return unless Thread.current.respond_to?(:name=)
75
78
  Thread.current.name = "puma #{name}"
76
79
  end
77
80
  end