puma 5.0.0.beta1 → 5.0.0.beta2
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 +23 -1
- data/README.md +3 -3
- data/docs/architecture.md +3 -3
- data/docs/deployment.md +6 -2
- data/docs/signals.md +4 -4
- data/ext/puma_http11/http11_parser.c +3 -1
- data/ext/puma_http11/http11_parser.rl +3 -1
- data/ext/puma_http11/mini_ssl.c +12 -2
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +37 -6
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma.rb +1 -0
- data/lib/puma/app/status.rb +4 -2
- data/lib/puma/binder.rb +5 -4
- data/lib/puma/client.rb +36 -9
- data/lib/puma/cluster.rb +8 -4
- data/lib/puma/commonlogger.rb +2 -2
- data/lib/puma/const.rb +1 -1
- data/lib/puma/dsl.rb +3 -3
- data/lib/puma/error_logger.rb +96 -0
- data/lib/puma/events.rb +33 -31
- data/lib/puma/launcher.rb +5 -2
- data/lib/puma/minissl.rb +34 -2
- data/lib/puma/reactor.rb +2 -2
- data/lib/puma/runner.rb +1 -1
- data/lib/puma/server.rb +84 -44
- data/lib/puma/state_file.rb +1 -1
- data/lib/puma/thread_pool.rb +5 -2
- metadata +8 -7
    
        data/lib/puma/server.rb
    CHANGED
    
    | @@ -98,10 +98,22 @@ module Puma | |
| 98 98 | 
             
                  @binder = bind
         | 
| 99 99 | 
             
                end
         | 
| 100 100 |  | 
| 101 | 
            +
                class << self
         | 
| 102 | 
            +
                  # :nodoc:
         | 
| 103 | 
            +
                  def tcp_cork_supported?
         | 
| 104 | 
            +
                    RbConfig::CONFIG['host_os'] =~ /linux/ &&
         | 
| 105 | 
            +
                      Socket.const_defined?(:IPPROTO_TCP) &&
         | 
| 106 | 
            +
                      Socket.const_defined?(:TCP_CORK) &&
         | 
| 107 | 
            +
                      Socket.const_defined?(:SOL_TCP) &&
         | 
| 108 | 
            +
                      Socket.const_defined?(:TCP_INFO)
         | 
| 109 | 
            +
                  end
         | 
| 110 | 
            +
                  private :tcp_cork_supported?
         | 
| 111 | 
            +
                end
         | 
| 112 | 
            +
             | 
| 101 113 | 
             
                # On Linux, use TCP_CORK to better control how the TCP stack
         | 
| 102 114 | 
             
                # packetizes our stream. This improves both latency and throughput.
         | 
| 103 115 | 
             
                #
         | 
| 104 | 
            -
                if  | 
| 116 | 
            +
                if tcp_cork_supported?
         | 
| 105 117 | 
             
                  UNPACK_TCP_STATE_FROM_TCP_INFO = "C".freeze
         | 
| 106 118 |  | 
| 107 119 | 
             
                  # 6 == Socket::IPPROTO_TCP
         | 
| @@ -109,7 +121,7 @@ module Puma | |
| 109 121 | 
             
                  # 1/0 == turn on/off
         | 
| 110 122 | 
             
                  def cork_socket(socket)
         | 
| 111 123 | 
             
                    begin
         | 
