mechanize 2.11.0 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4c0419c6395467b67e04d02f6fad693555635888226463874b23836dd481f74
4
- data.tar.gz: e9787a25ee371a1f9c5918c49cab30c89d6fb375ca1e6fffc7b444bc5dc5f7e1
3
+ metadata.gz: 7183879e98b1195380219464368f7761a6ee2b9adb3eb18f47b216e740d840d5
4
+ data.tar.gz: 9eaf999bb67a5f7f7625b1a77a4466b88a005d947003b67e155398f3af2b0bf5
5
5
  SHA512:
6
- metadata.gz: 23436f8664e13b44f71d5abb2b7b29a0a309e76880503c6ac68c19e1258d3e0dd73919f4b407f0dcfb3fe04dfeea0a350c0fcc967c2fee13085a69aa71992084
7
- data.tar.gz: 9869c25e459212cbff34f11e0cadcc985fff6e97bfad5012c091a9c594dd9a58ba2bc4afb7fed50c089cbe943a3adb9528968e80df01803869709508aaf9d218
6
+ metadata.gz: 3ba304c3a37d0eb98ccbbba83f425a68cb6ad2fb0da5d768a93cc8fd802f691da8fb86d7b6670888a597ca5f3f96ff755d6155197cbd1eef7c8db2442177bd72
7
+ data.tar.gz: db944be6db0079e9740c8e3aaade533baf990efbd87b6ebdbca034eb81a0adef82838fa50fd301f72d23c463109660a3256d0fae7f0154c8393a97b24ab214a1
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Mechanize CHANGELOG
2
2
 
