puma 1.6.3-java → 2.0.0.b1-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.
- data/History.txt +13 -0
 - data/Manifest.txt +18 -0
 - data/Rakefile +6 -0
 - data/docs/config.md +0 -0
 - data/docs/nginx.md +85 -0
 - data/examples/puma/keystore.jks +0 -0
 - data/ext/puma_http11/PumaHttp11Service.java +2 -0
 - data/ext/puma_http11/extconf.rb +3 -0
 - data/ext/puma_http11/io_buffer.c +146 -0
 - data/ext/puma_http11/mini_ssl.c +189 -0
 - data/ext/puma_http11/org/jruby/puma/MiniSSL.java +289 -0
 - data/ext/puma_http11/puma_http11.c +6 -0
 - data/lib/puma/accept_nonblock.rb +23 -0
 - data/lib/puma/binder.rb +253 -0
 - data/lib/puma/cli.rb +212 -114
 - data/lib/puma/client.rb +28 -3
 - data/lib/puma/configuration.rb +11 -4
 - data/lib/puma/const.rb +12 -1
 - data/lib/puma/delegation.rb +11 -0
 - data/lib/puma/events.rb +18 -0
 - data/lib/puma/io_buffer.rb +7 -0
 - data/lib/puma/java_io_buffer.rb +45 -0
 - data/lib/puma/minissl.rb +124 -0
 - data/lib/puma/puma_http11.bundle +0 -0
 - data/lib/puma/puma_http11.jar +0 -0
 - data/lib/puma/reactor.rb +4 -1
 - data/lib/puma/server.rb +67 -144
 - data/lib/puma/thread_pool.rb +5 -2
 - data/puma.gemspec +5 -5
 - data/test/test_integration.rb +53 -2
 - data/test/test_iobuffer.rb +38 -0
 - data/test/test_puma_server.rb +12 -7
 - data/tools/jungle/README.md +54 -0
 - data/tools/jungle/puma +332 -0
 - data/tools/jungle/run-puma +3 -0
 - metadata +24 -6
 
    
        data/lib/puma/cli.rb
    CHANGED
    
    | 
         @@ -4,6 +4,7 @@ require 'uri' 
     | 
|
| 
       4 
4 
     | 
    
         
             
            require 'puma/server'
         
     | 
| 
       5 
5 
     | 
    
         
             
            require 'puma/const'
         
     | 
| 
       6 
6 
     | 
    
         
             
            require 'puma/configuration'
         
     | 
| 
      
 7 
     | 
    
         
            +
            require 'puma/binder'
         
     | 
| 
       7 
8 
     | 
    
         
             
            require 'puma/detect'
         
     | 
| 
       8 
9 
     | 
    
         | 
| 
       9 
10 
     | 
    
         
             
            require 'rack/commonlogger'
         
     | 
| 
         @@ -20,10 +21,13 @@ module Puma 
     | 
|
| 
       20 
21 
     | 
    
         
             
                # this object will report status on.
         
     | 
| 
       21 
22 
     | 
    
         
             
                #
         
     | 
| 
       22 
23 
     | 
    
         
             
                def initialize(argv, stdout=STDOUT, stderr=STDERR)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @debug = false
         
     | 
| 
       23 
25 
     | 
    
         
             
                  @argv = argv
         
     | 
| 
       24 
26 
     | 
    
         
             
                  @stdout = stdout
         
     | 
| 
       25 
27 
     | 
    
         
             
                  @stderr = stderr
         
     | 
| 
       26 
28 
     | 
    
         | 
| 
      
 29 
     | 
    
         
            +
                  @workers = []
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
       27 
31 
     | 
    
         
             
                  @events = Events.new @stdout, @stderr
         
     | 
| 
       28 
32 
     | 
    
         | 
| 
       29 
33 
     | 
    
         
             
                  @server = nil
         
     | 
| 
         @@ -31,26 +35,12 @@ module Puma 
     | 
|
| 
       31 
35 
     | 
    
         | 
| 
       32 
36 
     | 
    
         
             
                  @restart = false
         
     | 
| 
       33 
37 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
                  @listeners = []
         
     | 
| 
       35 
     | 
    
         
            -
             
     | 
| 
       36 
38 
     | 
    
         
             
                  setup_options
         
     | 
| 
       37 
39 
     | 
    
         | 
| 
       38 
40 
     | 
    
         
             
                  generate_restart_data
         
     | 
| 
       39 
41 
     | 
    
         | 
| 
       40 
     | 
    
         
            -
                  @ 
     | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
       42 
     | 
    
         
            -
             
     | 
| 
       43 
     | 
    
         
            -
                  ENV.each do |k,v|
         
     | 
| 
       44 
     | 
    
         
            -
                    if k =~ /PUMA_INHERIT_\d+/
         
     | 
| 
       45 
     | 
    
         
            -
                      fd, url = v.split(":", 2)
         
     | 
| 
       46 
     | 
    
         
            -
                      @inherited_fds[url] = fd.to_i
         
     | 
| 
       47 
     | 
    
         
            -
                      remove << k
         
     | 
| 
       48 
     | 
    
         
            -
                    end
         
     | 
| 
       49 
     | 
    
         
            -
                  end
         
     | 
| 
       50 
     | 
    
         
            -
             
     | 
