Skip to content

Commit e1efe3e

Browse files
authored
fix: #216 Configure with ws/wss url (#435)
1 parent 3c95a10 commit e1efe3e

File tree

8 files changed

+75
-27
lines changed

8 files changed

+75
-27
lines changed

lib/ferrum/browser.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,6 @@ def start
245245

246246
begin
247247
@process.start
248-
@options.ws_url = @process.ws_url&.merge(path: "/")
249248
@options.default_user_agent = @process.default_user_agent
250249

251250
@client = Client.new(@process.ws_url, options)

lib/ferrum/browser/options.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ class Options
1313

1414
attr_reader :window_size, :logger, :ws_max_receive_size,
1515
:js_errors, :base_url, :slowmo, :pending_connection_errors,
16-
:url, :env, :process_timeout, :browser_name, :browser_path,
16+
:url, :ws_url, :env, :process_timeout, :browser_name, :browser_path,
1717
:save_path, :proxy, :port, :host, :headless, :browser_options,
1818
:ignore_default_browser_options, :xvfb, :flatten
19-
attr_accessor :timeout, :ws_url, :default_user_agent
19+
attr_accessor :timeout, :default_user_agent
2020

2121
def initialize(options = nil)
2222
@options = Hash(options&.dup)
@@ -44,6 +44,7 @@ def initialize(options = nil)
4444
@logger = parse_logger(@options[:logger])
4545
@base_url = parse_base_url(@options[:base_url]) if @options[:base_url]
4646
@url = @options[:url].to_s if @options[:url]
47+
@ws_url = @options[:ws_url].to_s if @options[:ws_url]
4748

4849
@options = @options.merge(window_size: @window_size).freeze
4950
@browser_options = @options.fetch(:browser_options, {}).freeze

lib/ferrum/browser/process.rb

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,15 @@ def self.directory_remover(path)
6262
def initialize(options)
6363
@pid = @xvfb = @user_data_dir = nil
6464

65+
if options.ws_url
66+
response = parse_json_version(options.ws_url)
67+
self.ws_url = response&.[]("webSocketDebuggerUrl") || options.ws_url
68+
return
69+
end
70+
6571
if options.url
66-
url = URI.join(options.url, "/json/version")
67-
response = JSON.parse(::Net::HTTP.get(url))
68-
self.ws_url = response["webSocketDebuggerUrl"]
69-
parse_browser_versions
72+
response = parse_json_version(options.url)
73+
self.ws_url = response&.[]("webSocketDebuggerUrl")
7074
return
7175
end
7276

@@ -100,7 +104,7 @@ def start
100104
ObjectSpace.define_finalizer(self, self.class.process_killer(@pid))
101105

102106
parse_ws_url(read_io, @process_timeout)
103-
parse_browser_versions
107+
parse_json_version(ws_url)
104108
ensure
105109
close_io(read_io, write_io)
106110
end
@@ -174,25 +178,37 @@ def ws_url=(url)
174178
@port = @ws_url.port
175179
end
176180

177-
def parse_browser_versions
178-
return unless ws_url.is_a?(Addressable::URI)
181+
def close_io(*ios)
182+
ios.each do |io|
183+
io.close unless io.closed?
184+
rescue IOError
185+
raise unless RUBY_ENGINE == "jruby"
186+
end
187+
end
188+
189+
def parse_json_version(url)
190+
url = URI.join(url, "/json/version")
191+
192+
if %w[wss ws].include?(url.scheme)
193+
url.scheme = case url.scheme
194+
when "ws"
195+
"http"
196+
when "wss"
197+
"https"
198+
end
199+
end
179200

180-
version_url = URI.parse(ws_url.merge(scheme: "http", path: "/json/version"))
181-
response = JSON.parse(::Net::HTTP.get(version_url))
201+
response = JSON.parse(::Net::HTTP.get(URI(url.to_s)))
182202

183203
@v8_version = response["V8-Version"]
184204
@browser_version = response["Browser"]
185205
@webkit_version = response["WebKit-Version"]
186206
@default_user_agent = response["User-Agent"]
187207
@protocol_version = response["Protocol-Version"]
188-
end
189208