3
+ ## 2.12.1 / 2024-08-21
4
+
5
+ * Introduce experimental support for handling Zstd-compressed responses (CRuby only). (#652) @adrianodennanni
6
+
7
+
8
+ ## 2.12.0 / 2024-07-29
9
+
10
+ * Introduce experimental support for handling Brotli-compressed responses (CRuby only). (#650) @weshatheleopard
11
+
12
+
3
13
  ## 2.11.0 / 2024-07-18
4
14
 
5
15
  * The `accept-charset` header is no longer sent. In early versions of Mechanize, circa 2007, this was a common header but now no modern browser sends it, and servers are instructed to ignore it. See #646 for an example of a server that is confused by its presence. (#647) @flavorjones
data/Gemfile CHANGED
@@ -1,3 +1,12 @@
1
1
  source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
+
5
+ gem "minitest", "~> 5.14"
6
+ gem "rake", "~> 13.0"
7
+ gem "rdoc", "~> 6.3"
8
+ gem "rubocop", "~> 1.12"
9
+ unless RUBY_PLATFORM == 'java'
10
+ gem 'brotli', '>= 0.5'
11
+ gem 'zstd-ruby', '~> 1.5'
12
+ end
@@ -495,6 +495,63 @@ class Mechanize::HTTP::Agent
495
495
  body_io.close
496
496
  end
497
497
 
498
+ ##
499
+ # Decodes a Brotli-encoded +body_io+
500
+ #
501
+ # (Experimental, CRuby only) Although Mechanize will never request a Brotli-encoded response via
502
+ # `accept-encoding`, buggy servers may return brotli-encoded responses anyway. Let's try to handle
503
+ # that case if the Brotli gem is loaded.
504
+ #
505
+ # If you need to handle Brotli-encoded responses, install the 'brotli' gem and require it in your
506
+ # application. If the `Brotli` constant is defined, Mechanize will attempt to use it to inflate
507
+ # the response.
508
+ #
509
+ def content_encoding_brotli(body_io)
510
+ log.debug('deflate brotli body') if log
511
+
512
+ unless defined?(::Brotli)
513
+ raise Mechanize::Error, "cannot deflate brotli-encoded response. Please install and require the 'brotli' gem."
514
+ end
515
+
516
+ begin
517
+ return StringIO.new(Brotli.inflate(body_io.read))
518
+ rescue Brotli::Error
519
+ log.error("unable to brotli-inflate response") if log
520
+ raise Mechanize::Error, "error inflating brotli-encoded response."
521
+ end
522
+ ensure
523
+ body_io.close
524
+ end
525
+
526
+ ##
527
+ # Decodes a Zstd-encoded +body_io+
528
+ #
529
+ # (Experimental, CRuby only) Although Mechanize will never request a zstd-encoded response via
530
+ # `accept-encoding`, buggy servers may return zstd-encoded responses, or you might need to
531
+ # inform the zstd keyword on your Accept-Encoding headers. Let's try to handle those cases if
532
+ # the Zstd gem is loaded.
533
+ #
534
+ # If you need to handle Zstd-encoded responses, install the 'zstd-ruby' gem and require it in your
535
+ # application. If the `Zstd` constant is defined, Mechanize will attempt to use it to inflate
536
+ # the response.
537
+ #
538
+ def content_encoding_zstd(body_io)
539
+ log.debug('deflate zstd body') if log
540
+
541
+ unless defined?(::Zstd)
542
+ raise Mechanize::Error, "cannot deflate zstd-encoded response. Please install and require the 'zstd-ruby' gem."
543
+ end
544
+
545
+ begin
546
+ return StringIO.new(Zstd.decompress(body_io.read))
547
+ rescue StandardError
548
+ log.error("unable to zstd#decompress response") if log
549
+ raise Mechanize::Error, "error decompressing zstd-encoded response."
550
+ end
551
+ ensure
552
+ body_io.close
553
+ end
554
+
498
555
  def disable_keep_alive request
499
556
  request['connection'] = 'close' unless @keep_alive
500
557
  end
@@ -831,6 +888,10 @@ class Mechanize::HTTP::Agent
831
888
  content_encoding_inflate body_io
832
889
  when 'gzip', 'x-gzip' then
833
890
  content_encoding_gunzip body_io
891
+ when 'br' then
892
+ content_encoding_brotli body_io
893
+ when 'zstd' then
894
+ content_encoding_zstd body_io
834
895
  else
835
896
  raise Mechanize::Error,
836
897
  "unsupported content-encoding: #{response['Content-Encoding']}"
@@ -15,11 +15,6 @@ end
15
15
 
16
16
  require 'minitest/autorun'
17
17
 
18
- begin
19
- require 'minitest/pride'
20
- rescue LoadError
21
- end
22
-
23
18
  ##
24
19
  # A generic test case for testing mechanize. Using a subclass of
25
20
  # Mechanize::TestCase for your tests will create an isolated mechanize
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  class Mechanize
3
- VERSION = "2.11.0"
3
+ VERSION = "2.12.1"
4
4
  end
data/mechanize.gemspec CHANGED
@@ -71,9 +71,4 @@ Gem::Specification.new do |spec|
71
71
  spec.add_runtime_dependency("rubyntlm", ">= 0.6.3", "~> 0.6")
72
72
  spec.add_runtime_dependency("base64") # removed from bundled gems in 3.4, and needed by rubyntlm (which doesn't declare this dependency)
73
73
  spec.add_runtime_dependency("nkf") # removed from bundled gems in 3.4
74
-
75
- spec.add_development_dependency("minitest", "~> 5.14")
76
- spec.add_development_dependency("rake", "~> 13.0")
77
- spec.add_development_dependency("rdoc", "~> 6.3")
78
- spec.add_development_dependency("rubocop", "~> 1.12")
79
74
  end
@@ -2,6 +2,10 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'mechanize/test_case'
5
+ unless RUBY_PLATFORM == 'java'
6
+ require 'brotli'
7
+ require 'zstd-ruby'
8
+ end
5
9
 
6
10
  class TestMechanizeHttpAgent < Mechanize::TestCase
7
11
 
@@ -924,6 +928,86 @@ class TestMechanizeHttpAgent < Mechanize::TestCase
924
928
  assert_equal 'part', body.read
925
929
  end
926
930
 
931
+ def test_response_content_encoding_brotli_when_brotli_not_loaded
932
+ skip("only test this on jruby which doesn't have brotli support") unless RUBY_ENGINE == 'jruby'
933
+
934
+ @res.instance_variable_set :@header, 'content-encoding' => %w[br]
935
+ body_io = StringIO.new("content doesn't matter for this test")
936
+
937
+ e = assert_raises(Mechanize::Error) do
938
+ @agent.response_content_encoding(@res, body_io)
939
+ end
940
+ assert_includes(e.message, "cannot deflate brotli-encoded response")
941
+
942
+ assert(body_io.closed?)
943
+ end
944
+
945
+ def test_response_content_encoding_brotli
946
+ skip("jruby does not have brotli support") if RUBY_ENGINE == 'jruby'
947
+
948
+ @res.instance_variable_set :@header, 'content-encoding' => %w[br]
949
+ body_io = StringIO.new(Brotli.deflate("this is compressed by brotli"))
950
+
951
+ body = @agent.response_content_encoding(@res, body_io)
952
+
953
+ assert_equal("this is compressed by brotli", body.read)
954
+ assert(body_io.closed?)
955
+ end
956
+
957
+ def test_response_content_encoding_brotli_corrupt
958
+ skip("jruby does not have brotli support") if RUBY_ENGINE == 'jruby'
959
+
960
+ @res.instance_variable_set :@header, 'content-encoding' => %w[br]
961
+ body_io = StringIO.new("not a brotli payload")
962
+
963
+ e = assert_raises(Mechanize::Error) do
964
+ @agent.response_content_encoding(@res, body_io)
965
+ end
966
+ assert_includes(e.message, "error inflating brotli-encoded response")
967
+ assert_kind_of(Brotli::Error, e.cause)
968
+ assert(body_io.closed?)
969
+ end
970
+
971
+ def test_response_content_encoding_zstd_when_zstd_not_loaded
972
+ skip("only test this on jruby which doesn't have zstd support") unless RUBY_ENGINE == 'jruby'
973
+
974
+ @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
975
+ body_io = StringIO.new("content doesn't matter for this test")
976
+
977
+ e = assert_raises(Mechanize::Error) do
978
+ @agent.response_content_encoding(@res, body_io)
979
+ end
980
+ assert_includes(e.message, 'cannot deflate zstd-encoded response')
981
+
982
+ assert(body_io.closed?)
983
+ end
984
+
985
+ def test_response_content_encoding_zstd
986
+ skip('jruby does not have zstd support') if RUBY_ENGINE == 'jruby'
987
+
988
+ @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
989
+ body_io = StringIO.new(Zstd.compress('this is compressed by zstd'))
990
+
991
+ body = @agent.response_content_encoding(@res, body_io)
992
+
993
+ assert_equal('this is compressed by zstd', body.read)
994
+ assert(body_io.closed?)
995
+ end
996
+
997
+ def test_response_content_encoding_zstd_corrupt
998
+ skip('jruby does not have zstd support') if RUBY_ENGINE == 'jruby'
999
+
1000
+ @res.instance_variable_set :@header, 'content-encoding' => %w[zstd]
1001
+ body_io = StringIO.new('not a zstd payload')
1002
+
1003
+ e = assert_raises(Mechanize::Error) do
1004
+ @agent.response_content_encoding(@res, body_io)
1005
+ end
1006
+ assert_includes(e.message, 'error decompressing zstd-encoded response')
1007
+ assert_kind_of(RuntimeError, e.cause)
1008
+ assert(body_io.closed?)
1009
+ end
1010
+
927
1011
  def test_response_content_encoding_gzip_corrupt
928
1012
  log = StringIO.new
929
1013
  logger = Logger.new log
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.11.0
4
+ version: 2.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Hodel
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2024-07-18 00:00:00.000000000 Z
15
+ date: 2024-08-21 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: addressable
@@ -218,62 +218,6 @@ dependencies:
218
218
  - - ">="
219
219
  - !ruby/object:Gem::Version
220
220
  version: '0'
221
- - !ruby/object:Gem::Dependency
222
- name: minitest
223
- requirement: !ruby/object:Gem::Requirement
224
- requirements:
225
- - - "~>"
226
- - !ruby/object:Gem::Version
227
- version: '5.14'
228
- type: :development
229
- prerelease: false
230
- version_requirements: !ruby/object:Gem::Requirement
231
- requirements:
232
- - - "~>"
233
- - !ruby/object:Gem::Version
234
- version: '5.14'
235
- - !ruby/object:Gem::Dependency
236
- name: rake
237
- requirement: !ruby/object:Gem::Requirement
238
- requirements:
239
- - - "~>"
240
- - !ruby/object:Gem::Version
241
- version: '13.0'
242
- type: :development
243
- prerelease: false
244
- version_requirements: !ruby/object:Gem::Requirement
245
- requirements:
246
- - - "~>"
247
- - !ruby/object:Gem::Version
248
- version: '13.0'
249
- - !ruby/object:Gem::Dependency
250
- name: rdoc
251
- requirement: !ruby/object:Gem::Requirement
252
- requirements:
253
- - - "~>"
254
- - !ruby/object:Gem::Version
255
- version: '6.3'
256
- type: :development
257
- prerelease: false
258
- version_requirements: !ruby/object:Gem::Requirement
259
- requirements:
260
- - - "~>"
261
- - !ruby/object:Gem::Version
262
- version: '6.3'
263
- - !ruby/object:Gem::Dependency
264
- name: rubocop
265
- requirement: !ruby/object:Gem::Requirement
266
- requirements:
267
- - - "~>"
268
- - !ruby/object:Gem::Version
269
- version: '1.12'
270
- type: :development
271
- prerelease: false
272
- version_requirements: !ruby/object:Gem::Requirement
273
- requirements:
274
- - - "~>"
275
- - !ruby/object:Gem::Version
276
- version: '1.12'
277
221
  description: |-
278
222
  The Mechanize library is used for automating interaction with websites.
279
223
  Mechanize automatically stores and sends cookies, follows redirects,