| 
       51 
     | 
    
         
            -
                  remove.each do |k|
         
     | 
| 
       52 
     | 
    
         
            -
                    ENV.delete k
         
     | 
| 
       53 
     | 
    
         
            -
                  end
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @binder = Binder.new(@events)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @binder.import_from_env
         
     | 
| 
       54 
44 
     | 
    
         
             
                end
         
     | 
| 
       55 
45 
     | 
    
         | 
| 
       56 
46 
     | 
    
         
             
                def restart_on_stop!
         
     | 
| 
         @@ -98,8 +88,8 @@ module Puma 
     | 
|
| 
       98 
88 
     | 
    
         
             
                    blk.call self
         
     | 
| 
       99 
89 
     | 
    
         
             
                  end
         
     | 
| 
       100 
90 
     | 
    
         | 
| 
       101 
     | 
    
         
            -
                  if  
     | 
| 
       102 
     | 
    
         
            -
                    @listeners.each_with_index do |(str,io),i|
         
     | 
| 
      
 91 
     | 
    
         
            +
                  if jruby?
         
     | 
| 
      
 92 
     | 
    
         
            +
                    @binder.listeners.each_with_index do |(str,io),i|
         
     | 
| 
       103 
93 
     | 
    
         
             
                      io.close
         
     | 
| 
       104 
94 
     | 
    
         | 
| 
       105 
95 
     | 
    
         
             
                      # We have to unlink a unix socket path that's not being used
         
     | 
| 
         @@ -113,7 +103,7 @@ module Puma 
     | 
|
| 
       113 
103 
     | 
    
         
             
                    require 'puma/jruby_restart'
         
     | 
| 
       114 
104 
     | 
    
         
             
                    JRubyRestart.chdir_exec(@restart_dir, Gem.ruby, *@restart_argv)
         
     | 
| 
       115 
105 
     | 
    
         
             
                  else
         
     | 
| 
       116 
     | 
    
         
            -
                    @listeners.each_with_index do |(l,io),i|
         
     | 
| 
      
 106 
     | 
    
         
            +
                    @binder.listeners.each_with_index do |(l,io),i|
         
     | 
| 
       117 
107 
     | 
    
         
             
                      ENV["PUMA_INHERIT_#{i}"] = "#{io.to_i}:#{l}"
         
     | 
| 
       118 
108 
     | 
    
         
             
                    end
         
     | 
| 
       119 
109 
     | 
    
         | 
| 
         @@ -140,6 +130,26 @@ module Puma 
     | 
|
| 
       140 
130 
     | 
    
         
             
                  @events.error str
         
     | 
| 
       141 
131 
     | 
    
         
             
                end
         
     | 
| 
       142 
132 
     | 
    
         | 
| 
      
 133 
     | 
    
         
            +
                def debug(str)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  if @options[:debug]
         
     | 
| 
      
 135 
     | 
    
         
            +
                    @events.log "- #{str}"
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
      
 137 
     | 
    
         
            +
                end
         
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
      
 139 
     | 
    
         
            +
                def jruby?
         
     | 
| 
      
 140 
     | 
    
         
            +
                  IS_JRUBY
         
     | 
| 
      
 141 
     | 
    
         
            +
                end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                def windows?
         
     | 
| 
      
 144 
     | 
    
         
            +
                  RUBY_PLATFORM =~ /mswin32|ming32/
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                def unsupported(str, cond=true)
         
     | 
| 
      
 148 
     | 
    
         
            +
                  return unless cond
         
     | 
| 
      
 149 
     | 
    
         
            +
                  @events.error str
         
     | 
| 
      
 150 
     | 
    
         
            +
                  raise UnsupportedOption
         
     | 
| 
      
 151 
     | 
    
         
            +
                end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
       143 
153 
     | 
    
         
             
                # Build the OptionParser object to handle the available options.
         
     | 
| 
       144 
154 
     | 
    
         
             
                #
         
     | 
| 
       145 
155 
     | 
    
         
             
                def setup_options
         
     | 
| 
         @@ -147,11 +157,13 @@ module Puma 
     | 
|
| 
       147 
157 
     | 
    
         
             
                    :min_threads => 0,
         
     | 
| 
       148 
158 
     | 
    
         
             
                    :max_threads => 16,
         
     | 
| 
       149 
159 
     | 
    
         
             
                    :quiet => false,
         
     | 
| 
       150 
     | 
    
         
            -
                    : 
     | 
| 
      
 160 
     | 
    
         
            +
                    :debug => false,
         
     | 
| 
      
 161 
     | 
    
         
            +
                    :binds => [],
         
     | 
| 
      
 162 
     | 
    
         
            +
                    :workers => 0
         
     | 
| 
       151 
163 
     | 
    
         
             
                  }
         
     | 
| 
       152 
164 
     | 
    
         | 
| 
       153 
165 
     | 
    
         
             
                  @parser = OptionParser.new do |o|
         
     | 
| 
       154 
     | 
    
         
            -
                    o.on "-b", "--bind URI", "URI to bind to (tcp 
     | 
| 
      
 166 
     | 
    
         
            +
                    o.on "-b", "--bind URI", "URI to bind to (tcp://, unix://, ssl://)" do |arg|
         
     | 
| 
       155 
