puma 5.6.5-java → 6.0.1-java
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.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +120 -11
- data/README.md +21 -17
- data/bin/puma-wild +1 -1
- data/docs/compile_options.md +34 -0
- data/docs/fork_worker.md +1 -3
- data/docs/nginx.md +1 -1
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/extconf.rb +11 -8
- data/ext/puma_http11/http11_parser.c +1 -1
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +2 -2
- data/ext/puma_http11/http11_parser.rl +2 -2
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +36 -15
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +3 -3
- data/lib/puma/binder.rb +36 -42
- data/lib/puma/cli.rb +11 -17
- data/lib/puma/client.rb +26 -13
- data/lib/puma/cluster/worker.rb +13 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +28 -25
- data/lib/puma/configuration.rb +74 -58
- data/lib/puma/const.rb +14 -18
- data/lib/puma/control_cli.rb +3 -6
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +96 -52
- data/lib/puma/error_logger.rb +17 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -4
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +96 -156
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +23 -12
- data/lib/puma/minissl.rb +82 -11
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/puma_http11.jar +0 -0
- data/lib/puma/rack/builder.rb +4 -4
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +4 -4
- data/lib/puma/request.rb +334 -166
- data/lib/puma/runner.rb +41 -20
- data/lib/puma/server.rb +55 -71
- data/lib/puma/single.rb +10 -10
- data/lib/puma/state_file.rb +1 -4
- data/lib/puma/systemd.rb +3 -2
- data/lib/puma/thread_pool.rb +16 -16
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +12 -9
- data/lib/rack/handler/puma.rb +9 -9
- metadata +8 -4
- 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 | 
            -
             | 
| 4 | 
            -
             | 
| 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( | 
| 12 | 
            -
                  @launcher =  | 
| 13 | 
            -
                  @ | 
| 14 | 
            -
                  @ | 
| 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 | 
            -
                  @ | 
| 45 | 
            +
                  @log_writer.log str
         | 
| 40 46 | 
             
                end
         | 
| 41 47 |  | 
| 42 48 | 
             
                # @version 5.0.0
         | 
| 43 49 | 
             
                def stop_control
         | 
| 44 | 
            -
                  @control | 
| 50 | 
            +
                  @control&.stop true
         | 
| 45 51 | 
             
                end
         | 
| 46 52 |  | 
| 47 53 | 
             
                def error(str)
         | 
| 48 | 
            -
                  @ | 
| 54 | 
            +
                  @log_writer.error str
         | 
| 49 55 | 
             
                end
         | 
| 50 56 |  | 
| 51 57 | 
             
                def debug(str)
         | 
| 52 | 
            -
                  @ | 
| 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 | 
            -
                   | 
| 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 | 
            -
                   | 
| 68 | 
            -
             | 
| 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],  | 
| 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 @ | 
| 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 = @ | 
| 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] | 
| 164 | 
            +
                  @launcher.binder.parse @options[:binds]
         | 
| 157 165 | 
             
                end
         | 
| 158 166 |  | 
| 159 167 | 
             
                # @!attribute [r] app
         | 
| 160 168 | 
             
                def app
         | 
| 161 | 
            -
                  @app ||= @ | 
| 169 | 
            +
                  @app ||= @config.app
         | 
| 162 170 | 
             
                end
         | 
| 163 171 |  | 
| 164 172 | 
             
                def start_server
         | 
| 165 | 
            -
                  server = Puma::Server.new | 
| 166 | 
            -
                  server.inherit_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,19 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            require 'stringio'
         | 
| 4 4 |  | 
| 5 | 
            -
             | 
| 6 | 
            -
             | 
| 7 | 
            -
             | 
| 8 | 
            -
             | 
| 9 | 
            -
             | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 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 'request'
         | 
| 15 15 |  | 
| 16 16 | 
             
            require 'socket'
         | 
| 17 | 
            -
            require 'io/wait'
         | 
| 17 | 
            +
            require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
         | 
| 18 18 | 
             
            require 'forwardable'
         | 
| 19 19 |  | 
| 20 20 | 
             
            module Puma
         | 
