ferrum 0.12 → 0.14

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +28 -22
  3. data/lib/ferrum/browser/client.rb +6 -5
  4. data/lib/ferrum/browser/command.rb +9 -6
  5. data/lib/ferrum/browser/options/base.rb +1 -4
  6. data/lib/ferrum/browser/options/chrome.rb +22 -10
  7. data/lib/ferrum/browser/options/firefox.rb +3 -6
  8. data/lib/ferrum/browser/options.rb +84 -0
  9. data/lib/ferrum/browser/process.rb +6 -7
  10. data/lib/ferrum/browser/version_info.rb +71 -0
  11. data/lib/ferrum/browser/web_socket.rb +1 -1
  12. data/lib/ferrum/browser/xvfb.rb +1 -1
  13. data/lib/ferrum/browser.rb +184 -64
  14. data/lib/ferrum/context.rb +3 -2
  15. data/lib/ferrum/contexts.rb +2 -2
  16. data/lib/ferrum/cookies/cookie.rb +183 -0
  17. data/lib/ferrum/cookies.rb +122 -49
  18. data/lib/ferrum/dialog.rb +30 -0
  19. data/lib/ferrum/frame/dom.rb +177 -0
  20. data/lib/ferrum/frame/runtime.rb +41 -61
  21. data/lib/ferrum/frame.rb +91 -3
  22. data/lib/ferrum/headers.rb +28 -0
  23. data/lib/ferrum/keyboard.rb +45 -2
  24. data/lib/ferrum/mouse.rb +84 -0
  25. data/lib/ferrum/network/exchange.rb +104 -5
  26. data/lib/ferrum/network/intercepted_request.rb +3 -12
  27. data/lib/ferrum/network/request.rb +58 -19
  28. data/lib/ferrum/network/request_params.rb +57 -0
  29. data/lib/ferrum/network/response.rb +106 -4
  30. data/lib/ferrum/network.rb +193 -8
  31. data/lib/ferrum/node.rb +21 -1
  32. data/lib/ferrum/page/animation.rb +16 -0
  33. data/lib/ferrum/page/frames.rb +66 -11
  34. data/lib/ferrum/page/screenshot.rb +97 -0
  35. data/lib/ferrum/page/tracing.rb +26 -0
  36. data/lib/ferrum/page.rb +158 -45
  37. data/lib/ferrum/proxy.rb +91 -2
  38. data/lib/ferrum/target.rb +6 -4
  39. data/lib/ferrum/version.rb +1 -1
  40. metadata +7 -101
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.14"
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.14'
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: 2023-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -72,104 +72,6 @@ dependencies:
72
72
  - - "<"
73
73
  - !ruby/object:Gem::Version
74
74
  version: '0.8'
75
- - !ruby/object:Gem::Dependency
76
- name: chunky_png
77
- requirement: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - "~>"
80
- - !ruby/object:Gem::Version
81
- version: '1.3'
82
- type: :development
83
- prerelease: false
84
- version_requirements: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: '1.3'
89
- - !ruby/object:Gem::Dependency
90
- name: image_size
91
- requirement: !ruby/object:Gem::Requirement
92
- requirements:
93
- - - "~>"
94
- - !ruby/object:Gem::Version
95
- version: '2.0'
96
- type: :development
97
- prerelease: false
98
- version_requirements: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: '2.0'
103
- - !ruby/object:Gem::Dependency
104
- name: pdf-reader
105
- requirement: !ruby/object:Gem::Requirement
106
- requirements:
107
- - - "~>"
108
- - !ruby/object:Gem::Version
109
- version: '2.2'
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: '2.2'
117
- - !ruby/object:Gem::Dependency
118
- name: puma
119
- requirement: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - "~>"
122
- - !ruby/object:Gem::Version
123
- version: '4.1'
124
- type: :development
125
- prerelease: false
126
- version_requirements: !ruby/object:Gem::Requirement
127
- requirements:
128
- - - "~>"
129
- - !ruby/object:Gem::Version
130
- version: '4.1'
131
- - !ruby/object:Gem::Dependency
132
- name: rake
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - "~>"
136
- - !ruby/object:Gem::Version
137
- version: '13.0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - "~>"
143
- - !ruby/object:Gem::Version
144
- version: '13.0'
145
- - !ruby/object:Gem::Dependency
146
- name: rspec
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - "~>"
150
- - !ruby/object:Gem::Version
151
- version: '3.8'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - "~>"
157
- - !ruby/object:Gem::Version
158
- version: '3.8'
159
- - !ruby/object:Gem::Dependency
160
- name: sinatra
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '2.0'
166
- type: :development
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - "~>"
171
- - !ruby/object:Gem::Version
172
- version: '2.0'
173
75
  description: Ferrum allows you to control headless Chrome browser
174
76
  email:
175
77
  - d.vorotilin@gmail.com
@@ -184,16 +86,19 @@ files:
184
86
  - lib/ferrum/browser/binary.rb
185
87
  - lib/ferrum/browser/client.rb
186
88
  - lib/ferrum/browser/command.rb
89
+ - lib/ferrum/browser/options.rb
187
90
  - lib/ferrum/browser/options/base.rb
188
91
  - lib/ferrum/browser/options/chrome.rb
189
92
  - lib/ferrum/browser/options/firefox.rb
190
93
  - lib/ferrum/browser/process.rb
191
94
  - lib/ferrum/browser/subscriber.rb
95
+ - lib/ferrum/browser/version_info.rb
192
96
  - lib/ferrum/browser/web_socket.rb
193
97
  - lib/ferrum/browser/xvfb.rb
194
98
  - lib/ferrum/context.rb
195
99
  - lib/ferrum/contexts.rb
196
100
  - lib/ferrum/cookies.rb
101
+ - lib/ferrum/cookies/cookie.rb
197
102
  - lib/ferrum/dialog.rb
198
103
  - lib/ferrum/errors.rb
199
104
  - lib/ferrum/frame.rb
@@ -209,6 +114,7 @@ files:
209
114
  - lib/ferrum/network/exchange.rb
210
115
  - lib/ferrum/network/intercepted_request.rb
211
116
  - lib/ferrum/network/request.rb
117
+ - lib/ferrum/network/request_params.rb
212
118
  - lib/ferrum/network/response.rb
213
119
  - lib/ferrum/node.rb
214
120
  - lib/ferrum/page.rb
@@ -249,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
155
  - !ruby/object:Gem::Version
250
156
  version: '0'
251
157
  requirements: []
252
- rubygems_version: 3.3.7
158
+ rubygems_version: 3.4.13
253
159
  signing_key:
254
160
  specification_version: 4
255
161
  summary: Ruby headless Chrome driver