lib/browsermob/proxy/server.rb in browsermob-proxy-0.1.8.rc1 vs lib/browsermob/proxy/server.rb in browsermob-proxy-0.1.8
- old
+ new
@@ -5,30 +5,36 @@
module Proxy
class Server
attr_reader :port
+ #
+ # Create a new server instance
+ #
+ # @param [String] path Path to the BrowserMob Proxy server executable
+ # @param [Hash] opts options to create the server with
+ # @option opts [Integer] port What port to start the server on
+ # @option opts [Boolean] log Show server output (server inherits stdout/stderr)
+ # @option opts [Integer] timeout Seconds to wait for server to launch before timing out.
+ #
+
def initialize(path, opts = {})
- unless File.exist?(path)
- raise Errno::ENOENT, path
- end
+ assert_executable path
- unless File.executable?(path)
- raise Errno::EACCES, "not executable: #{path}"
- end
+ @path = path
+ @port = Integer(opts[:port] || 8080)
+ @timeout = Integer(opts[:timeout] || 10)
+ @log = !!opts[:log]
- @path = path
- @port = Integer(opts[:port] || 8080)
-
- @process = ChildProcess.new(path, "--port", port.to_s)
- @process.io.inherit! if opts[:log]
+ @process = create_process
end
def start
@process.start
- sleep 0.1 until listening? && initialized?
+ wait_for_startup
+
pid = Process.pid
at_exit { stop if Process.pid == pid }
self
end
@@ -45,11 +51,33 @@
@process.stop if @process.alive?
end
private
+ def create_process
+ process = ChildProcess.new(@path, "--port", @port.to_s)
+ process.leader = true
+ process.io.inherit! if @log
+
+ process
+ end
+
+ def wait_for_startup
+ end_time = Time.now + @timeout
+
+ sleep 0.1 until (listening? && initialized?) || Time.now > end_time || !@process.alive?
+
+ if Time.now > end_time
+ raise TimeoutError, "timed out waiting for the server to start (rerun with :log => true to see process output)"
+ end
+
+ unless @process.alive?
+ raise ServerDiedError, "unable to launch the server (rerun with :log => true to see process output)"
+ end
+ end
+
def listening?
TCPSocket.new("127.0.0.1", port).close
true
rescue
false
@@ -59,9 +87,25 @@
RestClient.get("#{url}/proxy")
true
rescue RestClient::Exception
false
end
- end # Server
+ def assert_executable(path)
+ unless File.exist?(path)
+ raise Errno::ENOENT, path
+ end
+
+ unless File.executable?(path)
+ raise Errno::EACCES, "not executable: #{path}"
+ end
+ end
+
+ class TimeoutError < StandardError
+ end
+
+ class ServerDiedError < StandardError
+ end
+
+ end # Server
end # Proxy
end # BrowserMob
\ No newline at end of file