167 
     | 
    
         
             
                      @options[:binds] << arg
         
     | 
| 
       156 
168 
     | 
    
         
             
                    end
         
     | 
| 
       157 
169 
     | 
    
         | 
| 
         @@ -176,6 +188,10 @@ module Puma 
     | 
|
| 
       176 
188 
     | 
    
         
             
                      @options[:quiet] = true
         
     | 
| 
       177 
189 
     | 
    
         
             
                    end
         
     | 
| 
       178 
190 
     | 
    
         | 
| 
      
 191 
     | 
    
         
            +
                    o.on "--debug", "Log lowlevel debugging information" do
         
     | 
| 
      
 192 
     | 
    
         
            +
                      @options[:debug] = true
         
     | 
| 
      
 193 
     | 
    
         
            +
                    end
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
       179 
195 
     | 
    
         
             
                    o.on "-S", "--state PATH", "Where to store the state details" do |arg|
         
     | 
| 
       180 
196 
     | 
    
         
             
                      @options[:state] = arg
         
     | 
| 
       181 
197 
     | 
    
         
             
                    end
         
     | 
| 
         @@ -184,8 +200,8 @@ module Puma 
     | 
|
| 
       184 
200 
     | 
    
         
             
                                          "Use 'auto' to use temp unix server" do |arg|
         
     | 
| 
       185 
201 
     | 
    
         
             
                      if arg
         
     | 
| 
       186 
202 
     | 
    
         
             
                        @options[:control_url] = arg
         
     | 
| 
       187 
     | 
    
         
            -
                      elsif  
     | 
| 
       188 
     | 
    
         
            -
                         
     | 
| 
      
 203 
     | 
    
         
            +
                      elsif jruby?
         
     | 
| 
      
 204 
     | 
    
         
            +
                        unsupported "No default url available on JRuby"
         
     | 
| 
       189 
205 
     | 
    
         
             
                      end
         
     | 
| 
       190 
206 
     | 
    
         
             
                    end
         
     | 
| 
       191 
207 
     | 
    
         | 
| 
         @@ -205,6 +221,14 @@ module Puma 
     | 
|
| 
       205 
221 
     | 
    
         
             
                      end
         
     | 
| 
       206 
222 
     | 
    
         
             
                    end
         
     | 
| 
       207 
223 
     | 
    
         | 
| 
      
 224 
     | 
    
         
            +
                    o.on "-w", "--workers COUNT",
         
     | 
| 
      
 225 
     | 
    
         
            +
                               "Activate cluster mode: How many worker processes to create" do |arg|
         
     | 
| 
      
 226 
     | 
    
         
            +
                      unsupported "-w not supported on JRuby and Windows",
         
     | 
| 
      
 227 
     | 
    
         
            +
                                  jruby? || windows?
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                      @options[:workers] = arg.to_i
         
     | 
| 
      
 230 
     | 
    
         
            +
                    end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
       208 
232 
     | 
    
         
             
                    o.on "--restart-cmd CMD",
         
     | 
| 
       209 
233 
     | 
    
         
             
                         "The puma command to run during a hot restart",
         
     | 
| 
       210 
234 
     | 
    
         
             
                         "Default: inferred" do |cmd|
         
     | 
| 
         @@ -291,19 +315,39 @@ module Puma 
     | 
|
| 
       291 
315 
     | 
    
         
             
                # for it to finish.
         
     | 
| 
       292 
316 
     | 
    
         
             
                #
         
     | 
| 
       293 
317 
     | 
    
         
             
                def run
         
     | 
| 
       294 
     | 
    
         
            -
                   
     | 
| 
      
 318 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 319 
     | 
    
         
            +
                    parse_options
         
     | 
| 
      
 320 
     | 
    
         
            +
                  rescue UnsupportedOption
         
     | 
| 
      
 321 
     | 
    
         
            +
                    exit 1
         
     | 
| 
      
 322 
     | 
    
         
            +
                  end
         
     | 
| 
       295 
323 
     | 
    
         | 
| 
       296 
     | 
    
         
            -
                   
     | 
| 
      
 324 
     | 
    
         
            +
                  clustered = @options[:workers] > 0
         
     | 
| 
      
 325 
     | 
    
         
            +
             
     | 
| 
      
 326 
     | 
    
         
            +
                  if clustered
         
     | 
| 
      
 327 
     | 
    
         
            +
                    @events = PidEvents.new STDOUT, STDERR
         
     | 
| 
      
 328 
     | 
    
         
            +
                    @options[:logger] = @events
         
     | 
| 
      
 329 
     | 
    
         
            +
                  end
         
     | 
| 
       297 
330 
     | 
    
         | 
| 
       298 
     | 
    
         
            -
                   
     | 
| 
      
 331 
     | 
    
         
            +
                  set_rack_environment
         
     | 
| 
       299 
332 
     | 
    
         | 
| 
       300 
333 
     | 
    
         
             
                  write_pid
         
     | 
| 
       301 
334 
     | 
    
         
             
                  write_state
         
     | 
| 
       302 
335 
     | 
    
         | 
| 
      
 336 
     | 
    
         
            +
                  @binder.parse @options[:binds], self
         
     | 
| 
      
 337 
     | 
    
         
            +
             
     | 