| @@ -30,27 +30,21 @@ module Puma | |
| 30 30 | 
             
              #
         | 
| 31 31 | 
             
              # Each `Puma::Server` will have one reactor and one thread pool.
         | 
| 32 32 | 
             
              class Server
         | 
| 33 | 
            -
             | 
| 34 33 | 
             
                include Puma::Const
         | 
| 35 34 | 
             
                include Request
         | 
| 36 35 | 
             
                extend Forwardable
         | 
| 37 36 |  | 
| 38 37 | 
             
                attr_reader :thread
         | 
| 38 | 
            +
                attr_reader :log_writer
         | 
| 39 39 | 
             
                attr_reader :events
         | 
| 40 40 | 
             
                attr_reader :min_threads, :max_threads  # for #stats
         | 
| 41 41 | 
             
                attr_reader :requests_count             # @version 5.0.0
         | 
| 42 | 
            -
                attr_reader :log_writer                 # to help with backports
         | 
| 43 42 |  | 
| 44 43 | 
             
                # @todo the following may be deprecated in the future
         | 
| 45 44 | 
             
                attr_reader :auto_trim_time, :early_hints, :first_data_timeout,
         | 
| 46 45 | 
             
                  :leak_stack_on_error,
         | 
| 47 46 | 
             
                  :persistent_timeout, :reaping_time
         | 
| 48 47 |  | 
| 49 | 
            -
                # @deprecated v6.0.0
         | 
| 50 | 
            -
                attr_writer :auto_trim_time, :early_hints, :first_data_timeout,
         | 
| 51 | 
            -
                  :leak_stack_on_error, :min_threads, :max_threads,
         | 
| 52 | 
            -
                  :persistent_timeout, :reaping_time
         | 
| 53 | 
            -
             | 
| 54 48 | 
             
                attr_accessor :app
         | 
| 55 49 | 
             
                attr_accessor :binder
         | 
| 56 50 |  | 
| @@ -61,8 +55,9 @@ module Puma | |
| 61 55 |  | 
| 62 56 | 
             
                # Create a server for the rack app +app+.
         | 
| 63 57 | 
             
                #
         | 
| 64 | 
            -
                # + | 
| 65 | 
            -
                # | 
| 58 | 
            +
                # +log_writer+ is a Puma::LogWriter object used to log info and error messages.
         | 
| 59 | 
            +
                #
         | 
| 60 | 
            +
                # +events+ is a Puma::Events object used to notify application status events.
         | 
| 66 61 | 
             
                #
         | 
| 67 62 | 
             
                # Server#run returns a thread that you can join on to wait for the server
         | 
| 68 63 | 
             
                # to do its work.
         | 
| @@ -71,35 +66,40 @@ module Puma | |
| 71 66 | 
             
                #   and have default values set via +fetch+.  Normally the values are set via
         | 
| 72 67 | 
             
                #   `::Puma::Configuration.puma_default_options`.
         | 
| 73 68 | 
             
                #
         | 
| 74 | 
            -
                 | 
| 69 | 
            +
                # @note The `events` parameter is set to nil, and set to `Events.new` in code.
         | 
| 70 | 
            +
                #   Often `options` needs to be passed, but `events` does not.  Using nil allows
         | 
| 71 | 
            +
                #   calling code to not require events.rb.
         | 
| 72 | 
            +
                #
         | 
| 73 | 
            +
                def initialize(app, events = nil, options = {})
         | 
| 75 74 | 
             
                  @app = app
         | 
| 76 | 
            -
                  @events = events
         | 
| 77 | 
            -
                  @log_writer = events
         | 
| 75 | 
            +
                  @events = events || Events.new
         | 
| 78 76 |  | 
| 79 77 | 
             
                  @check, @notify = nil
         | 
| 80 78 | 
             
                  @status = :stop
         | 
| 81 79 |  | 
| 82 | 
            -
                  @auto_trim_time = 30
         | 
| 83 | 
            -
                  @reaping_time = 1
         | 
| 84 | 
            -
             | 
| 85 80 | 
             
                  @thread = nil
         | 