| 112 | 
            -
                      socket.setsockopt( | 
| 124 | 
            +
                      socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if socket.kind_of? TCPSocket
         | 
| 113 125 | 
             
                    rescue IOError, SystemCallError
         | 
| 114 126 | 
             
                      Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         | 
| 115 127 | 
             
                    end
         | 
| @@ -117,7 +129,7 @@ module Puma | |
| 117 129 |  | 
| 118 130 | 
             
                  def uncork_socket(socket)
         | 
| 119 131 | 
             
                    begin
         | 
| 120 | 
            -
                      socket.setsockopt( | 
| 132 | 
            +
                      socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if socket.kind_of? TCPSocket
         | 
| 121 133 | 
             
                    rescue IOError, SystemCallError
         | 
| 122 134 | 
             
                      Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         | 
| 123 135 | 
             
                    end
         | 
| @@ -207,14 +219,16 @@ module Puma | |
| 207 219 |  | 
| 208 220 | 
             
                      client.close
         | 
| 209 221 |  | 
| 210 | 
            -
                      @events.ssl_error  | 
| 222 | 
            +
                      @events.ssl_error e, addr, cert
         | 
| 211 223 | 
             
                    rescue HttpParserError => e
         | 
| 212 224 | 
             
                      client.write_error(400)
         | 
| 213 225 | 
             
                      client.close
         | 
| 214 226 |  | 
| 215 | 
            -
                      @events.parse_error  | 
| 216 | 
            -
                    rescue ConnectionError, EOFError
         | 
| 227 | 
            +
                      @events.parse_error e, client
         | 
| 228 | 
            +
                    rescue ConnectionError, EOFError => e
         | 
| 217 229 | 
             
                      client.close
         | 
| 230 | 
            +
             | 
| 231 | 
            +
                      @events.connection_error e, client
         | 
| 218 232 | 
             
                    else
         | 
| 219 233 | 
             
                      if process_now
         | 
| 220 234 | 
             
                        process_client client, buffer
         | 
| @@ -281,35 +295,26 @@ module Puma | |
| 281 295 | 
             
                          if sock == check
         | 
| 282 296 | 
             
                            break if handle_check
         | 
| 283 297 | 
             
                          else
         | 
| 284 | 
            -
                             | 
| 285 | 
            -
             | 
| 286 | 
            -
                               | 
| 287 | 
            -
             | 
| 288 | 
            -
             | 
| 289 | 
            -
                               | 
| 290 | 
            -
             | 
| 291 | 
            -
             | 
| 292 | 
            -
             | 
| 293 | 
            -
             | 
| 294 | 
            -
             | 
| 295 | 
            -
             | 
| 296 | 
            -
             | 
| 297 | 
            -
             | 
| 298 | 
            -
                              end
         | 
| 299 | 
            -
                            rescue SystemCallError
         | 
| 300 | 
            -
                              # nothing
         | 
| 301 | 
            -
                            rescue Errno::ECONNABORTED
         | 
| 302 | 
            -
                              # client closed the socket even before accept
         | 
| 303 | 
            -
                              begin
         | 
| 304 | 
            -
                                io.close
         | 
| 305 | 
            -
                              rescue
         | 
| 306 | 
            -
                                Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         | 
| 307 | 
            -
                              end
         | 
| 298 | 
            +
                            pool.wait_until_not_full
         | 
| 299 | 
            +
                            pool.wait_for_less_busy_worker(
         | 
| 300 | 
            +
                              @options[:wait_for_less_busy_worker].to_f)
         | 
| 301 | 
            +
             | 
| 302 | 
            +
                            io = begin
         | 
| 303 | 
            +
                              sock.accept_nonblock
         | 
| 304 | 
            +
                            rescue IO::WaitReadable
         | 
| 305 | 
            +
                              next
         | 
| 306 | 
            +
                            end
         | 
| 307 | 
            +
                            client = Client.new io, @binder.env(sock)
         | 
| 308 | 
            +
                            if remote_addr_value
         | 
| 309 | 
            +
                              client.peerip = remote_addr_value
         | 
| 310 | 
            +
                            elsif remote_addr_header
         | 
| 311 | 
            +
                              client.remote_addr_header = remote_addr_header
         | 
| 308 312 | 
             
                            end
         | 
| 313 | 
            +
                            pool << client
         | 
| 309 314 | 
             
                          end
         | 
| 310 315 | 
             
                        end
         | 
| 311 316 | 
             
                      rescue Object => e
         | 
| 312 | 
            -
                        @events.unknown_error  | 
| 317 | 
            +
                        @events.unknown_error e, nil, "Listen loop"
         | 
| 313 318 | 
             
                      end
         | 
| 314 319 | 
             
                    end
         | 
| 315 320 |  | 
| @@ -322,10 +327,14 @@ module Puma | |
| 322 327 | 
             
                    end
         | 
| 323 328 | 
             
                    graceful_shutdown if @status == :stop || @status == :restart
         | 
| 324 329 | 
             
                  rescue Exception => e
         | 
| 325 | 
            -
                     | 
| 326 | 
            -
                    STDERR.puts e.backtrace
         | 
| 330 | 
            +
                    @events.unknown_error e, nil, "Exception handling servers"
         | 
| 327 331 | 
             
                  ensure
         | 
| 328 | 
            -
                     | 
| 332 | 
            +
                    begin
         | 
| 333 | 
            +
                      @check.close unless @check.closed?
         | 
| 334 | 
            +
                    rescue Errno::EBADF, RuntimeError
         | 
| 335 | 
            +
                      # RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
         | 
| 336 | 
            +
                      # Errno::EBADF is infrequently raised
         | 
| 337 | 
            +
                    end
         | 
| 329 338 | 
             
                    @notify.close
         | 
| 330 339 | 
             
                    @notify = nil
         | 
| 331 340 | 
             
                    @check = nil
         | 
| @@ -415,7 +424,7 @@ module Puma | |
| 415 424 |  | 
| 416 425 | 
             
                    close_socket = true
         | 
| 417 426 |  | 
| 418 | 
            -
                    @events.ssl_error  | 
| 427 | 
            +
                    @events.ssl_error e, addr, cert
         | 
| 419 428 |  | 
| 420 429 | 
             
                  # The client doesn't know HTTP well
         | 
| 421 430 | 
             
                  rescue HttpParserError => e
         | 
| @@ -423,7 +432,7 @@ module Puma | |
| 423 432 |  | 
| 424 433 | 
             
                    client.write_error(400)
         | 
| 425 434 |  | 
| 426 | 
            -
                    @events.parse_error  | 
| 435 | 
            +
                    @events.parse_error e, client
         | 
| 427 436 |  | 
| 428 437 | 
             
                  # Server error
         | 
| 429 438 | 
             
                  rescue StandardError => e
         | 
| @@ -431,8 +440,7 @@ module Puma | |
| 431 440 |  | 
| 432 441 | 
             
                    client.write_error(500)
         | 
| 433 442 |  | 
| 434 | 
            -
                    @events.unknown_error  | 
| 435 | 
            -
             | 
| 443 | 
            +
                    @events.unknown_error e, nil, "Read"
         | 
| 436 444 | 
             
                  ensure
         | 
| 437 445 | 
             
                    buffer.reset
         | 
| 438 446 |  | 
| @@ -442,7 +450,7 @@ module Puma | |
| 442 450 | 
             
                      Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         | 
| 443 451 | 
             
                      # Already closed
         | 
| 444 452 | 
             
                    rescue StandardError => e
         | 
| 445 | 
            -
                      @events.unknown_error  | 
| 453 | 
            +
                      @events.unknown_error e, nil, "Client"
         | 
| 446 454 | 
             
                    end
         | 
| 447 455 | 
             
                  end
         | 
| 448 456 | 
             
                end
         | 
| @@ -478,7 +486,7 @@ module Puma | |
| 478 486 |  | 
| 479 487 | 
             
                  env[PATH_INFO] = env[REQUEST_PATH]
         | 
| 480 488 |  | 
| 481 | 
            -
                  # From  | 
| 489 | 
            +
                  # From https://www.ietf.org/rfc/rfc3875 :
         | 
| 482 490 | 
             
                  # "Script authors should be aware that the REMOTE_ADDR and
         | 
| 483 491 | 
             
                  # REMOTE_HOST meta-variables (see sections 4.1.8 and 4.1.9)
         | 
| 484 492 | 
             
                  # may not identify the ultimate source of the request.
         | 
| @@ -567,12 +575,44 @@ module Puma | |
| 567 575 | 
             
                        end
         | 
| 568 576 |  | 
| 569 577 | 
             
                        fast_write client, "\r\n".freeze
         | 
| 570 | 
            -
                      rescue ConnectionError
         | 
| 578 | 
            +
                      rescue ConnectionError => e
         | 
| 579 | 
            +
                        @events.debug_error e
         | 
| 571 580 | 
             
                        # noop, if we lost the socket we just won't send the early hints
         | 
| 572 581 | 
             
                      end
         | 
| 573 582 | 
             
                    }
         | 
| 574 583 | 
             
                  end
         | 
| 575 584 |  | 
| 585 | 
            +
                  # Fixup any headers with , in the name to have _ now. We emit
         | 
| 586 | 
            +
                  # headers with , in them during the parse phase to avoid ambiguity
         | 
| 587 | 
            +
                  # with the - to _ conversion for critical headers. But here for
         | 
| 588 | 
            +
                  # compatibility, we'll convert them back. This code is written to
         | 
| 589 | 
            +
                  # avoid allocation in the common case (ie there are no headers
         | 
| 590 | 
            +
                  # with , in their names), that's why it has the extra conditionals.
         | 
| 591 | 
            +
             | 
| 592 | 
            +
                  to_delete = nil
         | 
| 593 | 
            +
                  to_add = nil
         | 
| 594 | 
            +
             | 
| 595 | 
            +
                  env.each do |k,v|
         | 
| 596 | 
            +
                    if k.start_with?("HTTP_") and k.include?(",") and k != "HTTP_TRANSFER,ENCODING"
         | 
| 597 | 
            +
                      if to_delete
         | 
| 598 | 
            +
                        to_delete << k
         | 
| 599 | 
            +
                      else
         | 
| 600 | 
            +
                        to_delete = [k]
         | 
| 601 | 
            +
                      end
         | 
| 602 | 
            +
             | 
| 603 | 
            +
                      unless to_add
         | 
| 604 | 
            +
                        to_add = {}
         | 
| 605 | 
            +
                      end
         | 
| 606 | 
            +
             | 
| 607 | 
            +
                      to_add[k.tr(",", "_")] = v
         | 
| 608 | 
            +
                    end
         | 
| 609 | 
            +
                  end
         | 
| 610 | 
            +
             | 
| 611 | 
            +
                  if to_delete
         | 
| 612 | 
            +
                    to_delete.each { |k| env.delete(k) }
         | 
| 613 | 
            +
                    env.merge! to_add
         | 
| 614 | 
            +
                  end
         | 
| 615 | 
            +
             | 
| 576 616 | 
             
                  # A rack extension. If the app writes #call'ables to this
         | 
| 577 617 | 
             
                  # array, we will invoke them when the request is done.
         | 
| 578 618 | 
             
                  #
         | 
| @@ -594,12 +634,12 @@ module Puma | |
| 594 634 | 
             
                        return :async
         | 
| 595 635 | 
             
                      end
         | 
| 596 636 | 
             
                    rescue ThreadPool::ForceShutdown => e
         | 
| 597 | 
            -
                      @events.unknown_error  | 
| 637 | 
            +
                      @events.unknown_error e, req, "Rack app"
         | 
| 598 638 | 
             
                      @events.log "Detected force shutdown of a thread"
         | 
| 599 639 |  | 
| 600 640 | 
             
                      status, headers, res_body = lowlevel_error(e, env, 503)
         | 
| 601 641 | 
             
                    rescue Exception => e
         | 
| 602 | 
            -
                      @events.unknown_error  | 
| 642 | 
            +
                      @events.unknown_error e, req, "Rack app"
         | 
| 603 643 |  | 
| 604 644 | 
             
                      status, headers, res_body = lowlevel_error(e, env, 500)
         | 
| 605 645 | 
             
                    end
         | 
| @@ -889,7 +929,7 @@ module Puma | |
| 889 929 | 
             
                  @check, @notify = Puma::Util.pipe unless @notify
         | 
| 890 930 | 
             
                  begin
         | 
| 891 931 | 
             
                    @notify << message
         | 
| 892 | 
            -
                  rescue IOError
         | 
| 932 | 
            +
                  rescue IOError, NoMethodError, Errno::EPIPE
         | 
| 893 933 | 
             
                     # The server, in another thread, is shutting down
         | 
| 894 934 | 
             
                    Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
         | 
| 895 935 | 
             
                  rescue RuntimeError => e
         | 
    
        data/lib/puma/state_file.rb
    CHANGED
    
    
    
        data/lib/puma/thread_pool.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: puma
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 5.0.0. | 
| 4 | 
            +
              version: 5.0.0.beta2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Evan Phoenix
         | 
| 8 | 
            -
            autorequire: | 
| 8 | 
            +
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020-05 | 
| 11 | 
            +
            date: 2020-09-05 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: nio4r
         | 
| @@ -87,6 +87,7 @@ files: | |
| 87 87 | 
             
            - lib/puma/control_cli.rb
         | 
| 88 88 | 
             
            - lib/puma/detect.rb
         | 
| 89 89 | 
             
            - lib/puma/dsl.rb
         | 
| 90 | 
            +
            - lib/puma/error_logger.rb
         | 
| 90 91 | 
             
            - lib/puma/events.rb
         | 
| 91 92 | 
             
            - lib/puma/io_buffer.rb
         | 
| 92 93 | 
             
            - lib/puma/jruby_restart.rb
         | 
| @@ -109,15 +110,15 @@ files: | |
| 109 110 | 
             
            - lib/rack/handler/puma.rb
         | 
| 110 111 | 
             
            - tools/Dockerfile
         | 
| 111 112 | 
             
            - tools/trickletest.rb
         | 
| 112 | 
            -
            homepage:  | 
| 113 | 
            +
            homepage: https://puma.io
         | 
| 113 114 | 
             
            licenses:
         | 
| 114 115 | 
             
            - BSD-3-Clause
         | 
| 115 116 | 
             
            metadata:
         | 
| 116 117 | 
             
              bug_tracker_uri: https://github.com/puma/puma/issues
         | 
| 117 118 | 
             
              changelog_uri: https://github.com/puma/puma/blob/master/History.md
         | 
| 118 | 
            -
              homepage_uri:  | 
| 119 | 
            +
              homepage_uri: https://puma.io
         | 
| 119 120 | 
             
              source_code_uri: https://github.com/puma/puma
         | 
| 120 | 
            -
            post_install_message: | 
| 121 | 
            +
            post_install_message:
         | 
| 121 122 | 
             
            rdoc_options: []
         | 
| 122 123 | 
             
            require_paths:
         | 
| 123 124 | 
             
            - lib
         | 
| @@ -133,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 133 134 | 
             
                  version: 1.3.1
         | 
| 134 135 | 
             
            requirements: []
         | 
| 135 136 | 
             
            rubygems_version: 3.1.2
         | 
| 136 | 
            -
            signing_key: | 
| 137 | 
            +
            signing_key:
         | 
| 137 138 | 
             
            specification_version: 4
         | 
| 138 139 | 
             
            summary: Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for
         | 
| 139 140 | 
             
              Ruby/Rack applications
         |