| 
      
 338 
     | 
    
         
            +
                  if clustered
         
     | 
| 
      
 339 
     | 
    
         
            +
                    run_cluster
         
     | 
| 
      
 340 
     | 
    
         
            +
                  else
         
     | 
| 
      
 341 
     | 
    
         
            +
                    run_single
         
     | 
| 
      
 342 
     | 
    
         
            +
                  end
         
     | 
| 
      
 343 
     | 
    
         
            +
                end
         
     | 
| 
      
 344 
     | 
    
         
            +
             
     | 
| 
      
 345 
     | 
    
         
            +
                def run_single
         
     | 
| 
       303 
346 
     | 
    
         
             
                  min_t = @options[:min_threads]
         
     | 
| 
       304 
347 
     | 
    
         
             
                  max_t = @options[:max_threads]
         
     | 
| 
       305 
348 
     | 
    
         | 
| 
       306 
     | 
    
         
            -
                  server = Puma::Server.new app, @events
         
     | 
| 
      
 349 
     | 
    
         
            +
                  server = Puma::Server.new @config.app, @events
         
     | 
| 
      
 350 
     | 
    
         
            +
                  server.binder = @binder
         
     | 
| 
       307 
351 
     | 
    
         
             
                  server.min_threads = min_t
         
     | 
| 
       308 
352 
     | 
    
         
             
                  server.max_threads = max_t
         
     | 
| 
       309 
353 
     | 
    
         | 
| 
         @@ -311,93 +355,6 @@ module Puma 
     | 
|
| 
       311 
355 
     | 
    
         
             
                  log "* Min threads: #{min_t}, max threads: #{max_t}"
         
     | 
| 
       312 
356 
     | 
    
         
             
                  log "* Environment: #{ENV['RACK_ENV']}"
         
     | 
| 
       313 
357 
     | 
    
         | 
| 
       314 
     | 
    
         
            -
                  @options[:binds].each do |str|
         
     | 
| 
       315 
     | 
    
         
            -
                    uri = URI.parse str
         
     | 
| 
       316 
     | 
    
         
            -
                    case uri.scheme
         
     | 
| 
       317 
     | 
    
         
            -
                    when "tcp"
         
     | 
| 
       318 
     | 
    
         
            -
                      if fd = @inherited_fds.delete(str)
         
     | 
| 
       319 
     | 
    
         
            -
                        log "* Inherited #{str}"
         
     | 
| 
       320 
     | 
    
         
            -
                        io = server.inherit_tcp_listener uri.host, uri.port, fd
         
     | 
| 
       321 
     | 
    
         
            -
                      else
         
     | 
| 
       322 
     | 
    
         
            -
                        log "* Listening on #{str}"
         
     | 
| 
       323 
     | 
    
         
            -
                        io = server.add_tcp_listener uri.host, uri.port
         
     | 
| 
       324 
     | 
    
         
            -
                      end
         
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
       326 
     | 
    
         
            -
                      @listeners << [str, io]
         
     | 
| 
       327 
     | 
    
         
            -
                    when "unix"
         
     | 
| 
       328 
     | 
    
         
            -
                      path = "#{uri.host}#{uri.path}"
         
     | 
| 
       329 
     | 
    
         
            -
             
     | 
| 
       330 
     | 
    
         
            -
                      if fd = @inherited_fds.delete(str)
         
     | 
| 
       331 
     | 
    
         
            -
                        log "* Inherited #{str}"
         
     | 
| 
       332 
     | 
    
         
            -
                        io = server.inherit_unix_listener path, fd
         
     | 
| 
       333 
     | 
    
         
            -
                      else
         
     | 
| 
       334 
     | 
    
         
            -
                        log "* Listening on #{str}"
         
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
                        umask = nil
         
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
                        if uri.query
         
     | 
| 
       339 
     | 
    
         
            -
                          params = Rack::Utils.parse_query uri.query
         
     | 
| 
       340 
     | 
    
         
            -
                          if u = params['umask']
         
     | 
| 
       341 
     | 
    
         
            -
                            # Use Integer() to respect the 0 prefix as octal
         
     | 
| 
       342 
     | 
    
         
            -
                            umask = Integer(u)
         
     | 
| 
       343 
     | 
    
         
            -
                          end
         
     | 
| 
       344 
     | 
    
         
            -
                        end
         
     | 
| 
       345 
     | 
    
         
            -
             
     | 
| 
       346 
     | 
    
         
            -
                        io = server.add_unix_listener path, umask
         
     | 
| 
       347 
     | 
    
         
            -
                      end
         
     | 
| 
       348 
     | 
    
         
            -
             
     | 
| 
       349 
     | 
    
         
            -
                      @listeners << [str, io]
         
     | 
| 
       350 
     | 
    
         
            -
                    when "ssl"
         
     | 
| 
       351 
     | 
    
         
            -
                      params = Rack::Utils.parse_query uri.query
         
     | 
| 
       352 
     | 
    
         
            -
                      require 'openssl'
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
                      ctx = OpenSSL::SSL::SSLContext.new
         
     | 
| 
       355 
     | 
    
         
            -
                      unless params['key']
         
     | 
| 
       356 
     | 
    
         
            -
                        error "Please specify the SSL key via 'key='"
         
     | 
| 
       357 
     | 
    
         
            -
                      end
         
     | 