| 86 81 | 
             
                  @thread_pool = nil
         | 
| 87 82 |  | 
| 88 | 
            -
                  @options = options
         | 
| 83 | 
            +
                  @options = if options.is_a?(UserFileDefaultOptions)
         | 
| 84 | 
            +
                    options
         | 
| 85 | 
            +
                  else
         | 
| 86 | 
            +
                    UserFileDefaultOptions.new(options, Configuration::DEFAULTS)
         | 
| 87 | 
            +
                  end
         | 
| 89 88 |  | 
| 90 | 
            -
                  @ | 
| 91 | 
            -
                  @ | 
| 92 | 
            -
                  @ | 
| 93 | 
            -
                  @ | 
| 94 | 
            -
                  @ | 
| 95 | 
            -
                  @ | 
| 96 | 
            -
                  @ | 
| 97 | 
            -
                  @ | 
| 89 | 
            +
                  @log_writer          = @options.fetch :log_writer, LogWriter.stdio
         | 
| 90 | 
            +
                  @early_hints         = @options[:early_hints]
         | 
| 91 | 
            +
                  @first_data_timeout  = @options[:first_data_timeout]
         | 
| 92 | 
            +
                  @min_threads         = @options[:min_threads]
         | 
| 93 | 
            +
                  @max_threads         = @options[:max_threads]
         | 
| 94 | 
            +
                  @persistent_timeout  = @options[:persistent_timeout]
         | 
| 95 | 
            +
                  @queue_requests      = @options[:queue_requests]
         | 
| 96 | 
            +
                  @max_fast_inline     = @options[:max_fast_inline]
         | 
| 97 | 
            +
                  @io_selector_backend = @options[:io_selector_backend]
         | 
| 98 98 |  | 
| 99 99 | 
             
                  temp = !!(@options[:environment] =~ /\A(development|test)\z/)
         | 
| 100 100 | 
             
                  @leak_stack_on_error = @options[:environment] ? temp : true
         | 
