about summary refs log tree commit homepage
path: root/lib/unicorn.rb
blob: 8a5fdcc5dd6ae5da3e18f581ec529c44d70b24d7 (plain)
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
# -*- encoding: binary -*-
require 'fcntl'
require 'etc'
require 'stringio'
require 'rack'
require 'kgio'

# :stopdoc:
# Unicorn module containing all of the classes (include C extensions) for
# running a Unicorn web server.  It contains a minimalist HTTP server with just
# enough functionality to service web application requests fast as possible.
# :startdoc:

# \Unicorn exposes very little of an user-visible API and most of its
# internals are subject to change.  \Unicorn is designed to host Rack
# applications, so applications should be written against the Rack SPEC
# and not \Unicorn internals.
module Unicorn

  # Raised inside TeeInput when a client closes the socket inside the
  # application dispatch.  This is always raised with an empty backtrace
  # since there is nothing in the application stack that is responsible
  # for client shutdowns/disconnects.  This exception is visible to Rack
  # applications unless PrereadInput middleware is loaded.
  class ClientShutdown < EOFError
  end

  # :stopdoc:
  def self.run(app, options = {})
    Unicorn::HttpServer.new(app, options).start.join
  end

  # This returns a lambda to pass in as the app, this does not "build" the
  # app (which we defer based on the outcome of "preload_app" in the
  # Unicorn config).  The returned lambda will be called when it is
  # time to build the app.
  def self.builder(ru, opts)
    # allow Configurator to parse cli switches embedded in the ru file
    Unicorn::Configurator::RACKUP.update(:file => ru, :optparse => opts)

    # always called after config file parsing, may be called after forking
    lambda do ||
      inner_app = case ru
      when /\.ru$/
        raw = File.read(ru)
        raw.sub!(/^__END__\n.*/, '')
        eval("Rack::Builder.new {(#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
      else
        require ru
        Object.const_get(File.basename(ru, '.rb').capitalize)
      end

      pp({ :inner_app => inner_app }) if $DEBUG

      # return value, matches rackup defaults based on env
      case ENV["RACK_ENV"]
      when "development"
        Rack::Builder.new do
          use Rack::CommonLogger, $stderr
          use Rack::ShowExceptions
          use Rack::Lint
          run inner_app
        end.to_app
      when "deployment"
        Rack::Builder.new do
          use Rack::CommonLogger, $stderr
          run inner_app
        end.to_app
      else
        inner_app
      end
    end
  end

  # returns an array of strings representing TCP listen socket addresses
  # and Unix domain socket paths.  This is useful for use with
  # Raindrops::Middleware under Linux: http://raindrops.bogomips.org/
  def self.listener_names
    Unicorn::HttpServer::LISTENERS.map do |io|
      Unicorn::SocketHelper.sock_name(io)
    end
  end
  # :startdoc:
end
# :enddoc:
require 'unicorn/const'
require 'unicorn/socket_helper'
require 'unicorn/stream_input'
require 'unicorn/tee_input'
require 'unicorn/http_request'
require 'unicorn/configurator'
require 'unicorn/tmpio'
require 'unicorn/util'
require 'unicorn/http_response'
require 'unicorn/worker'
require 'unicorn/http_server'