| 
       358 
     | 
    
         
            -
             
     | 
| 
       359 
     | 
    
         
            -
                      ctx.key = OpenSSL::PKey::RSA.new File.read(params['key'])
         
     | 
| 
       360 
     | 
    
         
            -
             
     | 
| 
       361 
     | 
    
         
            -
                      unless params['cert']
         
     | 
| 
       362 
     | 
    
         
            -
                        error "Please specify the SSL cert via 'cert='"
         
     | 
| 
       363 
     | 
    
         
            -
                      end
         
     | 
| 
       364 
     | 
    
         
            -
             
     | 
| 
       365 
     | 
    
         
            -
                      ctx.cert = OpenSSL::X509::Certificate.new File.read(params['cert'])
         
     | 
| 
       366 
     | 
    
         
            -
             
     | 
| 
       367 
     | 
    
         
            -
                      ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
         
     | 
| 
       368 
     | 
    
         
            -
             
     | 
| 
       369 
     | 
    
         
            -
                      if fd = @inherited_fds.delete(str)
         
     | 
| 
       370 
     | 
    
         
            -
                        log "* Inherited #{str}"
         
     | 
| 
       371 
     | 
    
         
            -
                        io = server.inherited_ssl_listener fd, ctx
         
     | 
| 
       372 
     | 
    
         
            -
                      else
         
     | 
| 
       373 
     | 
    
         
            -
                        log "* Listening on #{str}"
         
     | 
| 
       374 
     | 
    
         
            -
                        io = server.add_ssl_listener uri.host, uri.port, ctx
         
     | 
| 
       375 
     | 
    
         
            -
                      end
         
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
       377 
     | 
    
         
            -
                      @listeners << [str, io]
         
     | 
| 
       378 
     | 
    
         
            -
                    else
         
     | 
| 
       379 
     | 
    
         
            -
                      error "Invalid URI: #{str}"
         
     | 
| 
       380 
     | 
    
         
            -
                    end
         
     | 
| 
       381 
     | 
    
         
            -
                  end
         
     | 
| 
       382 
     | 
    
         
            -
             
     | 
| 
       383 
     | 
    
         
            -
                  # If we inherited fds but didn't use them (because of a
         
     | 
| 
       384 
     | 
    
         
            -
                  # configuration change), then be sure to close them.
         
     | 
| 
       385 
     | 
    
         
            -
                  @inherited_fds.each do |str, fd|
         
     | 
| 
       386 
     | 
    
         
            -
                    log "* Closing unused inherited connection: #{str}"
         
     | 
| 
       387 
     | 
    
         
            -
             
     | 
| 
       388 
     | 
    
         
            -
                    begin
         
     | 
| 
       389 
     | 
    
         
            -
                      IO.for_fd(fd).close
         
     | 
| 
       390 
     | 
    
         
            -
                    rescue SystemCallError
         
     | 
| 
       391 
     | 
    
         
            -
                    end
         
     | 
| 
       392 
     | 
    
         
            -
             
     | 
| 
       393 
     | 
    
         
            -
                    # We have to unlink a unix socket path that's not being used
         
     | 
| 
       394 
     | 
    
         
            -
                    uri = URI.parse str
         
     | 
| 
       395 
     | 
    
         
            -
                    if uri.scheme == "unix"
         
     | 
| 
       396 
     | 
    
         
            -
                      path = "#{uri.host}#{uri.path}"
         
     | 
| 
       397 
     | 
    
         
            -
                      File.unlink path
         
     | 
| 
       398 
     | 
    
         
            -
                    end
         
     | 
| 
       399 
     | 
    
         
            -
                  end
         
     | 
| 
       400 
     | 
    
         
            -
             
     | 
| 
       401 
358 
     | 
    
         
             
                  @server = server
         
     | 
| 
       402 
359 
     | 
    
         | 
| 
       403 
360 
     | 
    
         
             
                  if str = @options[:control_url]
         
     | 
| 
         @@ -465,6 +422,147 @@ module Puma 
     | 
|
| 
       465 
422 
     | 
    
         
             
                  end
         
     | 
| 
       466 
423 
     | 
    
         
             
                end
         
     | 
| 
       467 
424 
     | 
    
         | 
| 
      
 425 
     | 
    
         
            +
                def worker
         
     | 
| 
      
 426 
     | 
    
         
            +
                  $0 = "puma: cluster worker: #{@master_pid}"
         
     | 
| 
      
 427 
     | 
    
         
            +
                  Signal.trap "SIGINT", "IGNORE"
         
     | 
| 
      
 428 
     | 
    
         
            +
             
     | 
| 
      
 429 
     | 
    
         
            +
                  @suicide_pipe.close
         
     | 
| 
      
 430 
     | 
    
         
            +
             
     | 
| 
      
 431 
     | 
    
         
            +
                  Thread.new do
         
     | 
| 
      
 432 
     | 
    
         
            +
                    IO.select [@check_pipe]
         
     | 
| 
      
 433 
     | 
    
         
            +
                    log "! Detected parent died, dieing"
         
     | 
| 
      
 434 
     | 
    
         
            +
                    exit! 1
         
     | 
| 
      
 435 
     | 
    
         
            +
                  end
         
     | 
| 
      
 436 
     | 
    
         
            +
             
     | 