| 101 101 |  | 
| 102 | 
            -
                  @binder = Binder.new( | 
| 102 | 
            +
                  @binder = Binder.new(log_writer)
         | 
| 103 103 |  | 
| 104 104 | 
             
                  ENV['RACK_ENV'] ||= "development"
         | 
| 105 105 |  | 
| @@ -195,12 +195,12 @@ module Puma | |
| 195 195 |  | 
| 196 196 | 
             
                # @!attribute [r] backlog
         | 
| 197 197 | 
             
                def backlog
         | 
| 198 | 
            -
                  @thread_pool | 
| 198 | 
            +
                  @thread_pool&.backlog
         | 
| 199 199 | 
             
                end
         | 
| 200 200 |  | 
| 201 201 | 
             
                # @!attribute [r] running
         | 
| 202 202 | 
             
                def running
         | 
| 203 | 
            -
                  @thread_pool | 
| 203 | 
            +
                  @thread_pool&.spawned
         | 
| 204 204 | 
             
                end
         | 
| 205 205 |  | 
| 206 206 |  | 
| @@ -213,7 +213,7 @@ module Puma | |
| 213 213 | 
             
                # value would be 4 until it finishes processing.
         | 
| 214 214 | 
             
                # @!attribute [r] pool_capacity
         | 
| 215 215 | 
             
                def pool_capacity
         | 
| 216 | 
            -
                  @thread_pool | 
| 216 | 
            +
                  @thread_pool&.pool_capacity
         | 
| 217 217 | 
             
                end
         | 
| 218 218 |  | 
| 219 219 | 
             
                # Runs the server.
         | 
| @@ -229,29 +229,16 @@ module Puma | |
| 229 229 |  | 
| 230 230 | 
             
                  @status = :run
         | 
| 231 231 |  | 
| 232 | 
            -
                  @thread_pool = ThreadPool.new(
         | 
| 233 | 
            -
                    thread_name,
         | 
| 234 | 
            -
                    @min_threads,
         | 
| 235 | 
            -
                    @max_threads,
         | 
| 236 | 
            -
                    ::Puma::IOBuffer,
         | 
| 237 | 
            -
                    &method(:process_client)
         | 
| 238 | 
            -
                  )
         | 
| 239 | 
            -
             | 
| 240 | 
            -
                  @thread_pool.out_of_band_hook = @options[:out_of_band]
         | 
| 241 | 
            -
                  @thread_pool.clean_thread_locals = @options[:clean_thread_locals]
         | 
| 232 | 
            +
                  @thread_pool = ThreadPool.new(thread_name, @options) { |client| process_client client }
         | 
| 242 233 |  | 
| 243 234 | 
             
                  if @queue_requests
         | 
| 244 | 
            -
                    @reactor = Reactor.new(@io_selector_backend | 
| 235 | 
            +
                    @reactor = Reactor.new(@io_selector_backend) { |c| reactor_wakeup c }
         | 
| 245 236 | 
             
                    @reactor.run
         | 
| 246 237 | 
             
                  end
         | 
| 247 238 |  | 
| 248 | 
            -
                  if @reaping_time
         | 
| 249 | 
            -
                    @thread_pool.auto_reap!(@reaping_time)
         | 
| 250 | 
            -
                  end
         | 
| 251 239 |  | 
| 252 | 
            -
                  if @ | 
| 253 | 
            -
             | 
| 254 | 
            -
                  end
         | 
| 240 | 
            +
                  @thread_pool.auto_reap! if @options[:reaping_time]
         | 
| 241 | 
            +
                  @thread_pool.auto_trim! if @options[:auto_trim_time]
         | 
| 255 242 |  | 
| 256 243 | 
             
                  @check, @notify = Puma::Util.pipe unless @notify
         | 
| 257 244 |  | 
| @@ -355,11 +342,11 @@ module Puma | |
| 355 342 | 
             
                        # In the case that any of the sockets are unexpectedly close.
         | 
| 356 343 | 
             
                        raise
         | 
| 357 344 | 
             
                      rescue StandardError => e
         | 
| 358 | 
            -
                        @ | 
| 345 | 
            +
                        @log_writer.unknown_error e, nil, "Listen loop"
         | 
| 359 346 | 
             
                      end
         | 
| 360 347 | 
             
                    end
         | 
| 361 348 |  | 
| 362 | 
            -
                    @ | 
| 349 | 
            +
                    @log_writer.debug "Drained #{drain} additional connections." if drain
         | 
| 363 350 | 
             
                    @events.fire :state, @status
         | 
| 364 351 |  | 
| 365 352 | 
             
                    if queue_requests
         | 
| @@ -368,14 +355,13 @@ module Puma | |
| 368 355 | 
             
                    end
         | 
| 369 356 | 
             
                    graceful_shutdown if @status == :stop || @status == :restart
         | 
| 370 357 | 
             
                  rescue Exception => e
         | 
| 371 | 
            -
                    @ | 
| 358 | 
            +
                    @log_writer.unknown_error e, nil, "Exception handling servers"
         | 
| 372 359 | 
             
                  ensure
         | 
| 373 | 
            -
                    # RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
         | 
| 374 360 | 
             
                    # Errno::EBADF is infrequently raised
         | 
| 375 361 | 
             
                    [@check, @notify].each do |io|
         | 
| 376 362 | 
             
                      begin
         | 
| 377 363 | 
             
                        io.close unless io.closed?
         | 
| 378 | 
            -
                      rescue Errno::EBADF | 
| 364 | 
            +
                      rescue Errno::EBADF
         | 
| 379 365 | 
             
                      end
         | 
| 380 366 | 
             
                    end
         | 
| 381 367 | 
             
                    @notify = nil
         | 
| @@ -414,7 +400,7 @@ module Puma | |
| 414 400 | 
             
                # returning.
         | 
| 415 401 | 
             
                #
         | 
| 416 402 | 
             
                # Return true if one or more requests were processed.
         | 
| 417 | 
            -
                def process_client(client | 
| 403 | 
            +
                def process_client(client)
         | 
| 418 404 | 
             
                  # Advertise this server into the thread
         | 
| 419 405 | 
             
                  Thread.current[ThreadLocalKey] = self
         | 
| 420 406 |  | 
| @@ -440,15 +426,13 @@ module Puma | |
| 440 426 |  | 
| 441 427 | 
             
                    while true
         | 
| 442 428 | 
             
                      @requests_count += 1
         | 
| 443 | 
            -
                      case handle_request(client,  | 
| 429 | 
            +
                      case handle_request(client, requests + 1)
         | 
| 444 430 | 
             
                      when false
         | 
| 445 431 | 
             
                        break
         | 
| 446 432 | 
             
                      when :async
         | 
| 447 433 | 
             
                        close_socket = false
         | 
| 448 434 | 
             
                        break
         | 
| 449 435 | 
             
                      when true
         | 
| 450 | 
            -
                        buffer.reset
         | 
| 451 | 
            -
             | 
| 452 436 | 
             
                        ThreadPool.clean_thread_locals if clean_thread_locals
         | 
| 453 437 |  | 
| 454 438 | 
             
                        requests += 1
         | 
| @@ -482,7 +466,7 @@ module Puma | |
| 482 466 | 
             
                    # The ensure tries to close +client+ down
         | 
| 483 467 | 
             
                    requests > 0
         | 
| 484 468 | 
             
                  ensure
         | 
| 485 | 
            -
                     | 
| 469 | 
            +
                    client.io_buffer.reset
         | 
| 486 470 |  | 
| 487 471 | 
             
                    begin
         | 
| 488 472 | 
             
                      client.close if close_socket
         | 
| @@ -490,7 +474,7 @@ module Puma | |
| 490 474 | 
             
                      Puma::Util.purge_interrupt_queue
         | 
| 491 475 | 
             
                      # Already closed
         | 
| 492 476 | 
             
                    rescue StandardError => e
         | 
| 493 | 
            -
                      @ | 
| 477 | 
            +
                      @log_writer.unknown_error e, nil, "Client"
         | 
| 494 478 | 
             
                    end
         | 
| 495 479 | 
             
                  end
         | 
| 496 480 | 
             
                end
         | 
| @@ -513,16 +497,16 @@ module Puma | |
| 513 497 | 
             
                  lowlevel_error(e, client.env)
         | 
| 514 498 | 
             
                  case e
         | 
| 515 499 | 
             
                  when MiniSSL::SSLError
         | 
| 516 | 
            -
                    @ | 
| 500 | 
            +
                    @log_writer.ssl_error e, client.io
         | 
| 517 501 | 
             
                  when HttpParserError
         | 
| 518 502 | 
             
                    client.write_error(400)
         | 
| 519 | 
            -
                    @ | 
| 503 | 
            +
                    @log_writer.parse_error e, client
         | 
| 520 504 | 
             
                  when HttpParserError501
         | 
| 521 505 | 
             
                    client.write_error(501)
         | 
| 522 | 
            -
                    @ | 
| 506 | 
            +
                    @log_writer.parse_error e, client
         | 
| 523 507 | 
             
                  else
         | 
| 524 508 | 
             
                    client.write_error(500)
         | 
| 525 | 
            -
                    @ | 
| 509 | 
            +
                    @log_writer.unknown_error e, nil, "Read"
         | 
| 526 510 | 
             
                  end
         | 
| 527 511 | 
             
                end
         | 
| 528 512 |  | 
    
        data/lib/puma/single.rb
    CHANGED
    
    | @@ -1,8 +1,8 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
             | 
| 4 | 
            -
             | 
| 5 | 
            -
             | 
| 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 | 
| 24 | 
            +
                  @server&.begin_restart
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 27 | 
             
                def stop
         | 
| 28 | 
            -
                  @server | 
| 28 | 
            +
                  @server&.stop false
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| 31 31 | 
             
                def halt
         | 
| 32 | 
            -
                  @server | 
| 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 | 
| 38 | 
            -
                  @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 | 
            -
                  @ | 
| 58 | 
            +
                  @events.fire_on_booted!
         | 
| 59 59 |  | 
| 60 60 | 
             
                  begin
         | 
| 61 61 | 
             
                    server_thread.join
         | 
    
        data/lib/puma/state_file.rb
    CHANGED
    
    | @@ -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" | 
| 23 | 
            +
                  contents = +"---\n"
         | 
| 27 24 | 
             
                  @options.each do |k,v|
         | 
| 28 25 | 
             
                    next unless ALLOWED_FIELDS.include? k
         | 
| 29 26 | 
             
                    case v
         | 
    
        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 | 
            -
                  @ | 
| 44 | 
            +
                  @log_writer.log(str)
         | 
| 44 45 | 
             
                end
         | 
| 45 46 | 
             
              end
         | 
| 46 47 | 
             
            end
         | 
    
        data/lib/puma/thread_pool.rb
    CHANGED
    
    | @@ -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,  | 
| 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,13 @@ module Puma | |
| 40 42 | 
             
                  @waiting = 0
         | 
| 41 43 |  | 
| 42 44 | 
             
                  @name = name
         | 
| 43 | 
            -
                  @min = Integer( | 
| 44 | 
            -
                  @max = Integer( | 
| 45 | 
            +
                  @min = Integer(options[:min_threads])
         | 
| 46 | 
            +
                  @max = Integer(options[:max_threads])
         | 
| 45 47 | 
             
                  @block = block
         | 
| 46 | 
            -
                  @ | 
| 48 | 
            +
                  @out_of_band = options[:out_of_band]
         | 
| 49 | 
            +
                  @clean_thread_locals = options[:clean_thread_locals]
         | 
| 50 | 
            +
                  @reaping_time = options[:reaping_time]
         | 
| 51 | 
            +
                  @auto_trim_time = options[:auto_trim_time]
         | 
| 47 52 |  | 
| 48 53 | 
             
                  @shutdown = false
         | 
| 49 54 |  | 
| @@ -62,14 +67,11 @@ module Puma | |
| 62 67 | 
             
                    end
         | 
| 63 68 | 
             
                  end
         | 
| 64 69 |  | 
| 65 | 
            -
                  @clean_thread_locals = false
         | 
| 66 70 | 
             
                  @force_shutdown = false
         | 
| 67 71 | 
             
                  @shutdown_mutex = Mutex.new
         | 
| 68 72 | 
             
                end
         | 
| 69 73 |  | 
| 70 74 | 
             
                attr_reader :spawned, :trim_requested, :waiting
         | 
| 71 | 
            -
                attr_accessor :clean_thread_locals
         | 
| 72 | 
            -
                attr_accessor :out_of_band_hook # @version 5.0.0
         | 
| 73 75 |  | 
| 74 76 | 
             
                def self.clean_thread_locals
         | 
| 75 77 | 
             
                  Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
         | 
| @@ -109,8 +111,6 @@ module Puma | |
| 109 111 | 
             
                    not_empty = @not_empty
         | 
| 110 112 | 
             
                    not_full = @not_full
         | 
| 111 113 |  | 
| 112 | 
            -
                    extra = @extra.map { |i| i.new }
         | 
| 113 | 
            -
             | 
| 114 114 | 
             
                    while true
         | 
| 115 115 | 
             
                      work = nil
         | 
| 116 116 |  | 
| @@ -144,7 +144,7 @@ module Puma | |
| 144 144 | 
             
                      end
         | 
| 145 145 |  | 
| 146 146 | 
             
                      begin
         | 
| 147 | 
            -
                        @out_of_band_pending = true if block.call(work | 
| 147 | 
            +
                        @out_of_band_pending = true if block.call(work)
         | 
| 148 148 | 
             
                      rescue Exception => e
         | 
| 149 149 | 
             
                        STDERR.puts "Error reached top of thread-pool: #{e.message} (#{e.class})"
         | 
| 150 150 | 
             
                      end
         | 
| @@ -160,12 +160,12 @@ module Puma | |
| 160 160 |  | 
| 161 161 | 
             
                # @version 5.0.0
         | 
| 162 162 | 
             
                def trigger_out_of_band_hook
         | 
| 163 | 
            -
                  return false unless  | 
| 163 | 
            +
                  return false unless @out_of_band&.any?
         | 
| 164 164 |  | 
| 165 165 | 
             
                  # we execute on idle hook when all threads are free
         | 
| 166 166 | 
             
                  return false unless @spawned == @waiting
         | 
| 167 167 |  | 
| 168 | 
            -
                   | 
| 168 | 
            +
                  @out_of_band.each(&:call)
         | 
| 169 169 | 
             
                  true
         | 
| 170 170 | 
             
                rescue Exception => e
         | 
| 171 171 | 
             
                  STDERR.puts "Exception calling out_of_band_hook: #{e.message} (#{e.class})"
         | 
| @@ -319,12 +319,12 @@ module Puma | |
| 319 319 | 
             
                  end
         | 
| 320 320 | 
             
                end
         | 
| 321 321 |  | 
| 322 | 
            -
                def auto_trim!(timeout | 
| 322 | 
            +
                def auto_trim!(timeout=@auto_trim_time)
         | 
| 323 323 | 
             
                  @auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
         | 
| 324 324 | 
             
                  @auto_trim.start!
         | 
| 325 325 | 
             
                end
         | 
| 326 326 |  | 
| 327 | 
            -
                def auto_reap!(timeout | 
| 327 | 
            +
                def auto_reap!(timeout=@reaping_time)
         | 
| 328 328 | 
             
                  @reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
         | 
| 329 329 | 
             
                  @reaper.start!
         | 
| 330 330 | 
             
                end
         | 
| @@ -354,8 +354,8 @@ module Puma | |
| 354 354 | 
             
                    @not_empty.broadcast
         | 
| 355 355 | 
             
                    @not_full.broadcast
         | 
| 356 356 |  | 
| 357 | 
            -
                    @auto_trim | 
| 358 | 
            -
                    @reaper | 
| 357 | 
            +
                    @auto_trim&.stop
         | 
| 358 | 
            +
                    @reaper&.stop
         | 
| 359 359 | 
             
                    # dup workers so that we join them all safely
         | 
| 360 360 | 
             
                    @workers.dup
         | 
| 361 361 | 
             
                  end
         | 
    
        data/lib/puma/util.rb
    CHANGED
    
    | @@ -39,17 +39,6 @@ module Puma | |
| 39 39 | 
             
                end
         | 
| 40 40 | 
             
                module_function :unescape, :escape
         | 
| 41 41 |  | 
| 42 | 
            -
                # @version 5.0.0
         | 
| 43 | 
            -
                def nakayoshi_gc(events)
         | 
| 44 | 
            -
                  events.log "! Promoting existing objects to old generation..."
         | 
| 45 | 
            -
                  4.times { GC.start(full_mark: false) }
         | 
| 46 | 
            -
                  if GC.respond_to?(:compact)
         | 
| 47 | 
            -
                    events.log "! Compacting..."
         | 
| 48 | 
            -
                    GC.compact
         | 
| 49 | 
            -
                  end
         | 
| 50 | 
            -
                  events.log "! Friendly fork preparation complete."
         | 
| 51 | 
            -
                end
         | 
| 52 | 
            -
             | 
| 53 42 | 
             
                DEFAULT_SEP = /[&;] */n
         | 
| 54 43 |  | 
| 55 44 | 
             
                # Stolen from Mongrel, with some small modifications:
         | 
    
        data/lib/puma.rb
    CHANGED
    
    | @@ -10,23 +10,28 @@ 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 | 
            -
             | 
| 15 | 
            -
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            require_relative 'puma/detect'
         | 
| 17 | 
            +
            require_relative 'puma/json_serialization'
         | 
| 16 18 |  | 
| 17 19 | 
             
            module Puma
         | 
| 18 | 
            -
               | 
| 19 | 
            -
               | 
| 20 | 
            -
              autoload : | 
| 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
         | 
| 24 29 | 
             
              HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
         | 
| 25 30 |  | 
| 26 | 
            -
              HAS_UNIX_SOCKET = Object.const_defined? | 
| 31 | 
            +
              HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
         | 
| 27 32 |  | 
| 28 33 | 
             
              if HAS_SSL
         | 
| 29 | 
            -
                 | 
| 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
         |