# class Puma::Configuration

The main configuration class of Puma.

It can be initialized with a set of “user” options and “default” options. Defaults will be merged with `Configuration.puma_default_options`.

This class works together with 2 main other classes the `UserFileDefaultOptions` which stores configuration options in order so the precedence is that user set configuration wins over “file” based configuration wins over “default” configuration. These configurations are set via the `DSL` class. This class powers the Puma config file syntax and does double duty as a configuration DSL used by the `Puma::CLI` and Puma rack handler.

It also handles loading plugins.

> Note: `:port` and `:host` are not valid keys. By they time they make it to the

    configuration options they are expected to be incorporated into a `:binds` key.
    Under the hood the DSL maps `port` and `host` calls to `:binds`

    config = Configuration.new({}) do |user_config, file_config, default_config|
      user_config.port 3003
    end
    config.load
    puts config.options[:port]
    # => 3003

It is expected that `load` is called on the configuration instance after setting config. This method expands any values in `config_file` and puts them into the correct configuration option hash.

Once all configuration is complete it is expected that `clamp` will be called on the instance. This will expand any procs stored under “default” values. This is done because an environment variable may have been modified while loading configuration files.

### Attributes

options[R]
plugins[R]

### Public Class Methods

new(user_options={}, default_options = {}, &block) click to toggle source

    # File lib/puma/configuration.rb, line 129
    def initialize(user_options={}, default_options = {}, &block)
      default_options = self.puma_default_options.merge(default_options)

      @options     = UserFileDefaultOptions.new(user_options, default_options)
      @plugins     = PluginLoader.new
      @user_dsl    = DSL.new(@options.user_options, self)
      @file_dsl    = DSL.new(@options.file_options, self)
      @default_dsl = DSL.new(@options.default_options, self)

      if block
        configure(&block)
      end
    end

temp_path() click to toggle source

    # File lib/puma/configuration.rb, line 279
    def self.temp_path
      require 'tmpdir'

      t = (Time.now.to_f * 1000).to_i
      "#{Dir.tmpdir}/puma-status-#{t}-#{$$}"
    end

### Private Class Methods

random_token() click to toggle source

    # File lib/puma/configuration.rb, line 331
    def self.random_token
      begin
        require 'openssl'
      rescue LoadError
      end

      count = 16

      bytes = nil

      if defined? OpenSSL::Random
        bytes = OpenSSL::Random.random_bytes(count)
      elsif File.exist?("/dev/urandom")
        File.open('/dev/urandom') { |f| bytes = f.read(count) }
      end

      if bytes
        token = "".dup
        bytes.each_byte { |b| token << b.to_s(16) }
      else
        token = (0..count).to_a.map { rand(255).to_s(16) }.join
      end

      return token
    end

### Public Instance Methods

app() click to toggle source

Load the specified rackup file, pull options from the rackup file, and set @app.

    # File lib/puma/configuration.rb, line 242
    def app
      found = options[:app] || load_rackup

      if @options[:mode] == :tcp
        require 'puma/tcp_logger'

        logger = @options[:logger]
        quiet = !@options[:log_requests]
        return TCPLogger.new(logger, found, quiet)
      end

      if @options[:log_requests]
        require 'puma/commonlogger'
        logger = @options[:logger]
        found = CommonLogger.new(found, logger)
      end

      ConfigMiddleware.new(self, found)
    end

app_configured?() click to toggle source

Indicate if there is a properly configured app

    # File lib/puma/configuration.rb, line 231
    def app_configured?
      @options[:app] || File.exist?(rackup)
    end

clamp() click to toggle source

Call once all configuration (included from rackup files) is loaded to flesh out any defaults

    # File lib/puma/configuration.rb, line 212
    def clamp
      @options.finalize_values
    end

