class Roger::Server

The Roger webserver. Initializes a rack server.

@option options :port [Integer] The specified port you'd want to use @option options :auto_port [Boolean] Wether or not you want Roger

to find a suitable port if the specified port is in use.

@option options :handler [String] The preferred handler to use

Attributes

project[RW]
application_options[RW]

@attr_accessor [Hash] Options pass to ::Roger::Rack::Roger initialization

@see ::Roger::Rack:Roger

auto_port[RW]
handler[RW]
host[RW]
port[RW]
project[R]

@attr_reader [Roger::Project] project The project used in this server

server_options[R]
used_handler[R]

@attr_reader [nil, Class] used_handler The actual used handler.

Only set if the server is running.
used_port[R]

@attr_reader [nil, Integer] used_port The actual port used to start

the webserver. Only set if the server is running.

Public Class Methods

new(project, options = {}) click to toggle source
# File lib/roger/server.rb, line 36
def initialize(project, options = {})
  @project = project

  @stack = initialize_rack_builder

  @server_options = {}

  # Defaults
  self.port = 9000
  self.handler = nil
  self.host = "0.0.0.0"
  self.auto_port = true

  @used_port = nil
  @used_handler = nil

  set_options(options)
end

Public Instance Methods

handler=(h) click to toggle source
# File lib/roger/server.rb, line 120
def handler=(h)
  @handler = if h.respond_to?(:run)
               h
             else
               get_handler(h)
             end
end
host=(h) click to toggle source
# File lib/roger/server.rb, line 116
def host=(h)
  @host = server_options[:Host] = h
end
map(*args, &block) click to toggle source

Use the map handler to map endpoints to certain urls

@see ::Rack::Builder#map

# File lib/roger/server.rb, line 74
def map(*args, &block)
  @stack.map(*args, &block)
end
port=(p) click to toggle source
# File lib/roger/server.rb, line 112
def port=(p)
  @port = server_options[:Port] = p
end
run()
Alias for: run!
run!() { |server| ... } click to toggle source
# File lib/roger/server.rb, line 78
def run!
  project.mode = :server

  options = server_options_for_handler
  @used_port = options[:Port]
  @used_handler = handler

  handler.run application, options do |server|
    trap(:INT) do
      ## Use thins' hard #stop! if available, otherwise just #stop
      server.respond_to?(:stop!) ? server.stop! : server.stop
      puts "Roger, out!"
    end

    yield server if block_given?
  end
ensure
  project.mode = nil
  @used_port = nil
  @used_handler = nil
end
Also aliased as: run
server_options_for_handler() click to toggle source
# File lib/roger/server.rb, line 101
def server_options_for_handler
  # Search for available port
  options = server_options.dup
  if auto_port && !port_free?(options[:Host], options[:Port])
    options[:Port] = free_port_for_host_above(options[:Host], options[:Port])
  end

  # Return the options
  options
end
set_options(options) click to toggle source

Sets the options, this is a separate method as we want to override certain things set in the rogerfile from the commandline

# File lib/roger/server.rb, line 57
def set_options(options)
  self.port = options[:port].to_i if options.key?(:port)
  self.handler = options[:handler] if options.key?(:handler)
  self.host = options[:host] if options.key?(:host)
  self.auto_port = options[:auto_port] if options.key?(:auto_port)
end
use(*args, &block) click to toggle source

Use the specified Rack middleware

@see ::Rack::Builder#use

# File lib/roger/server.rb, line 67
def use(*args, &block)
  @stack.use(*args, &block)
end

Protected Instance Methods

application() click to toggle source

Build the final application that get's run by the Rack Handler

# File lib/roger/server.rb, line 148
def application
  return @app if @app

  @stack.run Rack::Roger.new(project, @application_options || {})

  @app = @stack
end
call(env) click to toggle source
# File lib/roger/server.rb, line 169
def call(env)
  env["roger.project"] = self.class.project
  @app.call(env)
end
detect_valid_handler(servers) click to toggle source

See what handlers work

# File lib/roger/server.rb, line 202
def detect_valid_handler(servers)
  handler = nil
  while (server_name = servers.shift) && handler.nil?
    begin
      handler = ::Rack::Handler.get(server_name)
      return [handler, server_name]
    rescue LoadError
      handler = nil
    rescue NameError
      handler = nil
    end
  end
end
free_port_for_host_above(host, port) click to toggle source

Get the first free port for host above port Will only ever test 100 ports.

# File lib/roger/server.rb, line 132
def free_port_for_host_above(host, port)
  test_port = port
  test_port += 1 until port_free?(host, test_port) || port + 100 <= test_port
  test_port
end
get_handler(preferred_handler_name = nil) click to toggle source

Get the actual handler for use in the server Will always return a handler, it will try to use the fallbacks

# File lib/roger/server.rb, line 189
def get_handler(preferred_handler_name = nil)
  servers = %w(puma mongrel thin webrick)
  servers.unshift(preferred_handler_name) if preferred_handler_name

  handler, server_name = detect_valid_handler(servers)

  if preferred_handler_name && server_name != preferred_handler_name
    puts "Handler '#{preferred_handler_name}' not found, using fallback ('#{handler.inspect}')."
  end
  handler
end
initialize_rack_builder() click to toggle source

Initialize the Rack builder instance for this server

@return ::Rack::Builder instance

# File lib/roger/server.rb, line 159
def initialize_rack_builder
  roger_env = Class.new do
    class << self
      attr_accessor :project
    end

    def initialize(app)
      @app = app
    end

    def call(env)
      env["roger.project"] = self.class.project
      @app.call(env)
    end
  end

  roger_env.project = project

  builder = ::Rack::Builder.new
  builder.use roger_env
  builder.use ::Rack::ShowExceptions
  builder.use ::Rack::Lint
  builder.use ::Rack::ConditionalGet
  builder.use ::Rack::Head

  builder
end
port_free?(host, port) click to toggle source

See if a certain port is free on a certain host

# File lib/roger/server.rb, line 139
def port_free?(host, port)
  Addrinfo.tcp(host, port).listen.close

  true
rescue SocketError, Errno::EADDRINUSE, Errno::EACCES
  false
end