mechanize 2.14.1 → 2.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -1
- data/lib/mechanize/directory_saver.rb +2 -1
- data/lib/mechanize/file_saver.rb +2 -0
- data/lib/mechanize/parser.rb +33 -3
- data/lib/mechanize/test_case.rb +2 -9
- data/lib/mechanize/version.rb +1 -1
- metadata +3 -172
- data/.autotest +0 -6
- data/.github/dependabot.yml +0 -11
- data/.github/workflows/ci.yml +0 -43
- data/.github/workflows/upstream.yml +0 -51
- data/.gitignore +0 -15
- data/.yardopts +0 -8
- data/Gemfile +0 -12
- data/Rakefile +0 -56
- data/examples/flickr_upload.rb +0 -22
- data/examples/latest_user_agents.rb +0 -100
- data/examples/mech-dump.rb +0 -5
- data/examples/proxy_req.rb +0 -7
- data/examples/rubygems.rb +0 -23
- data/examples/spider.rb +0 -22
- data/examples/wikipedia_links_to_philosophy.rb +0 -158
- data/mechanize.gemspec +0 -74
- data/test/data/htpasswd +0 -1
- data/test/data/server.crt +0 -16
- data/test/data/server.csr +0 -12
- data/test/data/server.key +0 -15
- data/test/data/server.pem +0 -15
- data/test/test_mechanize.rb +0 -1382
- data/test/test_mechanize_cookie.rb +0 -559
- data/test/test_mechanize_cookie_jar.rb +0 -615
- data/test/test_mechanize_directory_saver.rb +0 -60
- data/test/test_mechanize_download.rb +0 -102
- data/test/test_mechanize_element_not_found_error.rb +0 -16
- data/test/test_mechanize_file.rb +0 -118
- data/test/test_mechanize_file_connection.rb +0 -40
- data/test/test_mechanize_file_request.rb +0 -26
- data/test/test_mechanize_file_response.rb +0 -48
- data/test/test_mechanize_file_saver.rb +0 -22
- data/test/test_mechanize_form.rb +0 -1025
- data/test/test_mechanize_form_check_box.rb +0 -49
- data/test/test_mechanize_form_encoding.rb +0 -110
- data/test/test_mechanize_form_field.rb +0 -78
- data/test/test_mechanize_form_file_upload.rb +0 -21
- data/test/test_mechanize_form_image_button.rb +0 -13
- data/test/test_mechanize_form_keygen.rb +0 -34
- data/test/test_mechanize_form_multi_select_list.rb +0 -98
- data/test/test_mechanize_form_option.rb +0 -60
- data/test/test_mechanize_form_radio_button.rb +0 -96
- data/test/test_mechanize_form_select_list.rb +0 -81
- data/test/test_mechanize_form_textarea.rb +0 -53
- data/test/test_mechanize_headers.rb +0 -36
- data/test/test_mechanize_history.rb +0 -104
- data/test/test_mechanize_http_agent.rb +0 -2145
- data/test/test_mechanize_http_auth_challenge.rb +0 -64
- data/test/test_mechanize_http_auth_realm.rb +0 -56
- data/test/test_mechanize_http_auth_store.rb +0 -233
- data/test/test_mechanize_http_content_disposition_parser.rb +0 -167
- data/test/test_mechanize_http_www_authenticate_parser.rb +0 -204
- data/test/test_mechanize_image.rb +0 -9
- data/test/test_mechanize_link.rb +0 -171
- data/test/test_mechanize_page.rb +0 -295
- data/test/test_mechanize_page_encoding.rb +0 -215
- data/test/test_mechanize_page_frame.rb +0 -17
- data/test/test_mechanize_page_image.rb +0 -191
- data/test/test_mechanize_page_link.rb +0 -377
- data/test/test_mechanize_page_meta_refresh.rb +0 -151
- data/test/test_mechanize_parser.rb +0 -316
- data/test/test_mechanize_pluggable_parser.rb +0 -68
- data/test/test_mechanize_redirect_limit_reached_error.rb +0 -25
- data/test/test_mechanize_redirect_not_get_or_head_error.rb +0 -15
- data/test/test_mechanize_response_read_error.rb +0 -29
- data/test/test_mechanize_subclass.rb +0 -23
- data/test/test_mechanize_util.rb +0 -144
- data/test/test_mechanize_xml_file.rb +0 -30
- data/test/test_multi_select.rb +0 -120
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 88e582acc05ea06598dcdde3bd7feeaa34b865a9f14cbdb471867e011615d746
|
|
4
|
+
data.tar.gz: 0b6ef8790866784501313c7b8485bba98bda4665ae520f6cd7fef3c24e99f9a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22c3ccf0b548e92b4ff08a9144156d301d80bbf93e64302db5d8efdbdeb3f54dd1f8ddd827cc09382064134ec3f4488ae8f63ac3ad0c75b5aa536046e62dd8ad
|
|
7
|
+
data.tar.gz: 0a810214b4812af939185ccd63a73bb4adebff45afc0d94e5f931702c928e7949a21b09655dc16e36ecfd1e8e7c3d328e7c9912291373ac4d7cfb08f84ea0c5a
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Mechanize CHANGELOG
|
|
2
2
|
|
|
3
|
+
## 2.14.2 / 2026-10-26
|
|
4
|
+
|
|
5
|
+
### Security
|
|
6
|
+
|
|
7
|
+
* A malicious server can no longer make `Mechanize::FileSaver`, or `Mechanize::DirectorySaver` with `decode_filename: true`, write files outside the save directory. Only applications that register one of these as a pluggable parser are affected. [GHSA-hxgc-9476-fc65](https://github.com/sparklemotion/mechanize/security/advisories/GHSA-hxgc-9476-fc65)
|
|
8
|
+
|
|
9
|
+
### Improved
|
|
10
|
+
|
|
11
|
+
* The gem no longer packages the test suite, the test certificates, or the example scripts, which makes it about a third smaller. It still packages `test/htdocs/`, which `Mechanize::TestCase` needs. (#667) @yuri-zubov
|
|
12
|
+
* `Mechanize::TestCase` fake responses work with `net-http` 0.10.0 and later, which reads response lines with `Net::BufferedIO#readuntil`. Previously a chunked response body raised `NoMethodError`. The fake socket is now a `Net::BufferedIO`, like a real one, so `read_body` yields fragments of at most 16 KiB, and a body shorter than its `Content-Length` raises `EOFError` when `ignore_eof` is false.
|
|
13
|
+
|
|
14
|
+
|
|
3
15
|
## 2.14.1 / 2026-08-22
|
|
4
16
|
|
|
5
17
|
### Security
|
|
@@ -1147,4 +1159,3 @@ Mechanize is now under the MIT license
|
|
|
1147
1159
|
* Added a response code exception
|
|
1148
1160
|
* Thanks to Brian Ellin (brianellin@gmail.com) for:
|
|
1149
1161
|
Added support for CA files, and support for 301 response codes
|
|
1150
|
-
|
|
@@ -64,8 +64,9 @@ class Mechanize::DirectorySaver < Mechanize::Download
|
|
|
64
64
|
|
|
65
65
|
super
|
|
66
66
|
|
|
67
|
-
@filename = CGI.unescape(@filename) if self.class.decode_filename?
|
|
67
|
+
@filename = CGI.unescape(@filename).tr('/\\', '_') if self.class.decode_filename?
|
|
68
68
|
path = File.join directory, @filename
|
|
69
|
+
ensure_within directory, path
|
|
69
70
|
|
|
70
71
|
if self.class.overwrite?
|
|
71
72
|
save! path
|
data/lib/mechanize/file_saver.rb
CHANGED
data/lib/mechanize/parser.rb
CHANGED
|
@@ -108,10 +108,10 @@ module Mechanize::Parser
|
|
|
108
108
|
handled = false
|
|
109
109
|
|
|
110
110
|
if @uri then
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
uri_path = remove_dot_segments @uri.path
|
|
112
|
+
uri_path += 'index.html' if uri_path.end_with? '/'
|
|
113
113
|
|
|
114
|
-
path =
|
|
114
|
+
path = uri_path.split(/\//)
|
|
115
115
|
filename = path.pop || 'index.html'
|
|
116
116
|
else
|
|
117
117
|
path = []
|
|
@@ -163,6 +163,36 @@ module Mechanize::Parser
|
|
|
163
163
|
@response
|
|
164
164
|
end
|
|
165
165
|
|
|
166
|
+
##
|
|
167
|
+
# Resolves "." and ".." segments in the absolute +path+ as RFC 3986 section
|
|
168
|
+
# 5.2.4 does, without reparsing it as a URI.
|
|
169
|
+
|
|
170
|
+
def remove_dot_segments path
|
|
171
|
+
segments = path.split '/', -1
|
|
172
|
+
|
|
173
|
+
resolved = segments.each_with_object [] do |segment, result|
|
|
174
|
+
case segment
|
|
175
|
+
when '.' then next
|
|
176
|
+
when '..' then result.pop unless result == ['']
|
|
177
|
+
else result << segment
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
resolved << '' if ['.', '..'].include? segments.last
|
|
182
|
+
resolved.join '/'
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
##
|
|
186
|
+
# Raises Mechanize::Error unless +path+ is inside +directory+.
|
|
187
|
+
|
|
188
|
+
def ensure_within directory, path
|
|
189
|
+
directory = File.join File.expand_path(directory), ''
|
|
190
|
+
|
|
191
|
+
return if File.expand_path(path).start_with? directory
|
|
192
|
+
|
|
193
|
+
raise Mechanize::Error, "refusing to save #{path} outside #{directory}"
|
|
194
|
+
end
|
|
195
|
+
|
|
166
196
|
##
|
|
167
197
|
# Finds a free filename based on +filename+, but is not race-free
|
|
168
198
|
|
data/lib/mechanize/test_case.rb
CHANGED
|
@@ -262,15 +262,8 @@ class Net::HTTP # :nodoc:
|
|
|
262
262
|
response['Content-Type'] ||= 'text/html'
|
|
263
263
|
response['Content-Length'] = res['Content-Length'] || res.body.length.to_s
|
|
264
264
|
|
|
265
|
-
|
|
266
|
-
response.instance_variable_set :@socket,
|
|
267
|
-
def io.read clen, dest = nil, _ = nil
|
|
268
|
-
if dest then
|
|
269
|
-
dest << super(clen)
|
|
270
|
-
else
|
|
271
|
-
super clen
|
|
272
|
-
end
|
|
273
|
-
end
|
|
265
|
+
socket = Net::BufferedIO.new(StringIO.new(res.body))
|
|
266
|
+
response.instance_variable_set :@socket, socket
|
|
274
267
|
|
|
275
268
|
body_exist = req.response_body_permitted? &&
|
|
276
269
|
response_klass.body_permitted?
|
data/lib/mechanize/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mechanize
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.14.
|
|
4
|
+
version: 2.14.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Hodel
|
|
@@ -238,27 +238,12 @@ extra_rdoc_files:
|
|
|
238
238
|
- README.md
|
|
239
239
|
- SECURITY.md
|
|
240
240
|
files:
|
|
241
|
-
- ".autotest"
|
|
242
|
-
- ".github/dependabot.yml"
|
|
243
|
-
- ".github/workflows/ci.yml"
|
|
244
|
-
- ".github/workflows/upstream.yml"
|
|
245
|
-
- ".gitignore"
|
|
246
|
-
- ".yardopts"
|
|
247
241
|
- CHANGELOG.md
|
|
248
242
|
- EXAMPLES.rdoc
|
|
249
243
|
- GUIDE.rdoc
|
|
250
|
-
- Gemfile
|
|
251
244
|
- LICENSE.txt
|
|
252
245
|
- README.md
|
|
253
|
-
- Rakefile
|
|
254
246
|
- SECURITY.md
|
|
255
|
-
- examples/flickr_upload.rb
|
|
256
|
-
- examples/latest_user_agents.rb
|
|
257
|
-
- examples/mech-dump.rb
|
|
258
|
-
- examples/proxy_req.rb
|
|
259
|
-
- examples/rubygems.rb
|
|
260
|
-
- examples/spider.rb
|
|
261
|
-
- examples/wikipedia_links_to_philosophy.rb
|
|
262
247
|
- lib/mechanize.rb
|
|
263
248
|
- lib/mechanize/chunked_termination_error.rb
|
|
264
249
|
- lib/mechanize/content_type_error.rb
|
|
@@ -349,12 +334,6 @@ files:
|
|
|
349
334
|
- lib/mechanize/util.rb
|
|
350
335
|
- lib/mechanize/version.rb
|
|
351
336
|
- lib/mechanize/xml_file.rb
|
|
352
|
-
- mechanize.gemspec
|
|
353
|
-
- test/data/htpasswd
|
|
354
|
-
- test/data/server.crt
|
|
355
|
-
- test/data/server.csr
|
|
356
|
-
- test/data/server.key
|
|
357
|
-
- test/data/server.pem
|
|
358
337
|
- test/htdocs/alt_text.html
|
|
359
338
|
- test/htdocs/bad_form_test.html
|
|
360
339
|
- test/htdocs/button.jpg
|
|
@@ -402,54 +381,6 @@ files:
|
|
|
402
381
|
- test/htdocs/tc_textarea.html
|
|
403
382
|
- test/htdocs/test_click.html
|
|
404
383
|
- test/htdocs/unusual______.html
|
|
405
|
-
- test/test_mechanize.rb
|
|
406
|
-
- test/test_mechanize_cookie.rb
|
|
407
|
-
- test/test_mechanize_cookie_jar.rb
|
|
408
|
-
- test/test_mechanize_directory_saver.rb
|
|
409
|
-
- test/test_mechanize_download.rb
|
|
410
|
-
- test/test_mechanize_element_not_found_error.rb
|
|
411
|
-
- test/test_mechanize_file.rb
|
|
412
|
-
- test/test_mechanize_file_connection.rb
|
|
413
|
-
- test/test_mechanize_file_request.rb
|
|
414
|
-
- test/test_mechanize_file_response.rb
|
|
415
|
-
- test/test_mechanize_file_saver.rb
|
|
416
|
-
- test/test_mechanize_form.rb
|
|
417
|
-
- test/test_mechanize_form_check_box.rb
|
|
418
|
-
- test/test_mechanize_form_encoding.rb
|
|
419
|
-
- test/test_mechanize_form_field.rb
|
|
420
|
-
- test/test_mechanize_form_file_upload.rb
|
|
421
|
-
- test/test_mechanize_form_image_button.rb
|
|
422
|
-
- test/test_mechanize_form_keygen.rb
|
|
423
|
-
- test/test_mechanize_form_multi_select_list.rb
|
|
424
|
-
- test/test_mechanize_form_option.rb
|
|
425
|
-
- test/test_mechanize_form_radio_button.rb
|
|
426
|
-
- test/test_mechanize_form_select_list.rb
|
|
427
|
-
- test/test_mechanize_form_textarea.rb
|
|
428
|
-
- test/test_mechanize_headers.rb
|
|
429
|
-
- test/test_mechanize_history.rb
|
|
430
|
-
- test/test_mechanize_http_agent.rb
|
|
431
|
-
- test/test_mechanize_http_auth_challenge.rb
|
|
432
|
-
- test/test_mechanize_http_auth_realm.rb
|
|
433
|
-
- test/test_mechanize_http_auth_store.rb
|
|
434
|
-
- test/test_mechanize_http_content_disposition_parser.rb
|
|
435
|
-
- test/test_mechanize_http_www_authenticate_parser.rb
|
|
436
|
-
- test/test_mechanize_image.rb
|
|
437
|
-
- test/test_mechanize_link.rb
|
|
438
|
-
- test/test_mechanize_page.rb
|
|
439
|
-
- test/test_mechanize_page_encoding.rb
|
|
440
|
-
- test/test_mechanize_page_frame.rb
|
|
441
|
-
- test/test_mechanize_page_image.rb
|
|
442
|
-
- test/test_mechanize_page_link.rb
|
|
443
|
-
- test/test_mechanize_page_meta_refresh.rb
|
|
444
|
-
- test/test_mechanize_parser.rb
|
|
445
|
-
- test/test_mechanize_pluggable_parser.rb
|
|
446
|
-
- test/test_mechanize_redirect_limit_reached_error.rb
|
|
447
|
-
- test/test_mechanize_redirect_not_get_or_head_error.rb
|
|
448
|
-
- test/test_mechanize_response_read_error.rb
|
|
449
|
-
- test/test_mechanize_subclass.rb
|
|
450
|
-
- test/test_mechanize_util.rb
|
|
451
|
-
- test/test_mechanize_xml_file.rb
|
|
452
|
-
- test/test_multi_select.rb
|
|
453
384
|
homepage: https://github.com/sparklemotion/mechanize
|
|
454
385
|
licenses:
|
|
455
386
|
- MIT
|
|
@@ -476,107 +407,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
476
407
|
- !ruby/object:Gem::Version
|
|
477
408
|
version: '0'
|
|
478
409
|
requirements: []
|
|
479
|
-
rubygems_version: 4.0.
|
|
410
|
+
rubygems_version: 4.0.20
|
|
480
411
|
specification_version: 4
|
|
481
412
|
summary: The Mechanize library is used for automating interaction with websites
|
|
482
|
-
test_files:
|
|
483
|
-
- test/data/htpasswd
|
|
484
|
-
- test/data/server.crt
|
|
485
|
-
- test/data/server.csr
|
|
486
|
-
- test/data/server.key
|
|
487
|
-
- test/data/server.pem
|
|
488
|
-
- test/htdocs/alt_text.html
|
|
489
|
-
- test/htdocs/bad_form_test.html
|
|
490
|
-
- test/htdocs/button.jpg
|
|
491
|
-
- test/htdocs/canonical_uri.html
|
|
492
|
-
- test/htdocs/dir with spaces/foo.html
|
|
493
|
-
- test/htdocs/empty_form.html
|
|
494
|
-
- test/htdocs/file_upload.html
|
|
495
|
-
- test/htdocs/find_link.html
|
|
496
|
-
- test/htdocs/form_multi_select.html
|
|
497
|
-
- test/htdocs/form_multival.html
|
|
498
|
-
- test/htdocs/form_no_action.html
|
|
499
|
-
- test/htdocs/form_no_input_name.html
|
|
500
|
-
- test/htdocs/form_order_test.html
|
|
501
|
-
- test/htdocs/form_select.html
|
|
502
|
-
- test/htdocs/form_set_fields.html
|
|
503
|
-
- test/htdocs/form_test.html
|
|
504
|
-
- test/htdocs/frame_referer_test.html
|
|
505
|
-
- test/htdocs/frame_test.html
|
|
506
|
-
- test/htdocs/google.html
|
|
507
|
-
- test/htdocs/index.html
|
|
508
|
-
- test/htdocs/link with space.html
|
|
509
|
-
- test/htdocs/meta_cookie.html
|
|
510
|
-
- test/htdocs/no_title_test.html
|
|
511
|
-
- test/htdocs/noindex.html
|
|
512
|
-
- test/htdocs/rails_3_encoding_hack_form_test.html
|
|
513
|
-
- test/htdocs/relative/tc_relative_links.html
|
|
514
|
-
- test/htdocs/robots.html
|
|
515
|
-
- test/htdocs/tc_bad_charset.html
|
|
516
|
-
- test/htdocs/tc_bad_links.html
|
|
517
|
-
- test/htdocs/tc_base_link.html
|
|
518
|
-
- test/htdocs/tc_blank_form.html
|
|
519
|
-
- test/htdocs/tc_charset.html
|
|
520
|
-
- test/htdocs/tc_checkboxes.html
|
|
521
|
-
- test/htdocs/tc_encoded_links.html
|
|
522
|
-
- test/htdocs/tc_field_precedence.html
|
|
523
|
-
- test/htdocs/tc_follow_meta.html
|
|
524
|
-
- test/htdocs/tc_follow_meta_loop_1.html
|
|
525
|
-
- test/htdocs/tc_follow_meta_loop_2.html
|
|
526
|
-
- test/htdocs/tc_form_action.html
|
|
527
|
-
- test/htdocs/tc_links.html
|
|
528
|
-
- test/htdocs/tc_meta_in_body.html
|
|
529
|
-
- test/htdocs/tc_pretty_print.html
|
|
530
|
-
- test/htdocs/tc_referer.html
|
|
531
|
-
- test/htdocs/tc_relative_links.html
|
|
532
|
-
- test/htdocs/tc_textarea.html
|
|
533
|
-
- test/htdocs/test_click.html
|
|
534
|
-
- test/htdocs/unusual______.html
|
|
535
|
-
- test/test_mechanize.rb
|
|
536
|
-
- test/test_mechanize_cookie.rb
|
|
537
|
-
- test/test_mechanize_cookie_jar.rb
|
|
538
|
-
- test/test_mechanize_directory_saver.rb
|
|
539
|
-
- test/test_mechanize_download.rb
|
|
540
|
-
- test/test_mechanize_element_not_found_error.rb
|
|
541
|
-
- test/test_mechanize_file.rb
|
|
542
|
-
- test/test_mechanize_file_connection.rb
|
|
543
|
-
- test/test_mechanize_file_request.rb
|
|
544
|
-
- test/test_mechanize_file_response.rb
|
|
545
|
-
- test/test_mechanize_file_saver.rb
|
|
546
|
-
- test/test_mechanize_form.rb
|
|
547
|
-
- test/test_mechanize_form_check_box.rb
|
|
548
|
-
- test/test_mechanize_form_encoding.rb
|
|
549
|
-
- test/test_mechanize_form_field.rb
|
|
550
|
-
- test/test_mechanize_form_file_upload.rb
|
|
551
|
-
- test/test_mechanize_form_image_button.rb
|
|
552
|
-
- test/test_mechanize_form_keygen.rb
|
|
553
|
-
- test/test_mechanize_form_multi_select_list.rb
|
|
554
|
-
- test/test_mechanize_form_option.rb
|
|
555
|
-
- test/test_mechanize_form_radio_button.rb
|
|
556
|
-
- test/test_mechanize_form_select_list.rb
|
|
557
|
-
- test/test_mechanize_form_textarea.rb
|
|
558
|
-
- test/test_mechanize_headers.rb
|
|
559
|
-
- test/test_mechanize_history.rb
|
|
560
|
-
- test/test_mechanize_http_agent.rb
|
|
561
|
-
- test/test_mechanize_http_auth_challenge.rb
|
|
562
|
-
- test/test_mechanize_http_auth_realm.rb
|
|
563
|
-
- test/test_mechanize_http_auth_store.rb
|
|
564
|
-
- test/test_mechanize_http_content_disposition_parser.rb
|
|
565
|
-
- test/test_mechanize_http_www_authenticate_parser.rb
|
|
566
|
-
- test/test_mechanize_image.rb
|
|
567
|
-
- test/test_mechanize_link.rb
|
|
568
|
-
- test/test_mechanize_page.rb
|
|
569
|
-
- test/test_mechanize_page_encoding.rb
|
|
570
|
-
- test/test_mechanize_page_frame.rb
|
|
571
|
-
- test/test_mechanize_page_image.rb
|
|
572
|
-
- test/test_mechanize_page_link.rb
|
|
573
|
-
- test/test_mechanize_page_meta_refresh.rb
|
|
574
|
-
- test/test_mechanize_parser.rb
|
|
575
|
-
- test/test_mechanize_pluggable_parser.rb
|
|
576
|
-
- test/test_mechanize_redirect_limit_reached_error.rb
|
|
577
|
-
- test/test_mechanize_redirect_not_get_or_head_error.rb
|
|
578
|
-
- test/test_mechanize_response_read_error.rb
|
|
579
|
-
- test/test_mechanize_subclass.rb
|
|
580
|
-
- test/test_mechanize_util.rb
|
|
581
|
-
- test/test_mechanize_xml_file.rb
|
|
582
|
-
- test/test_multi_select.rb
|
|
413
|
+
test_files: []
|
data/.autotest
DELETED
data/.github/dependabot.yml
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# To get started with Dependabot version updates, you'll need to specify which
|
|
2
|
-
# package ecosystems to update and where the package manifests are located.
|
|
3
|
-
# Please see the documentation for all configuration options:
|
|
4
|
-
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
5
|
-
|
|
6
|
-
version: 2
|
|
7
|
-
updates:
|
|
8
|
-
- package-ecosystem: "bundler"
|
|
9
|
-
directory: "/"
|
|
10
|
-
schedule:
|
|
11
|
-
interval: "weekly"
|
data/.github/workflows/ci.yml
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
name: "ci"
|
|
2
|
-
|
|
3
|
-
concurrency:
|
|
4
|
-
group: "${{github.workflow}}-${{github.ref}}"
|
|
5
|
-
cancel-in-progress: true
|
|
6
|
-
|
|
7
|
-
on:
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
schedule:
|
|
10
|
-
- cron: "0 8 * * 5" # At 08:00 on Friday # https://crontab.guru/#0_8_*_*_5
|
|
11
|
-
push:
|
|
12
|
-
branches:
|
|
13
|
-
- main
|
|
14
|
-
pull_request:
|
|
15
|
-
types: [opened, synchronize]
|
|
16
|
-
branches:
|
|
17
|
-
- main
|
|
18
|
-
|
|
19
|
-
jobs:
|
|
20
|
-
rubocop:
|
|
21
|
-
runs-on: ubuntu-latest
|
|
22
|
-
steps:
|
|
23
|
-
- uses: actions/checkout@v4
|
|
24
|
-
- uses: ruby/setup-ruby@v1
|
|
25
|
-
with:
|
|
26
|
-
ruby-version: "4.0"
|
|
27
|
-
bundler-cache: true
|
|
28
|
-
- run: bundle exec rake rubocop
|
|
29
|
-
|
|
30
|
-
test:
|
|
31
|
-
needs: ["rubocop"]
|
|
32
|
-
strategy:
|
|
33
|
-
fail-fast: false
|
|
34
|
-
matrix:
|
|
35
|
-
ruby-version: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "3.4", "4.0"]
|
|
36
|
-
runs-on: ubuntu-latest
|
|
37
|
-
steps:
|
|
38
|
-
- uses: actions/checkout@v4
|
|
39
|
-
- uses: ruby/setup-ruby@v1
|
|
40
|
-
with:
|
|
41
|
-
ruby-version: ${{matrix.ruby-version}}
|
|
42
|
-
bundler-cache: true
|
|
43
|
-
- run: bundle exec rake test
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
name: "upstream"
|
|
2
|
-
|
|
3
|
-
concurrency:
|
|
4
|
-
group: "${{github.workflow}}-${{github.ref}}"
|
|
5
|
-
cancel-in-progress: true
|
|
6
|
-
|
|
7
|
-
on:
|
|
8
|
-
workflow_dispatch:
|
|
9
|
-
schedule:
|
|
10
|
-
- cron: "0 8 * * 5" # At 08:00 on Friday # https://crontab.guru/#0_8_*_*_5
|
|
11
|
-
push:
|
|
12
|
-
branches:
|
|
13
|
-
- main
|
|
14
|
-
pull_request:
|
|
15
|
-
types: [opened, synchronize]
|
|
16
|
-
branches:
|
|
17
|
-
- main
|
|
18
|
-
paths:
|
|
19
|
-
- .github/workflows/upstream.yml # this file
|
|
20
|
-
|
|
21
|
-
jobs:
|
|
22
|
-
test:
|
|
23
|
-
strategy:
|
|
24
|
-
fail-fast: false
|
|
25
|
-
matrix:
|
|
26
|
-
ruby-version: ["head", "truffleruby-head"]
|
|
27
|
-
runs-on: ubuntu-latest
|
|
28
|
-
steps:
|
|
29
|
-
- uses: actions/checkout@v4
|
|
30
|
-
- uses: ruby/setup-ruby@v1
|
|
31
|
-
with:
|
|
32
|
-
ruby-version: ${{matrix.ruby-version}}
|
|
33
|
-
bundler-cache: true
|
|
34
|
-
- run: bundle exec rake test
|
|
35
|
-
|
|
36
|
-
upstream:
|
|
37
|
-
name: "upstream (${{matrix.name}})"
|
|
38
|
-
strategy:
|
|
39
|
-
fail-fast: false
|
|
40
|
-
matrix:
|
|
41
|
-
include:
|
|
42
|
-
- { name: "nokogiri", git: "https://github.com/sparklemotion/nokogiri" }
|
|
43
|
-
runs-on: ubuntu-latest
|
|
44
|
-
steps:
|
|
45
|
-
- uses: actions/checkout@v4
|
|
46
|
-
- uses: ruby/setup-ruby@v1
|
|
47
|
-
with: { ruby-version: "4.0" }
|
|
48
|
-
- run: |
|
|
49
|
-
bundle add ${{matrix.name}} --git="${{matrix.git}}"
|
|
50
|
-
bundle show
|
|
51
|
-
- run: bundle exec rake test
|
data/.gitignore
DELETED
data/.yardopts
DELETED
data/Gemfile
DELETED
data/Rakefile
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
|
|
3
|
-
begin
|
|
4
|
-
require "bundler/gem_tasks"
|
|
5
|
-
rescue LoadError
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
require 'rdoc/task'
|
|
9
|
-
require 'rake/testtask'
|
|
10
|
-
|
|
11
|
-
task :prerelease => [:clobber_rdoc, :test]
|
|
12
|
-
|
|
13
|
-
desc "Update SSL Certificate"
|
|
14
|
-
task('ssl_cert') do |p|
|
|
15
|
-
sh "openssl genrsa -des3 -out server.key 1024"
|
|
16
|
-
sh "openssl req -new -key server.key -out server.csr"
|
|
17
|
-
sh "cp server.key server.key.org"
|
|
18
|
-
sh "openssl rsa -in server.key.org -out server.key"
|
|
19
|
-
sh "openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt"
|
|
20
|
-
sh "cp server.key server.pem"
|
|
21
|
-
sh "mv server.key server.csr server.crt server.pem test/data/"
|
|
22
|
-
sh "rm server.key.org"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
RDoc::Task.new do |rdoc|
|
|
26
|
-
rdoc.main = "README.md"
|
|
27
|
-
rdoc.rdoc_dir = 'doc'
|
|
28
|
-
rdoc.rdoc_files.include( "CHANGELOG.md", "EXAMPLES.rdoc", "GUIDE.rdoc", "LICENSE.txt", "README.md", "lib/**/*.rb")
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
desc "Run tests"
|
|
32
|
-
Rake::TestTask.new { |t|
|
|
33
|
-
t.test_files = Dir['test/**/test*.rb']
|
|
34
|
-
# t.verbose = true
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
task publish_docs: %w[rdoc] do
|
|
38
|
-
sh 'rsync', '-avzO', '--delete', 'doc/', 'docs-push.seattlerb.org:/data/www/docs.seattlerb.org/mechanize/'
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
desc "Run rubocop checks"
|
|
42
|
-
task :rubocop => ["rubocop:security", "rubocop:frozen_string_literals"]
|
|
43
|
-
|
|
44
|
-
namespace "rubocop" do
|
|
45
|
-
desc "Run rubocop security check"
|
|
46
|
-
task :security do
|
|
47
|
-
sh "rubocop lib --only Security"
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
desc "Run rubocop string literals check"
|
|
51
|
-
task :frozen_string_literals do
|
|
52
|
-
sh "rubocop lib test --auto-correct-all --only Style/FrozenStringLiteralComment"
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
task default: [:rubocop, :test]
|
data/examples/flickr_upload.rb
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require 'rubygems'
|
|
2
|
-
require 'mechanize'
|
|
3
|
-
|
|
4
|
-
agent = Mechanize.new
|
|
5
|
-
|
|
6
|
-
# Get the flickr sign in page
|
|
7
|
-
page = agent.get 'http://flickr.com/signin/flickr/'
|
|
8
|
-
|
|
9
|
-
# Fill out the login form
|
|
10
|
-
form = page.form_with :name => 'flickrloginform'
|
|
11
|
-
form.email = ARGV[0]
|
|
12
|
-
form.password = ARGV[1]
|
|
13
|
-
form.submit
|
|
14
|
-
|
|
15
|
-
# Go to the upload page
|
|
16
|
-
page = page.link_with(:text => 'Upload').click
|
|
17
|
-
|
|
18
|
-
# Fill out the form
|
|
19
|
-
form = page.forms.action('/photos_upload_process.gne').first
|
|
20
|
-
form.file_uploads.name('file1').first.file_name = ARGV[2]
|
|
21
|
-
form.submit
|
|
22
|
-
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
require 'mechanize'
|
|
2
|
-
require 'ostruct'
|
|
3
|
-
|
|
4
|
-
# LatestUAFetcher fetches latest user agents from `WhatIsMyBrowser.com`.
|
|
5
|
-
# It can use to update `Mechanize::AGENT_ALIASES`.
|
|
6
|
-
class LatestUAFetcher
|
|
7
|
-
attr_reader :user_agents
|
|
8
|
-
|
|
9
|
-
USER_AGENT_TYPES = OpenStruct.new(
|
|
10
|
-
linux_firefox: "Linux Firefox",
|
|
11
|
-
mac_firefox: "Mac Firefox",
|
|
12
|
-
mac_safari: "Mac Safari",
|
|
13
|
-
windows_chrome: "Windows Chrome",
|
|
14
|
-
windows_edge: "Windows Edge",
|
|
15
|
-
windows_firefox: "Windows Firefox",
|
|
16
|
-
android: "Android",
|
|
17
|
-
iphone: "iPhone",
|
|
18
|
-
ipad: "iPad",
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
BASE_URL = 'https://www.whatismybrowser.com/guides/the-latest-user-agent'
|
|
22
|
-
|
|
23
|
-
def initialize
|
|
24
|
-
@agent = Mechanize.new.tap { |a| a.user_agent_alias = 'Mac Firefox' }
|
|
25
|
-
@user_agents = {}
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def run
|
|
29
|
-
return unless user_agents.empty?
|
|
30
|
-
|
|
31
|
-
sleep_time = 1
|
|
32
|
-
|
|
33
|
-
fetch_user_agents('chrome')
|
|
34
|
-
fetch_user_agents('firefox')
|
|
35
|
-
fetch_user_agents('safari')
|
|
36
|
-
fetch_user_agents('edge')
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def ordered_user_agents
|
|
40
|
-
USER_AGENT_TYPES.to_h.values.each_with_object({}) do |type, ordered_user_agents|
|
|
41
|
-
ordered_user_agents[type] = user_agents[type]
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
private
|
|
46
|
-
|
|
47
|
-
def fetch_user_agents(browser_name, sleep_time = 1)
|
|
48
|
-
puts "fetch #{browser_name} UA..."
|
|
49
|
-
send(browser_name)
|
|
50
|
-
puts "sleeping... (#{sleep_time}s)"
|
|
51
|
-
sleep sleep_time
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def edge
|
|
55
|
-
page = @agent.get("#{BASE_URL}/edge")
|
|
56
|
-
|
|
57
|
-
windows_dom = page.css("h2:contains('Latest Edge on Windows User Agents')")
|
|
58
|
-
|
|
59
|
-
@user_agents[USER_AGENT_TYPES.windows_edge] = windows_dom.css('+ .listing-of-useragents .code').first.text
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def firefox
|
|
63
|
-
page = @agent.get("#{BASE_URL}/firefox")
|
|
64
|
-
|
|
65
|
-
desktop_dom = page.css("h2:contains('Latest Firefox on Desktop User Agents')")
|
|
66
|
-
table_dom = desktop_dom.css('+ .listing-of-useragents')
|
|
67
|
-
|
|
68
|
-
@user_agents[USER_AGENT_TYPES.linux_firefox] = table_dom.css('td:contains("Linux")').css("+ td .code:contains('Ubuntu; Linux x86_64')").text
|
|
69
|
-
@user_agents[USER_AGENT_TYPES.windows_firefox] = table_dom.css('td:contains("Windows")').css('+ td .code').text
|
|
70
|
-
@user_agents[USER_AGENT_TYPES.mac_firefox] = table_dom.css('td:contains("Macos")').css('+ td .code').text
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def safari
|
|
74
|
-
page = @agent.get("#{BASE_URL}/safari")
|
|
75
|
-
|
|
76
|
-
macos_dom = page.css("h2:contains('Latest Safari on macOS User Agents')")
|
|
77
|
-
ios_dom = page.css("h2:contains('Latest Safari on iOS User Agents')")
|
|
78
|
-
|
|
79
|
-
@user_agents[USER_AGENT_TYPES.mac_safari] = macos_dom.css('+ .listing-of-useragents .code').first.text
|
|
80
|
-
@user_agents[USER_AGENT_TYPES.iphone] = ios_dom.css('+ .listing-of-useragents').css("tr:contains('Iphone') .code").text
|
|
81
|
-
@user_agents[USER_AGENT_TYPES.ipad] = ios_dom.css('+ .listing-of-useragents').css("tr:contains('Ipad') .code").text
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def chrome
|
|
85
|
-
page = @agent.get("#{BASE_URL}/chrome")
|
|
86
|
-
|
|
87
|
-
windows_dom = page.css("h2:contains('Latest Chrome on Windows 10 User Agents')")
|
|
88
|
-
android_dom = page.css("h2:contains('Latest Chrome on Android User Agents')")
|
|
89
|
-
|
|
90
|
-
@user_agents[USER_AGENT_TYPES.windows_chrome] = windows_dom.css('+ .listing-of-useragents .code').first.text
|
|
91
|
-
@user_agents[USER_AGENT_TYPES.android] = android_dom.css('+ .listing-of-useragents .code').first.text
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
if $0 == __FILE__
|
|
96
|
-
agent = LatestUAFetcher.new
|
|
97
|
-
agent.run
|
|
98
|
-
|
|
99
|
-
pp agent.ordered_user_agents
|
|
100
|
-
end
|