quiet some mismatched indentation warnings
[unicorn.git] / lib / unicorn.rb
blobe7bc9cecbd77e513a30d1738132cd8a358d51acd
1 # -*- encoding: binary -*-
2 require 'etc'
3 require 'stringio'
4 require 'kgio'
6 begin
7   require 'rack'
8 rescue LoadError
9   warn 'rack not available, functionality reduced'
10 end
12 # :stopdoc:
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.
16 # :startdoc:
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.
22 module Unicorn
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)
33   # :stopdoc:
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}"
44     end
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
51     lambda do ||
52       inner_app = case ru
53       when /\.ru$/
54         raw = File.read(ru)
55         raw.sub!(/^__END__\n.*/, '')
56         eval("Rack::Builder.new {(\n#{raw}\n)}.to_app", TOPLEVEL_BINDING, ru)
57       else
58         require ru
59         Object.const_get(File.basename(ru, '.rb').capitalize)
60       end
62       if $DEBUG
63         require 'pp'
64         pp({ :inner_app => inner_app })
65       end
67       return inner_app if no_default_middleware
69       middleware = { # order matters
70         ContentLength: nil,
71         Chunked: nil,
72         CommonLogger: [ $stderr ],
73         ShowExceptions: nil,
74         Lint: nil,
75         TempfileReaper: nil,
76       }
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.
82       case ENV["RACK_ENV"]
83       when "development"
84       when "deployment"
85         middleware.delete(:ShowExceptions)
86         middleware.delete(:Lint)
87       else
88         return inner_app
89       end
90       Rack::Builder.new do
91         middleware.each do |m, args|
92           use(Rack.const_get(m), *args) if Rack.const_defined?(m)
93         end
94         run inner_app
95       end.to_app
96     end
97   end
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
106   end
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) }
113   end
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 }
118   end
119   # :startdoc:
121 # :enddoc:
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}"