config_files() click to toggle source

    # File lib/puma/configuration.rb, line 197
    def config_files
      files = @options.all_of(:config_files)

      return [] if files == ['-']
      return files if files.any?

      first_default_file = %W(config/puma/#{environment_str}.rb config/puma.rb).find do |f|
        File.exist?(f)
      end

      [first_default_file]
    end

configure() { |user_dsl, file_dsl, default_dsl| ... } click to toggle source

    # File lib/puma/configuration.rb, line 145
    def configure
      yield @user_dsl, @file_dsl, @default_dsl
    ensure
      @user_dsl._offer_plugins
      @file_dsl._offer_plugins
      @default_dsl._offer_plugins
    end

environment() click to toggle source

Return which environment we're running in

    # File lib/puma/configuration.rb, line 263
    def environment
      @options[:environment]
    end

environment_str() click to toggle source

    # File lib/puma/configuration.rb, line 267
    def environment_str
      environment.respond_to?(:call) ? environment.call : environment
    end

flatten() click to toggle source

    # File lib/puma/configuration.rb, line 159
    def flatten
      dup.flatten!
    end

flatten!() click to toggle source

    # File lib/puma/configuration.rb, line 163
    def flatten!
      @options = @options.flatten
      self
    end

initialize_copy(other) click to toggle source

    # File lib/puma/configuration.rb, line 153
    def initialize_copy(other)
      @conf        = nil
      @cli_options = nil
      @options     = @options.dup
    end

load() click to toggle source

    # File lib/puma/configuration.rb, line 191
    def load
      config_files.each { |config_file| @file_dsl._load_from(config_file) }

      @options
    end

load_plugin(name) click to toggle source

    # File lib/puma/configuration.rb, line 271
    def load_plugin(name)
      @plugins.create name
    end

puma_default_options() click to toggle source

    # File lib/puma/configuration.rb, line 168
    def puma_default_options
      {
        :min_threads => 0,
        :max_threads => 16,
        :log_requests => false,
        :debug => false,
        :binds => ["tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"],
        :workers => 0,
        :daemon => false,
        :mode => :http,
        :worker_timeout => DefaultWorkerTimeout,
        :worker_boot_timeout => DefaultWorkerTimeout,
        :worker_shutdown_timeout => DefaultWorkerShutdownTimeout,
        :remote_address => :socket,
        :tag => method(:infer_tag),
        :environment => -> { ENV['RACK_ENV'] || "development" },
        :rackup => DefaultRackup,
        :logger => STDOUT,
        :persistent_timeout => Const::PERSISTENT_TIMEOUT,
        :first_data_timeout => Const::FIRST_DATA_TIMEOUT
      }
    end

rackup() click to toggle source

    # File lib/puma/configuration.rb, line 235
    def rackup
      @options[:rackup]
    end

run_hooks(key, arg) click to toggle source

    # File lib/puma/configuration.rb, line 275
    def run_hooks(key, arg)
      @options.all_of(key).each { |b| b.call arg }
    end

### Private Instance Methods

infer_tag() click to toggle source

    # File lib/puma/configuration.rb, line 288
    def infer_tag
      File.basename(Dir.getwd)
    end

load_rackup() click to toggle source

    # File lib/puma/configuration.rb, line 315
    def load_rackup
      raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)

      rack_app, rack_options = rack_builder.parse_file(rackup)
      @options.file_options.merge!(rack_options)

      config_ru_binds = []
      rack_options.each do |k, v|
        config_ru_binds << v if k.to_s.start_with?("bind")
      end

      @options.file_options[:binds] = config_ru_binds unless config_ru_binds.empty?

      rack_app
    end

rack_builder() click to toggle source

Load and use the normal Rack builder if we can, otherwise fallback to our minimal version.

    # File lib/puma/configuration.rb, line 294
    def rack_builder
      # Load bundler now if we can so that we can pickup rack from
      # a Gemfile
      if ENV.key? 'PUMA_BUNDLER_PRUNED'
        begin
          require 'bundler/setup'
        rescue LoadError
        end
      end

      begin
        require 'rack'
        require 'rack/builder'
      rescue LoadError
        # ok, use builtin version
        return Puma::Rack::Builder
      else
        return ::Rack::Builder
      end
    end