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
70 CommonLogger: [ $stderr ],
76 # return value, matches rackup defaults based on env
77 # Unicorn does not support persistent connections, but Rainbows!
78 # and Zbatery both do. Users accustomed to the Rack::Server default
79 # middlewares will need ContentLength/Chunked middlewares.
83 middleware.delete(:ShowExceptions)
84 middleware.delete(:Lint)
89 middleware.each do |m, args|
90 use(Rack.const_get(m), *args) if Rack.const_defined?(m)
97 # returns an array of strings representing TCP listen socket addresses
98 # and Unix domain socket paths. This is useful for use with
99 # Raindrops::Middleware under Linux: https://yhbt.net/raindrops/
100 def self.listener_names
101 Unicorn::HttpServer::LISTENERS.map do |io|
102 Unicorn::SocketHelper.sock_name(io)
103 end + Unicorn::HttpServer::NEW_LISTENERS
106 def self.log_error(logger, prefix, exc)
107 message = exc.message
108 message = message.dump if /[[:cntrl:]]/ =~ message
109 logger.error "#{prefix}: #{message} (#{exc.class})"
110 exc.backtrace.each { |line| logger.error(line) }
113 F_SETPIPE_SZ = 1031 if RUBY_PLATFORM =~ /linux/
115 def self.pipe # :nodoc:
116 Kgio::Pipe.new.each do |io|
117 io.close_on_exec = true # remove this when we only support Ruby >= 2.0
119 # shrink pipes to minimize impact on /proc/sys/fs/pipe-user-pages-soft
121 if defined?(F_SETPIPE_SZ)
123 io.fcntl(F_SETPIPE_SZ, Raindrops::PAGE_SIZE)
127 # resizes fail if Linux is close to the pipe limit for the user
128 # or if the user does not have permissions to resize
137 %w(const socket_helper stream_input tee_input http_request configurator
138 tmpio util http_response worker http_server).each do |s|
139 require_relative "unicorn/#{s}"