| 
      
 437 
     | 
    
         
            +
                  min_t = @options[:min_threads]
         
     | 
| 
      
 438 
     | 
    
         
            +
                  max_t = @options[:max_threads]
         
     | 
| 
      
 439 
     | 
    
         
            +
             
     | 
| 
      
 440 
     | 
    
         
            +
                  server = Puma::Server.new @config.app, @events
         
     | 
| 
      
 441 
     | 
    
         
            +
                  server.min_threads = min_t
         
     | 
| 
      
 442 
     | 
    
         
            +
                  server.max_threads = max_t
         
     | 
| 
      
 443 
     | 
    
         
            +
                  server.binder = @binder
         
     | 
| 
      
 444 
     | 
    
         
            +
             
     | 
| 
      
 445 
     | 
    
         
            +
                  Signal.trap "SIGTERM" do
         
     | 
| 
      
 446 
     | 
    
         
            +
                    server.stop
         
     | 
| 
      
 447 
     | 
    
         
            +
                  end
         
     | 
| 
      
 448 
     | 
    
         
            +
             
     | 
| 
      
 449 
     | 
    
         
            +
                  server.run.join
         
     | 
| 
      
 450 
     | 
    
         
            +
                end
         
     | 
| 
      
 451 
     | 
    
         
            +
             
     | 
| 
      
 452 
     | 
    
         
            +
                def stop_workers
         
     | 
| 
      
 453 
     | 
    
         
            +
                  log "- Gracefully shutting down workers..."
         
     | 
| 
      
 454 
     | 
    
         
            +
                  @workers.each { |x| x.term }
         
     | 
| 
      
 455 
     | 
    
         
            +
             
     | 
| 
      
 456 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 457 
     | 
    
         
            +
                    Process.waitall
         
     | 
| 
      
 458 
     | 
    
         
            +
                  rescue Interrupt
         
     | 
| 
      
 459 
     | 
    
         
            +
                    log "! Cancelled waiting for workers"
         
     | 
| 
      
 460 
     | 
    
         
            +
                  else
         
     | 
| 
      
 461 
     | 
    
         
            +
                    log "- Goodbye!"
         
     | 
| 
      
 462 
     | 
    
         
            +
                  end
         
     | 
| 
      
 463 
     | 
    
         
            +
                end
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
                class Worker
         
     | 
| 
      
 466 
     | 
    
         
            +
                  def initialize(pid)
         
     | 
| 
      
 467 
     | 
    
         
            +
                    @pid = pid
         
     | 
| 
      
 468 
     | 
    
         
            +
                  end
         
     | 
| 
      
 469 
     | 
    
         
            +
             
     | 
| 
      
 470 
     | 
    
         
            +
                  attr_reader :pid
         
     | 
| 
      
 471 
     | 
    
         
            +
             
     | 
| 
      
 472 
     | 
    
         
            +
                  def term
         
     | 
| 
      
 473 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 474 
     | 
    
         
            +
                      Process.kill "TERM", @pid
         
     | 
| 
      
 475 
     | 
    
         
            +
                    rescue Errno::ESRCH
         
     | 
| 
      
 476 
     | 
    
         
            +
                    end
         
     | 
| 
      
 477 
     | 
    
         
            +
                  end
         
     | 
| 
      
 478 
     | 
    
         
            +
                end
         
     | 
| 
      
 479 
     | 
    
         
            +
             
     | 
| 
      
 480 
     | 
    
         
            +
                def spawn_workers
         
     | 
| 
      
 481 
     | 
    
         
            +
                  diff = @options[:workers] - @workers.size
         
     | 
| 
      
 482 
     | 
    
         
            +
             
     | 
| 
      
 483 
     | 
    
         
            +
                  diff.times do
         
     | 
| 
      
 484 
     | 
    
         
            +
                    pid = fork { worker }
         
     | 
| 
      
 485 
     | 
    
         
            +
                    debug "Spawned worker: #{pid}"
         
     | 
| 
      
 486 
     | 
    
         
            +
                    @workers << Worker.new(pid)
         
     | 
| 
      
 487 
     | 
    
         
            +
                  end
         
     | 
| 
      
 488 
     | 
    
         
            +
                end
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
      
 490 
     | 
    
         
            +
                def check_workers
         
     | 
| 
      
 491 
     | 
    
         
            +
                  while true
         
     | 
| 
      
 492 
     | 
    
         
            +
                    pid = Process.waitpid(-1, Process::WNOHANG)
         
     | 
| 
      
 493 
     | 
    
         
            +
                    break unless pid
         
     | 
| 
      
 494 
     | 
    
         
            +
             
     | 
| 
      
 495 
     | 
    
         
            +
                    @workers.delete_if { |w| w.pid == pid }
         
     | 
| 
      
 496 
     | 
    
         
            +
                  end
         
     | 
| 
      
 497 
     | 
    
         
            +
             
     | 
| 
      
 498 
     | 
    
         
            +
                  spawn_workers
         
     | 
| 
      
 499 
     | 
    
         
            +
                end
         
     | 
| 
      
 500 
     | 
    
         
            +
             
     | 
| 
      
 501 
     | 
    
         
            +
                def run_cluster
         
     | 