190-
def close_io(*ios)
191-
ios.each do |io|
192-
io.close unless io.closed?
193-
rescue IOError
194-
raise unless RUBY_ENGINE == "jruby"
195-
end
209+
response
210+
rescue StandardError
211+
# nop
196212
end
197213
end
198214
end

lib/ferrum/client.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ class Client
5757
extend Forwardable
5858
delegate %i[timeout timeout=] => :options
5959

60-
attr_reader :options, :subscriber
60+
attr_reader :ws_url, :options, :subscriber
6161

6262
def initialize(ws_url, options)
6363
@command_id = 0
64+
@ws_url = ws_url
6465
@options = options
6566
@pendings = Concurrent::Hash.new
6667
@ws = WebSocket.new(ws_url, options.ws_max_receive_size, options.logger)

lib/ferrum/client/web_socket.rb

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,27 @@ module Ferrum
88
class Client
99
class WebSocket
1010
WEBSOCKET_BUG_SLEEP = 0.05
11+
DEFAULT_PORTS = { "ws" => 80, "wss" => 443 }.freeze
1112
SKIP_LOGGING_SCREENSHOTS = !ENV["FERRUM_LOGGING_SCREENSHOTS"]
1213

1314
attr_reader :url, :messages
1415

1516
def initialize(url, max_receive_size, logger)
16-
@url = url
17-
@logger = logger
18-
uri = URI.parse(@url)
19-
@sock = TCPSocket.new(uri.host, uri.port)
17+
@url = url
18+
@logger = logger
19+
uri = URI.parse(@url)
20+
port = uri.port || DEFAULT_PORTS[uri.scheme]
21+
22+
if port == 443
23+
tcp = TCPSocket.new(uri.host, port)
24+
ssl_context = OpenSSL::SSL::SSLContext.new
25+
@sock = OpenSSL::SSL::SSLSocket.new(tcp, ssl_context)
26+
@sock.sync_close = true
27+
@sock.connect
28+
else
29+
@sock = TCPSocket.new(uri.host, port)
30+
end
31+
2032
max_receive_size ||= ::WebSocket::Driver::MAX_LENGTH
2133
@driver = ::WebSocket::Driver.client(self, max_length: max_receive_size)
2234
@messages = Queue.new

lib/ferrum/target.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def build_client
8181
end
8282

8383
def ws_url
84-
options.ws_url.merge(path: "/devtools/page/#{id}").to_s
84+
@browser_client.ws_url.merge(path: "/devtools/page/#{id}")
8585
end
8686
end
8787
end

spec/browser_spec.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,29 @@
119119
end
120120

121121
it "supports :url argument" do
122-
with_external_browser do |url|
122+
with_external_browser do |url, process|
123123
browser = Ferrum::Browser.new(url: url)
124124
browser.go_to(base_url)
125125
expect(browser.body).to include("Hello world!")
126+
expect(process.v8_version).not_to be_nil
127+
expect(process.browser_version).not_to be_nil
128+
expect(process.webkit_version).not_to be_nil
129+
expect(process.default_user_agent).not_to be_nil
130+
expect(process.protocol_version).not_to be_nil
131+
ensure
132+
browser&.quit
133+
end
134+
end
135+
136+
it "supports :ws_url argument" do
137+
with_external_browser do |url, process|
138+
uri = Addressable::URI.parse(url)
139+
browser = Ferrum::Browser.new(ws_url: "ws://#{uri.host}:#{uri.port}")
140+
expect(process.v8_version).not_to be_nil
141+
expect(process.browser_version).not_to be_nil
142+
expect(process.webkit_version).not_to be_nil
143+
expect(process.default_user_agent).not_to be_nil
144+
expect(process.protocol_version).not_to be_nil
126145
ensure
127146
browser&.quit
128147
end

spec/support/global_helpers.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def with_external_browser(host: "127.0.0.1", port: 32_001)
5353

5454
begin
5555
process.start
56-
yield "http://#{host}:#{port}"
56+
yield "http://#{host}:#{port}", process
5757
ensure
5858
process.stop
5959
end

0 commit comments

Comments
 (0)