ferrum 0.12 → 0.13

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ferrum/proxy.rb CHANGED
@@ -18,7 +18,6 @@ module Ferrum
18
18
  @port = port
19
19
  @user = user
20
20
  @password = password
21
- at_exit { stop }
22
21
  end
23
22
 
24
23
  def start
@@ -39,8 +38,10 @@ module Ferrum
39
38
  options.merge!(ProxyAuthProc: authenticator.method(:authenticate).to_proc)
40
39
  end
41
40
 
42
- @server = WEBrick::HTTPProxyServer.new(**options)
41
+ @server = HTTPProxyServer.new(**options)
43
42
  @server.start
43
+ at_exit { stop }
44
+
44
45
  @port = @server.config[:Port]
45
46
  end
46
47
 
@@ -54,5 +55,93 @@ module Ferrum
54
55
  @file&.unlink
55
56
  @server.shutdown
56
57
  end
58
+
59
+ # Fix hanging proxy at exit
60
+ class HTTPProxyServer < WEBrick::HTTPProxyServer
61
+ # rubocop:disable all
62
+ def do_CONNECT(req, res)
63
+ # Proxy Authentication
64
+ proxy_auth(req, res)
65
+
66
+ ua = Thread.current[:WEBrickSocket] # User-Agent
67
+ raise WEBrick::HTTPStatus::InternalServerError,
68
+ "[BUG] cannot get socket" unless ua
69
+
70
+ host, port = req.unparsed_uri.split(":", 2)
71
+ # Proxy authentication for upstream proxy server
72
+ if proxy = proxy_uri(req, res)
73
+ proxy_request_line = "CONNECT #{host}:#{port} HTTP/1.0"
74
+ if proxy.userinfo
75
+ credentials = "Basic " + [proxy.userinfo].pack("m0")
76
+ end
77
+ host, port = proxy.host, proxy.port
78
+ end
79
+
80
+ begin
81
+ @logger.debug("CONNECT: upstream proxy is `#{host}:#{port}'.")
82
+ os = TCPSocket.new(host, port) # origin server
83
+
84
+ if proxy
85
+ @logger.debug("CONNECT: sending a Request-Line")
86
+ os << proxy_request_line << CRLF
87
+ @logger.debug("CONNECT: > #{proxy_request_line}")
88
+ if credentials
89
+ @logger.debug("CONNECT: sending credentials")
90
+ os << "Proxy-Authorization: " << credentials << CRLF
91
+ end
92
+ os << CRLF
93
+ proxy_status_line = os.gets(LF)
94
+ @logger.debug("CONNECT: read Status-Line from the upstream server")
95
+ @logger.debug("CONNECT: < #{proxy_status_line}")
96
+ if %r{^HTTP/\d+\.\d+\s+200\s*} =~ proxy_status_line
97
+ while line = os.gets(LF)
98
+ break if /\A(#{CRLF}|#{LF})\z/om =~ line
99
+ end
100
+ else
101
+ raise WEBrick::HTTPStatus::BadGateway
102
+ end
103
+ end
104
+ @logger.debug("CONNECT #{host}:#{port}: succeeded")
105
+ res.status = WEBrick::HTTPStatus::RC_OK
106
+ rescue => ex
107
+ @logger.debug("CONNECT #{host}:#{port}: failed `#{ex.message}'")
108
+ res.set_error(ex)
109
+ raise WEBrick::HTTPStatus::EOFError
110
+ ensure
111
+ # At exit os variable sometimes can be nil which results in hanging forever
112
+ raise WEBrick::HTTPStatus::EOFError unless os
113
+
114
+ if handler = @config[:ProxyContentHandler]
115
+ handler.call(req, res)
116
+ end
117
+ res.send_response(ua)
118
+ access_log(@config, req, res)
119
+
120
+ # Should clear request-line not to send the response twice.
121
+ # see: HTTPServer#run
122
+ req.parse(NullReader) rescue nil
123
+ end
124
+
125
+ begin
126
+ while fds = IO::select([ua, os])
127
+ if fds[0].member?(ua)
128
+ buf = ua.readpartial(1024);
129
+ @logger.debug("CONNECT: #{buf.bytesize} byte from User-Agent")
130
+ os.write(buf)
131
+ elsif fds[0].member?(os)
132
+ buf = os.readpartial(1024);
133
+ @logger.debug("CONNECT: #{buf.bytesize} byte from #{host}:#{port}")
134
+ ua.write(buf)
135
+ end
136
+ end
137
+ rescue
138
+ os.close
139
+ @logger.debug("CONNECT #{host}:#{port}: closed")
140
+ end
141
+
142
+ raise WEBrick::HTTPStatus::EOFError
143
+ end
144
+ # rubocop:enable all
145
+ end
57
146
  end
58
147
  end
data/lib/ferrum/target.rb CHANGED
@@ -23,10 +23,12 @@ module Ferrum
23
23
  end
24
24
 
25
25
  def page
26
- @page ||= begin
27
- maybe_sleep_if_new_window
28
- Page.new(id, @browser)
29
- end
26
+ @page ||= build_page
27
+ end
28
+
29
+ def build_page(**options)
30
+ maybe_sleep_if_new_window
31
+ Page.new(id, @browser, **options)
30
32
  end
31
33
 
32
34
  def id
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ferrum
4
- VERSION = "0.12"
4
+ VERSION = "0.13"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ferrum
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.12'
4
+ version: '0.13'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Vorotilin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-13 00:00:00.000000000 Z
11
+ date: 2022-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -184,16 +184,19 @@ files:
184
184
  - lib/ferrum/browser/binary.rb
185
185
  - lib/ferrum/browser/client.rb
186
186
  - lib/ferrum/browser/command.rb
187
+ - lib/ferrum/browser/options.rb
187
188
  - lib/ferrum/browser/options/base.rb
188
189
  - lib/ferrum/browser/options/chrome.rb
189
190
  - lib/ferrum/browser/options/firefox.rb
190
191
  - lib/ferrum/browser/process.rb
191
192
  - lib/ferrum/browser/subscriber.rb
193
+ - lib/ferrum/browser/version_info.rb
192
194
  - lib/ferrum/browser/web_socket.rb
193
195
  - lib/ferrum/browser/xvfb.rb
194
196
  - lib/ferrum/context.rb
195
197
  - lib/ferrum/contexts.rb
196
198
  - lib/ferrum/cookies.rb
199
+ - lib/ferrum/cookies/cookie.rb
197
200
  - lib/ferrum/dialog.rb
198
201
  - lib/ferrum/errors.rb
199
202
  - lib/ferrum/frame.rb