diff options
Diffstat (limited to 'lib/unicorn/socket_helper.rb')
-rw-r--r-- | lib/unicorn/socket_helper.rb | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/lib/unicorn/socket_helper.rb b/lib/unicorn/socket_helper.rb index f8e3725..09085e5 100644 --- a/lib/unicorn/socket_helper.rb +++ b/lib/unicorn/socket_helper.rb @@ -1,3 +1,5 @@ +# -*- encoding: binary -*- + require 'socket' module Unicorn @@ -9,19 +11,24 @@ module Unicorn when /linux/ # from /usr/include/linux/tcp.h TCP_DEFER_ACCEPT = 9 unless defined?(TCP_DEFER_ACCEPT) + + # do not send out partial frames (Linux) TCP_CORK = 3 unless defined?(TCP_CORK) when /freebsd(([1-4]\..{1,2})|5\.[0-4])/ # Do nothing for httpready, just closing a bug when freebsd <= 5.4 - TCP_NOPUSH = 4 unless defined?(TCP_NOPUSH) + TCP_NOPUSH = 4 unless defined?(TCP_NOPUSH) # :nodoc: when /freebsd/ + # do not send out partial frames (FreeBSD) TCP_NOPUSH = 4 unless defined?(TCP_NOPUSH) + # Use the HTTP accept filter if available. # The struct made by pack() is defined in /usr/include/sys/socket.h # as accept_filter_arg - # We won't be seupportin the "dataready" filter unlike nginx - # since we only support HTTP and no other protocols unless `/sbin/sysctl -nq net.inet.accf.http`.empty? - HTTPREADY = ['httpready', nil].pack('a16a240').freeze + # set set the "httpready" accept filter in FreeBSD if available + # if other protocols are to be supported, this may be + # String#replace-d with "dataready" arguments instead + FILTER_ARG = ['httpready', nil].pack('a16a240') end end @@ -29,23 +36,23 @@ module Unicorn # highly portable, but off by default because we don't do keepalive if defined?(TCP_NODELAY) && ! (val = opt[:tcp_nodelay]).nil? - sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, val ? 1 : 0) rescue nil + sock.setsockopt(IPPROTO_TCP, TCP_NODELAY, val ? 1 : 0) end unless (val = opt[:tcp_nopush]).nil? val = val ? 1 : 0 if defined?(TCP_CORK) # Linux - sock.setsockopt(IPPROTO_TCP, TCP_CORK, val) rescue nil + sock.setsockopt(IPPROTO_TCP, TCP_CORK, val) elsif defined?(TCP_NOPUSH) # TCP_NOPUSH is untested (FreeBSD) - sock.setsockopt(IPPROTO_TCP, TCP_NOPUSH, val) rescue nil + sock.setsockopt(IPPROTO_TCP, TCP_NOPUSH, val) end end # No good reason to ever have deferred accepts off if defined?(TCP_DEFER_ACCEPT) - sock.setsockopt(SOL_TCP, TCP_DEFER_ACCEPT, 1) rescue nil - elsif defined?(SO_ACCEPTFILTER) && defined?(HTTPREADY) - sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, HTTPREADY) rescue nil + sock.setsockopt(SOL_TCP, TCP_DEFER_ACCEPT, 1) + elsif defined?(SO_ACCEPTFILTER) && defined?(FILTER_ARG) + sock.setsockopt(SOL_SOCKET, SO_ACCEPTFILTER, FILTER_ARG) end end @@ -61,6 +68,11 @@ module Unicorn log_buffer_sizes(sock, " after: ") end sock.listen(opt[:backlog] || 1024) + rescue => e + if respond_to?(:logger) + logger.error "error setting socket options: #{e.inspect}" + logger.error e.backtrace.join("\n") + end end def log_buffer_sizes(sock, pfx = '') @@ -76,7 +88,7 @@ module Unicorn def bind_listen(address = '0.0.0.0:8080', opt = {}) return address unless String === address - sock = if address[0..0] == "/" + sock = if address[0] == ?/ if File.exist?(address) if File.socket?(address) if self.respond_to?(:logger) @@ -88,7 +100,7 @@ module Unicorn "socket=#{address} specified but it is not a socket!" end end - old_umask = File.umask(0) + old_umask = File.umask(opt[:umask] || 0) begin UNIXServer.new(address) ensure |