| 
      
 502 
     | 
    
         
            +
                  log "Puma #{Puma::Const::PUMA_VERSION} starting in cluster mode..."
         
     | 
| 
      
 503 
     | 
    
         
            +
                  log "* Process workers: #{@options[:workers]}"
         
     | 
| 
      
 504 
     | 
    
         
            +
                  log "* Min threads: #{@options[:min_threads]}, max threads: #{@options[:max_threads]}"
         
     | 
| 
      
 505 
     | 
    
         
            +
                  log "* Environment: #{ENV['RACK_ENV']}"
         
     | 
| 
      
 506 
     | 
    
         
            +
             
     | 
| 
      
 507 
     | 
    
         
            +
                  @master_pid = Process.pid
         
     | 
| 
      
 508 
     | 
    
         
            +
             
     | 
| 
      
 509 
     | 
    
         
            +
                  read, write = IO.pipe
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
      
 511 
     | 
    
         
            +
                  Signal.trap "SIGCHLD" do
         
     | 
| 
      
 512 
     | 
    
         
            +
                    write.write "!"
         
     | 
| 
      
 513 
     | 
    
         
            +
                  end
         
     | 
| 
      
 514 
     | 
    
         
            +
             
     | 
| 
      
 515 
     | 
    
         
            +
                  stop = false
         
     | 
| 
      
 516 
     | 
    
         
            +
             
     | 
| 
      
 517 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 518 
     | 
    
         
            +
                    Signal.trap "SIGUSR2" do
         
     | 
| 
      
 519 
     | 
    
         
            +
                      @restart = true
         
     | 
| 
      
 520 
     | 
    
         
            +
                      stop = true
         
     | 
| 
      
 521 
     | 
    
         
            +
                      write.write "!"
         
     | 
| 
      
 522 
     | 
    
         
            +
                    end
         
     | 
| 
      
 523 
     | 
    
         
            +
                  rescue Exception
         
     | 
| 
      
 524 
     | 
    
         
            +
                  end
         
     | 
| 
      
 525 
     | 
    
         
            +
             
     | 
| 
      
 526 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 527 
     | 
    
         
            +
                    Signal.trap "SIGTERM" do
         
     | 
| 
      
 528 
     | 
    
         
            +
                      stop = true
         
     | 
| 
      
 529 
     | 
    
         
            +
                      write.write "!"
         
     | 
| 
      
 530 
     | 
    
         
            +
                    end
         
     | 
| 
      
 531 
     | 
    
         
            +
                  rescue Exception
         
     | 
| 
      
 532 
     | 
    
         
            +
                  end
         
     | 
| 
      
 533 
     | 
    
         
            +
             
     | 
| 
      
 534 
     | 
    
         
            +
                  # Used by the workers to detect if the master process dies.
         
     | 
| 
      
 535 
     | 
    
         
            +
                  # If select says that @check_pipe is ready, it's because the
         
     | 
| 
      
 536 
     | 
    
         
            +
                  # master has exited and @suicide_pipe has been automatically
         
     | 
| 
      
 537 
     | 
    
         
            +
                  # closed.
         
     | 
| 
      
 538 
     | 
    
         
            +
                  #
         
     | 
| 
      
 539 
     | 
    
         
            +
                  @check_pipe, @suicide_pipe = IO.pipe
         
     | 
| 
      
 540 
     | 
    
         
            +
             
     | 
| 
      
 541 
     | 
    
         
            +
                  spawn_workers
         
     | 
| 
      
 542 
     | 
    
         
            +
             
     | 
| 
      
 543 
     | 
    
         
            +
                  log "* Use Ctrl-C to stop"
         
     | 
| 
      
 544 
     | 
    
         
            +
             
     | 
| 
      
 545 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 546 
     | 
    
         
            +
                    while !stop
         
     | 
| 
      
 547 
     | 
    
         
            +
                      begin
         
     | 
| 
      
 548 
     | 
    
         
            +
                        IO.select([read], nil, nil, 5)
         
     | 
| 
      
 549 
     | 
    
         
            +
                        check_workers
         
     | 
| 
      
 550 
     | 
    
         
            +
                      rescue Interrupt
         
     | 
| 
      
 551 
     | 
    
         
            +
                        stop = true
         
     | 
| 
      
 552 
     | 
    
         
            +
                      end
         
     | 
| 
      
 553 
     | 
    
         
            +
                    end
         
     | 
| 
      
 554 
     | 
    
         
            +
             
     | 
| 
      
 555 
     | 
    
         
            +
                    stop_workers
         
     | 
| 
      
 556 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 557 
     | 
    
         
            +
                    delete_pidfile
         
     | 
| 
      
 558 
     | 
    
         
            +
                  end
         
     | 
| 
      
 559 
     | 
    
         
            +
             
     | 
| 
      
 560 
     | 
    
         
            +
                  if @restart
         
     | 
| 
      
 561 
     | 
    
         
            +
                    log "* Restarting..."
         
     | 
| 
      
 562 
     | 
    
         
            +
                    restart!
         
     | 
| 
      
 563 
     | 
    
         
            +
                  end
         
     | 
| 
      
 564 
     | 
    
         
            +
                end
         
     | 
| 
      
 565 
     | 
    
         
            +
             
     | 
| 
       468 
566 
     | 
    
         
             
                def stop
         
     | 
