1 # -*- encoding: binary -*-
9 warn 'rack not available, functionality reduced'
13 # Unicorn module containing all of the classes (include C extensions) for
14 # running a Unicorn web server. It contains a minimalist HTTP server with just
15 # enough functionality to service web application requests fast as possible.
18 # unicorn exposes very little of an user-visible API and most of its
19 # internals are subject to change. unicorn is designed to host Rack
20 # applications, so applications should be written against the Rack SPEC
21 # and not unicorn internals.
24 # Raised inside TeeInput when a client closes the socket inside the
25 # application dispatch. This is always raised with an empty backtrace
26 # since there is nothing in the application stack that is responsible
27 # for client shutdowns/disconnects. This exception is visible to Rack
28 # applications unless PrereadInput middleware is loaded. This
29 # is a subclass of the standard EOFError class and applications should
30 # not rescue it explicitly, but rescue EOFError instead.
31 ClientShutdown = Class.new(EOFError)
35 # This returns a lambda to pass in as the app, this does not "build" the
36 # app (which we defer based on the outcome of "preload_app" in the
37 # Unicorn config). The returned lambda will be called when it is
38 # time to build the app.
39 def self.builder(ru, op)
40 # allow Configurator to parse cli switches embedded in the ru file
41 op = Unicorn::Configurator::RACKUP.merge!(:file => ru, :optparse => op)
42 if ru =~ /\.ru$/ && !defined?(Rack::Builder)
43 abort "rack and Rack::Builder must be available for processing #{ru}"
46 # Op is going to get cleared before the returned lambda is called, so
47 # save this value so that it's still there when we need it:
48 no_default_middleware = op[:no_default_middleware]
50 # always called after config file parsing, may be called after forking
55 raw.sub!(/^__END__\n.*/, '')
56 eval("Rack::Builder.new {(\n#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
59 Object.const_get(File.basename(ru, '.rb').capitalize)
64 pp({ :inner_app => inner_app })
67 return inner_app if no_default_middleware
69 middleware = { # order matters
72 CommonLogger: [ $stderr ],
78 # return value, matches rackup defaults based on env
79 # Unicorn does not support persistent connections, but Rainbows!
80 # and Zbatery both do. Users accustomed to the Rack::Server default
81 # middlewares will need ContentLength/Chunked middlewares.
85 middleware.delete(:ShowExceptions)
86 middleware.delete(:Lint)
91 middleware.each do |m, args|
92 use(Rack.const_get(m), *args) if Rack.const_defined?(m)
99 # returns an array of strings representing TCP listen socket addresses
100 # and Unix domain socket paths. This is useful for use with
101 # Raindrops::Middleware under Linux: https://bogomips.org/raindrops/
102 def self.listener_names
103 Unicorn::HttpServer::LISTENERS.map do |io|
104 Unicorn::SocketHelper.sock_name(io)
105 end + Unicorn::HttpServer::NEW_LISTENERS
108 def self.log_error(logger, prefix, exc)
109 message = exc.message
110 message = message.dump if /[[:cntrl:]]/ =~ message
111 logger.error "#{prefix}: #{message} (#{exc.class})"
112 exc.backtrace.each { |line| logger.error(line) }
115 # remove this when we only support Ruby >= 2.0
116 def self.pipe # :nodoc:
117 Kgio::Pipe.new.each { |io| io.close_on_exec = true }
123 %w(const socket_helper stream_input tee_input http_request configurator
124 tmpio util http_response worker http_server).each do |s|
125 require_relative "unicorn/#{s}"