1 # -*- encoding: binary -*-
11 warn 'rack not available, functionality reduced'
15 # Unicorn module containing all of the classes (include C extensions) for
16 # running a Unicorn web server. It contains a minimalist HTTP server with just
17 # enough functionality to service web application requests fast as possible.
20 # unicorn exposes very little of an user-visible API and most of its
21 # internals are subject to change. unicorn is designed to host Rack
22 # applications, so applications should be written against the Rack SPEC
23 # and not unicorn internals.
26 # Raised inside TeeInput when a client closes the socket inside the
27 # application dispatch. This is always raised with an empty backtrace
28 # since there is nothing in the application stack that is responsible
29 # for client shutdowns/disconnects. This exception is visible to Rack
30 # applications unless PrereadInput middleware is loaded. This
31 # is a subclass of the standard EOFError class and applications should
32 # not rescue it explicitly, but rescue EOFError instead.
33 ClientShutdown = Class.new(EOFError)
37 # This returns a lambda to pass in as the app, this does not "build" the
38 # app (which we defer based on the outcome of "preload_app" in the
39 # Unicorn config). The returned lambda will be called when it is
40 # time to build the app.
41 def self.builder(ru, op)
42 # allow Configurator to parse cli switches embedded in the ru file
43 op = Unicorn::Configurator::RACKUP.merge!(:file => ru, :optparse => op)
44 if ru =~ /\.ru$/ && !defined?(Rack::Builder)
45 abort "rack and Rack::Builder must be available for processing #{ru}"
48 # always called after config file parsing, may be called after forking
53 raw.sub!(/^__END__\n.*/, '')
54 eval("Rack::Builder.new {(\n#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
57 Object.const_get(File.basename(ru, '.rb').capitalize)
62 pp({ :inner_app => inner_app })
65 return inner_app unless server.default_middleware
67 middleware = { # order matters
69 CommonLogger: [ $stderr ],
75 # return value, matches rackup defaults based on env
76 # Unicorn does not support persistent connections, but Rainbows!
77 # does. Users accustomed to the Rack::Server default
78 # middlewares will need ContentLength middleware.
82 middleware.delete(:ShowExceptions)
83 middleware.delete(:Lint)
88 middleware.each do |m, args|
89 use(Rack.const_get(m), *args) if Rack.const_defined?(m)
96 # returns an array of strings representing TCP listen socket addresses
97 # and Unix domain socket paths. This is useful for use with
98 # Raindrops::Middleware under Linux: https://yhbt.net/raindrops/
99 def self.listener_names
100 Unicorn::HttpServer::LISTENERS.map do |io|
101 Unicorn::SocketHelper.sock_name(io)
102 end + Unicorn::HttpServer::NEW_LISTENERS
105 def self.log_error(logger, prefix, exc)
106 message = exc.message
107 message = message.dump if /[[:cntrl:]]/ =~ message
108 logger.error "#{prefix}: #{message} (#{exc.class})"
109 exc.backtrace.each { |line| logger.error(line) }
112 F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
114 def self.pipe # :nodoc:
115 Kgio::Pipe.new.each do |io|
116 # shrink pipes to minimize impact on /proc/sys/fs/pipe-user-pages-soft
118 if defined?(F_SETPIPE_SZ)
120 io.fcntl(F_SETPIPE_SZ, Raindrops::PAGE_SIZE)
124 # resizes fail if Linux is close to the pipe limit for the user
125 # or if the user does not have permissions to resize
134 %w(const socket_helper stream_input tee_input http_request configurator
135 tmpio util http_response worker http_server).each do |s|
136 require_relative "unicorn/#{s}"