| 
       469 
567 
     | 
    
         
             
                  @server.stop(true) if @server
         
     | 
| 
       470 
568 
     | 
    
         
             
                  delete_pidfile
         
     | 
    
        data/lib/puma/client.rb
    CHANGED
    
    | 
         @@ -48,7 +48,7 @@ module Puma 
     | 
|
| 
       48 
48 
     | 
    
         
             
                  @timeout_at = Time.now + val
         
     | 
| 
       49 
49 
     | 
    
         
             
                end
         
     | 
| 
       50 
50 
     | 
    
         | 
| 
       51 
     | 
    
         
            -
                def reset
         
     | 
| 
      
 51 
     | 
    
         
            +
                def reset(fast_check=true)
         
     | 
| 
       52 
52 
     | 
    
         
             
                  @parser.reset
         
     | 
| 
       53 
53 
     | 
    
         
             
                  @read_header = true
         
     | 
| 
       54 
54 
     | 
    
         
             
                  @env = @proto_env.dup
         
     | 
| 
         @@ -67,6 +67,9 @@ module Puma 
     | 
|
| 
       67 
67 
     | 
    
         
             
                    end
         
     | 
| 
       68 
68 
     | 
    
         | 
| 
       69 
69 
     | 
    
         
             
                    return false
         
     | 
| 
      
 70 
     | 
    
         
            +
                  elsif fast_check &&
         
     | 
| 
      
 71 
     | 
    
         
            +
                        IO.select([@to_io], nil, nil, FAST_TRACK_KA_TIMEOUT)
         
     | 
| 
      
 72 
     | 
    
         
            +
                    return try_to_finish
         
     | 
| 
       70 
73 
     | 
    
         
             
                  end
         
     | 
| 
       71 
74 
     | 
    
         
             
                end
         
     | 
| 
       72 
75 
     | 
    
         | 
| 
         @@ -124,7 +127,11 @@ module Puma 
     | 
|
| 
       124 
127 
     | 
    
         
             
                def try_to_finish
         
     | 
| 
       125 
128 
     | 
    
         
             
                  return read_body unless @read_header
         
     | 
| 
       126 
129 
     | 
    
         | 
| 
       127 
     | 
    
         
            -
                   
     | 
| 
      
 130 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 131 
     | 
    
         
            +
                    data = @io.read_nonblock(CHUNK_SIZE)
         
     | 
| 
      
 132 
     | 
    
         
            +
                  rescue Errno::EAGAIN
         
     | 
| 
      
 133 
     | 
    
         
            +
                    return false
         
     | 
| 
      
 134 
     | 
    
         
            +
                  end
         
     | 
| 
       128 
135 
     | 
    
         | 
| 
       129 
136 
     | 
    
         
             
                  if @buffer
         
     | 
| 
       130 
137 
     | 
    
         
             
                    @buffer << data
         
     | 
| 
         @@ -204,7 +211,11 @@ module Puma 
     | 
|
| 
       204 
211 
     | 
    
         
             
                    want = remain
         
     | 
| 
       205 
212 
     | 
    
         
             
                  end
         
     | 
| 
       206 
213 
     | 
    
         | 
| 
       207 
     | 
    
         
            -
                   
     | 
| 
      
 214 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 215 
     | 
    
         
            +
                    chunk = @io.read_nonblock(want)
         
     | 
| 
      
 216 
     | 
    
         
            +
                  rescue Errno::EAGAIN
         
     | 
| 
      
 217 
     | 
    
         
            +
                    return false
         
     | 
| 
      
 218 
     | 
    
         
            +
                  end
         
     | 
| 
       208 
219 
     | 
    
         | 
| 
       209 
220 
     | 
    
         
             
                  # No chunk means a closed socket
         
     | 
| 
       210 
221 
     | 
    
         
             
                  unless chunk
         
     | 
| 
         @@ -229,5 +240,19 @@ module Puma 
     | 
|
| 
       229 
240 
     | 
    
         | 
| 
       230 
241 
     | 
    
         
             
                  false
         
     | 
| 
       231 
242 
     | 
    
         
             
                end
         
     | 
| 
      
 243 
     | 
    
         
            +
             
     | 
| 
      
 244 
     | 
    
         
            +
                def write_400
         
     | 
| 
      
 245 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 246 
     | 
    
         
            +
                    @io << ERROR_400_RESPONSE
         
     | 
| 
      
 247 
     | 
    
         
            +
                  rescue StandardError
         
     | 
| 
      
 248 
     | 
    
         
            +
                  end
         
     | 
| 
      
 249 
     | 
    
         
            +
                end
         
     | 
| 
      
 250 
     | 
    
         
            +
             
     | 
| 
      
 251 
     | 
    
         
            +
                def write_500
         
     | 
| 
      
 252 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 253 
     | 
    
         
            +
                    @io << ERROR_500_RESPONSE
         
     | 
| 
      
 254 
     | 
    
         
            +
                  rescue StandardError
         
     | 
| 
      
 255 
     | 
    
         
            +
                  end
         
     | 
| 
      
 256 
     | 
    
         
            +
                end
         
     | 
| 
       232 
257 
     | 
    
         
             
              end
         
     | 
| 
       233 
258 
     | 
    
         
             
            end
         
     |