File: puma.rb

package info (click to toggle)
puma 6.6.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,884 kB
  • sloc: ruby: 17,542; ansic: 2,003; java: 1,006; sh: 379; makefile: 10
file content (144 lines) | stat: -rw-r--r-- 4,342 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# frozen_string_literal: true

module Puma

  # This module is used as an 'include' file in code at bottom of file. It loads
  # into either `Rackup::Handler::Puma` or `Rack::Handler::Puma`.

  module RackHandler
    DEFAULT_OPTIONS = {
      :Verbose => false,
      :Silent  => false
    }

    def config(app, options = {})
      require_relative '../../puma'
      require_relative '../../puma/configuration'
      require_relative '../../puma/log_writer'
      require_relative '../../puma/launcher'

      default_options = DEFAULT_OPTIONS.dup

      # Libraries pass in values such as :Port and there is no way to determine
      # if it is a default provided by the library or a special value provided
      # by the user. A special key `user_supplied_options` can be passed. This
      # contains an array of all explicitly defined user options. We then
      # know that all other values are defaults
      if user_supplied_options = options.delete(:user_supplied_options)
        (options.keys - user_supplied_options).each do |k|
          default_options[k] = options.delete(k)
        end
      end

      @events = options[:events] || ::Puma::Events.new

      conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
        if options.delete(:Verbose)
          begin
            require 'rack/commonlogger'  # Rack 1.x
          rescue LoadError
            require 'rack/common_logger' # Rack 2 and later
          end
          app = ::Rack::CommonLogger.new(app, STDOUT)
        end

        if options[:environment]
          user_config.environment options[:environment]
        end

        if options[:Threads]
          min, max = options.delete(:Threads).split(':', 2)
          user_config.threads min, max
        end

        if options[:Host] || options[:Port]
          host = options[:Host] || default_options[:Host]
          port = options[:Port] || default_options[:Port]
          self.set_host_port_to_config(host, port, user_config)
        end

        if default_options[:Host]
          file_config.set_default_host(default_options[:Host])
        end
        self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)

        user_config.app app
      end
      conf
    end

    def run(app, **options)
      conf = self.config(app, options)

      log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio

      launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)

      yield launcher if block_given?
      begin
        launcher.run
      rescue Interrupt
        puts "* Gracefully stopping, waiting for requests to finish"
        launcher.stop
        puts "* Goodbye!"
      end
    end

    def valid_options
      {
        "Host=HOST"       => "Hostname to listen on (default: localhost)",
        "Port=PORT"       => "Port to listen on (default: 8080)",
        "Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
        "Verbose"         => "Don't report each request (default: false)"
      }
    end

    def set_host_port_to_config(host, port, config)
      config.clear_binds! if host || port

      if host&.start_with? '.', '/', '@'
        config.bind "unix://#{host}"
      elsif host&.start_with? 'ssl://'
        uri = URI.parse(host)
        uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
        config.bind uri.to_s
      else

        if host
          port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
        end

        if port
          host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
          config.port port, host
        end
      end
    end
  end
end

# rackup was removed in Rack 3, it is now a separate gem
if Object.const_defined?(:Rackup) && ::Rackup.const_defined?(:Handler)
  module Rackup
    module Handler
      module Puma
        class << self
          include ::Puma::RackHandler
        end
      end
      register :puma, Puma
    end
  end
else
  do_register = Object.const_defined?(:Rack) && ::Rack.release < '3'
  module Rack
    module Handler
      module Puma
        class << self
          include ::Puma::RackHandler
        end
      end
    end
  end
  ::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
end