Permalink
Browse files

Expand prespawn script to handle UNIX sockets.

  • Loading branch information...
1 parent 44058fd commit 8e34d3e6c8fc1af7e13495df792b67115422adf7 @danp danp committed with FooBarWidget May 3, 2011
Showing with 112 additions and 34 deletions.
  1. +112 −30 helper-scripts/prespawn
  2. +0 −4 lib/phusion_passenger/standalone/start_command.rb
View
@@ -26,38 +26,120 @@ STDOUT.sync = true
STDERR.sync = true
require 'uri'
-url = ARGV[0]
-begin
- uri = URI.parse(url)
-rescue URI::InvaludURIError
- STDERR.puts "*** ERROR: '#{url}' is not a valid URL."
- exit 1
+require 'socket'
+
+class PrespawnLocation
+ class InvalidURLError < RuntimeError
+ def initialize(url)
+ @url = url
+ end
+
+ def to_s
+ message
+ end
+
+ def message
+ "'#{@url}' is not a valid URL."
+ end
+ end
+
+ def self.parse(url)
+ uri = uri_for(url)
+
+ location = if uri.host == 'unix'
+ UNIXPrespawnLocation.new(uri)
+ else
+ case uri.scheme
+ when 'http'
+ TCPPrespawnLocation.new(uri)
+ when 'https'
+ SSLPrespawnLocation.new(uri)
+ end
+ end
+
+ unless location
+ raise InvalidURLError, url
+ end
+
+ location
+ end
+
+ def self.uri_for(url)
+ URI.parse(url)
+ rescue URI::InvalidURIError
+ raise InvalidURLError, url
+ end
+
+ def initialize(uri)
+ @uri = uri
+ end
+
+ def request_path
+ @uri.path.empty? ? '/' : @uri.path
+ end
+
+ def request_host
+ @uri.host
+ end
+
+ def socket
+ @socket ||= connect
+ end
+
+ def head_request
+ socket.write("HEAD #{request_path} HTTP/1.1\r\n")
+ socket.write("Host: #{request_host}\r\n")
+ socket.write("Connection: close\r\n")
+ socket.write("\r\n")
+
+ socket.read
+ end
end
-if uri.scheme.nil? || uri.host.nil? || uri.port.nil? || uri.path.nil?
- STDERR.puts "*** ERROR: '#{url}' is not a valid URL."
- exit 1
+
+class TCPPrespawnLocation < PrespawnLocation
+ def request_port
+ @uri.port
+ end
+
+ def connect
+ TCPSocket.new(request_host, request_port)
+ end
end
-require 'socket'
-path = uri.path.empty? ? "/" : uri.path
-socket = TCPSocket.new('127.0.0.1', uri.port)
-if uri.scheme == 'https'
- require 'openssl'
- socket = OpenSSL::SSL::SSLSocket.new(socket)
- socket.sync_close = true
- socket.connect
+class SSLPrespawnLocation < TCPPrespawnLocation
+ def connect
+ require 'openssl'
+ socket = OpenSSL::SSL::SSLSocket.new(super)
+ socket.sync_close = true
+ socket.connect
+ socket
+ end
end
-begin
- socket.write("HEAD #{path} HTTP/1.1\r\n")
- socket.write("Host: #{uri.host}\r\n")
- socket.write("Connection: close\r\n")
- socket.write("\r\n")
- if socket.respond_to?(:close_write)
- socket.close_write
- socket.read
- else
- socket.readline
+
+class UNIXPrespawnLocation < PrespawnLocation
+ def request_path
+ super.split(':', 2).last
end
-ensure
- socket.close
-end
+
+ def request_host
+ '_'
+ end
+
+ def socket_path
+ @uri.path.split(':', 2).first
+ end
+
+ def connect
+ UNIXSocket.new(socket_path)
+ end
+end
+
+url = ARGV[0]
+begin
+ prespawn_location = PrespawnLocation.parse(url)
+rescue PrespawnLocation::InvalidURLError => e
+ STDERR.puts "*** ERROR: #{e}"
+ exit 1
+end
+
+prespawn_location.head_request
@@ -267,10 +267,6 @@ def should_watch_logs?
return !@options[:daemonize] && @options[:log_file] != "/dev/null"
end
- def listening_on_unix_domain_socket?
- return !!@options[:socket_file]
- end
-
# Returns the URL that Nginx will be listening on.
def listen_url
if @options[:socket_file]

0 comments on commit 8e34d3e

Please sign in to comment.