From ab12abaa6514da5f91a7fe90fea75ae849829c89 Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Tue, 8 Oct 2024 19:58:50 +0900 Subject: [PATCH 1/2] Address `warning: literal string will be frozen in the future` warnings This commit addresses the `warning: literal string will be frozen in the future` warnings appeared at Rails CI https://buildkite.com/rails/rails-nightly/builds/1122#019263a3-2200-4e62-a6a8-028cffa60aaf Here are the warnings appeared: ``` /usr/local/lib/ruby/gems/3.4.0+0/bundler/gems/httpclient-d57cc6d5ffee/lib/httpclient.rb:1256: warning: literal string will be frozen in the future /usr/local/lib/ruby/gems/3.4.0+0/bundler/gems/httpclient-d57cc6d5ffee/lib/httpclient/http.rb:580: warning: literal string will be frozen in the future /usr/local/lib/ruby/gems/3.4.0+0/bundler/gems/httpclient-d57cc6d5ffee/lib/httpclient/session.rb:954: warning: literal string will be frozen in the future /usr/local/lib/ruby/gems/3.4.0+0/bundler/gems/httpclient-d57cc6d5ffee/lib/httpclient/util.rb:71: warning: literal string will be frozen in the future ``` There should be some warnings remained because Rails CI does not use all of httpclient code. I'll open some pull requests later to address remaining ones. Ref: https://bugs.ruby-lang.org/issues/20205 --- lib/httpclient.rb | 2 +- lib/httpclient/http.rb | 2 +- lib/httpclient/session.rb | 2 +- lib/httpclient/util.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/httpclient.rb b/lib/httpclient.rb index e1f18647..e844909c 100644 --- a/lib/httpclient.rb +++ b/lib/httpclient.rb @@ -1240,7 +1240,7 @@ def do_get_block(req, proxy, conn, &block) conn.push(res) return res end - content = block ? nil : '' + content = block ? nil : ''.dup res = HTTP::Message.new_response(content, req.header) @debug_dev << "= Request\n\n" if @debug_dev sess = @session_manager.query(req, proxy) diff --git a/lib/httpclient/http.rb b/lib/httpclient/http.rb index f6a86079..0fdedb57 100644 --- a/lib/httpclient/http.rb +++ b/lib/httpclient/http.rb @@ -574,7 +574,7 @@ def reset_pos(io) end def dump_file(io, dev, sz) - buf = '' + buf = ''.dup rest = sz while rest > 0 n = io.read([rest, @chunk_size].min, buf) diff --git a/lib/httpclient/session.rb b/lib/httpclient/session.rb index 67e2c3ba..8cb09d4d 100644 --- a/lib/httpclient/session.rb +++ b/lib/httpclient/session.rb @@ -950,7 +950,7 @@ def read_body_rest end def empty_bin_str - str = '' + str = ''.dup str.force_encoding('BINARY') if str.respond_to?(:force_encoding) str end diff --git a/lib/httpclient/util.rb b/lib/httpclient/util.rb index 6ff38016..9b93035d 100644 --- a/lib/httpclient/util.rb +++ b/lib/httpclient/util.rb @@ -64,7 +64,7 @@ class AddressableURI < Addressable::URI # Overwrites the original definition just for one line... def authority self.host && @authority ||= (begin - authority = "" + authority = "".dup if self.userinfo != nil authority << "#{self.userinfo}@" end From 06070a4f4431758c64ba6d57cbc520bad3ee4d49 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Tue, 18 Feb 2025 09:33:33 +0100 Subject: [PATCH 2/2] Test with --enable-frozen-string-literal on CI --- .github/workflows/test.yml | 8 ++-- Gemfile | 6 ++- bench/download.cgi | 2 +- lib/hexdump.rb | 24 +++++----- lib/httpclient/http.rb | 10 ++-- test/test_auth.rb | 30 ++++++------ test/test_hexdump.rb | 3 +- test/test_http-access2.rb | 40 ++++++++-------- test/test_httpclient.rb | 96 +++++++++++++++++++------------------- test/test_ssl.rb | 4 +- 10 files changed, 113 insertions(+), 110 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a80cff28..9f91e34f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -24,6 +24,10 @@ jobs: '3.4', 'head' ] + ruby-opt: [""] + include: + - ruby-version: '3.4' + ruby-opt: '--enable-frozen-string-literal --debug-frozen-string-literal' steps: - uses: actions/checkout@v3 @@ -34,6 +38,4 @@ jobs: bundler-cache: true cache-version: 2 - name: Run tests - run: bundle exec rake --trace - env: - RUBYOPT: "--disable-frozen-string-literal" # Silence these warnings for now. + run: bundle exec rake --trace RUBYOPT="${{ matrix.ruby-opt }}" diff --git a/Gemfile b/Gemfile index 3be97021..8bac1761 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,11 @@ group :development do gem 'pry' gem 'rack', '~> 2.2' gem 'rubysspi' - gem 'rubyntlm' + if RUBY_VERSION >= '3.2' + gem 'rubyntlm', github: 'https://github.com/WinRb/rubyntlm/pull/64' + else + gem 'rubyntlm' + end gem 'base64' gem 'rack-ntlm-test-service' gem 'logger' diff --git a/bench/download.cgi b/bench/download.cgi index 359b8b0c..6726fcc0 100755 --- a/bench/download.cgi +++ b/bench/download.cgi @@ -15,7 +15,7 @@ end buf_size = 1024 * 16 STDOUT.sync = true File.open(File.expand_path('10M.bin', File.dirname(__FILE__))) do |file| - buf = '' + buf = ''.dup while !file.read(buf_size, buf).nil? print dump_chunk(buf) end diff --git a/lib/hexdump.rb b/lib/hexdump.rb index 4cd006f3..56f3e146 100644 --- a/lib/hexdump.rb +++ b/lib/hexdump.rb @@ -11,13 +11,13 @@ def encode(str) result = [] while raw = str.slice(offset, 16) and raw.length > 0 # data field - data = '' + data = ''.dup for v in raw.unpack('N* a*') - if v.kind_of? Integer - data << sprintf("%08x ", v) - else - v.each_byte {|c| data << sprintf("%02x", c) } - end + if v.kind_of? Integer + data << sprintf("%08x ", v) + else + v.each_byte {|c| data << sprintf("%02x", c) } + end end # text field text = raw.tr("\000-\037\177-\377", ".") @@ -25,12 +25,12 @@ def encode(str) offset += 16 # omit duplicate line if /^(#{regex_quote_n(raw)})+/n =~ str[offset .. -1] - result << sprintf("%08x ...", offset) - offset += $&.length - # should print at the end - if offset == str.length - result << sprintf("%08x %-36s %s", offset-16, data, text) - end + result << sprintf("%08x ...", offset) + offset += $&.length + # should print at the end + if offset == str.length + result << sprintf("%08x %-36s %s", offset-16, data, text) + end end end result diff --git a/lib/httpclient/http.rb b/lib/httpclient/http.rb index 0fdedb57..543249b3 100644 --- a/lib/httpclient/http.rb +++ b/lib/httpclient/http.rb @@ -238,7 +238,7 @@ def content_type=(content_type) if defined?(Encoding::ASCII_8BIT) def set_body_encoding if type = self.content_type - OpenURI::Meta.init(o = '') + OpenURI::Meta.init(o = ''.dup) o.meta_add_field('content-type', type) @body_encoding = o.encoding end @@ -491,7 +491,7 @@ def init_response(body = nil) # String. # # assert: @size is not nil - def dump(header = '', dev = '') + def dump(header = '', dev = ''.dup) if @body.is_a?(Parts) dev << header @body.parts.each do |part| @@ -521,7 +521,7 @@ def dump(header = '', dev = '') # reason. (header is dumped to dev, too) # If no dev (the second argument) given, this method returns a dumped # String. - def dump_chunked(header = '', dev = '') + def dump_chunked(header = '', dev = ''.dup) dev << header if @body.is_a?(Parts) @body.parts.each do |part| @@ -585,7 +585,7 @@ def dump_file(io, dev, sz) end def dump_chunks(io, dev) - buf = '' + buf = ''.dup while !io.read(@chunk_size, buf).nil? dev << dump_chunk(buf) end @@ -954,7 +954,7 @@ def initialize # :nodoc: # Dumps message (header and body) to given dev. # dev needs to respond to <<. - def dump(dev = '') + def dump(dev = ''.dup) str = @http_header.dump + CRLF if @http_header.chunked dev = @http_body.dump_chunked(str, dev) diff --git a/test/test_auth.rb b/test/test_auth.rb index 13b329f3..95c17188 100644 --- a/test/test_auth.rb +++ b/test/test_auth.rb @@ -180,7 +180,7 @@ def test_BASIC_auth_force c.www_auth.basic_auth.instance_eval { @scheme = "BASIC" } # c.force_basic_auth = true - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.set_auth("http://localhost:#{serverport}/", 'admin', 'admin') assert_equal('basic_auth OK', c.get_content("http://localhost:#{serverport}/basic_auth")) assert_equal('Authorization: Basic YWRtaW46YWRtaW4='.upcase, str.split(/\r?\n/)[5].upcase) @@ -253,7 +253,7 @@ def test_basic_auth_reuses_credentials c.set_auth("http://localhost:#{serverport}/", 'admin', 'admin') assert_equal('basic_auth OK', c.get_content("http://localhost:#{serverport}/basic_auth/")) c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content("http://localhost:#{serverport}/basic_auth/sub/dir/") assert_match(/Authorization: Basic YWRtaW46YWRtaW4=/, str) end @@ -269,7 +269,7 @@ def test_digest_auth_reuses_credentials c.set_auth("http://localhost:#{serverport}/", 'admin', 'admin') assert_equal('digest_auth OK', c.get_content("http://localhost:#{serverport}/digest_auth/")) c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content("http://localhost:#{serverport}/digest_auth/sub/dir/") assert_match(/Authorization: Digest/, str) end @@ -315,7 +315,7 @@ def test_perfer_digest c.set_auth('http://example.com/', 'admin', 'admin') c.test_loopback_http_response << "HTTP/1.0 401 Unauthorized\nWWW-Authenticate: Basic realm=\"foo\"\nWWW-Authenticate: Digest realm=\"foo\", nonce=\"nonce\", stale=false\nContent-Length: 2\n\nNG" c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://example.com/') assert_match(/^Authorization: Digest/, str) end @@ -331,7 +331,7 @@ def test_proxy_auth c.set_proxy_auth('admin', 'admin') c.test_loopback_http_response << "HTTP/1.0 407 Unauthorized\nProxy-Authenticate: Basic realm=\"foo\"\nContent-Length: 2\n\nNG" c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://example.com/') assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str) end @@ -341,7 +341,7 @@ def test_proxy_auth_force c.set_proxy_auth('admin', 'admin') c.force_basic_auth = true c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://example.com/') assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str) end @@ -353,7 +353,7 @@ def test_proxy_auth_reuses_credentials c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" c.get_content('http://www1.example.com/') - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://www2.example.com/') assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str) end @@ -367,7 +367,7 @@ def test_digest_proxy_auth_loop ha1 = md5.hexdigest("admin:foo:admin") ha2 = md5.hexdigest("GET:/") response = md5.hexdigest("#{ha1}:nonce:#{ha2}") - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://example.com/') assert_match(/Proxy-Authorization: Digest/, str) assert_match(%r"response=\"#{response}\"", str) @@ -398,7 +398,7 @@ def test_prefer_digest_to_basic_proxy_auth ha1 = md5.hexdigest("admin:foo:admin") ha2 = md5.hexdigest("GET:/") response = md5.hexdigest("#{ha1}:nonce:#{ha2}") - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://example.com/') assert_match(/Proxy-Authorization: Digest/, str) assert_match(%r"response=\"#{response}\"", str) @@ -415,7 +415,7 @@ def test_digest_proxy_auth_reuses_credentials ha2 = md5.hexdigest("GET:/") response = md5.hexdigest("#{ha1}:nonce:#{ha2}") c.get_content('http://www1.example.com/') - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://www2.example.com/') assert_match(/Proxy-Authorization: Digest/, str) assert_match(%r"response=\"#{response}\"", str) @@ -437,19 +437,19 @@ def test_oauth c.www_auth.oauth.set_config('http://photos.example.net/', config) c.www_auth.oauth.challenge('http://photos.example.net/') c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://photos.example.net/photos', [[:file, 'vacation.jpg'], [:size, 'original']]) assert(str.index(%q(GET /photos?file=vacation.jpg&size=original))) assert(str.index(%q(Authorization: OAuth realm="http://photos.example.net/", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="kllo9940pd9333jh", oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d00sl2jdk", oauth_version="1.0"))) # c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get_content('http://photos.example.net/photos?file=vacation.jpg&size=original') assert(str.index(%q(GET /photos?file=vacation.jpg&size=original))) assert(str.index(%q(Authorization: OAuth realm="http://photos.example.net/", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="kllo9940pd9333jh", oauth_signature="tR3%2BTy81lMeYAr%2FFid0kMTYa%2FWM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d00sl2jdk", oauth_version="1.0"))) # c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK" - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.post_content('http://photos.example.net/photos', [[:file, 'vacation.jpg'], [:size, 'original']]) assert(str.index(%q(POST /photos))) assert(str.index(%q(Authorization: OAuth realm="http://photos.example.net/", oauth_consumer_key="dpf43f3p2l4k3l03", oauth_nonce="kllo9940pd9333jh", oauth_signature="wPkvxykrw%2BBTdCcGqKr%2B3I%2BPsiM%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp="1191242096", oauth_token="nnch734d00sl2jdk", oauth_version="1.0"))) @@ -479,7 +479,7 @@ def test_negotiate_and_basic c.test_loopback_http_response << %Q(HTTP/1.1 401 Unauthorized\r\nWWW-Authenticate: NTLM TlRMTVNTUAACAAAAAAAAACgAAAABAAAAAAAAAAAAAAA=\r\nConnection: Keep-Alive\r\nContent-Length: 0\r\n\r\n) c.test_loopback_http_response << %Q(HTTP/1.0 200 OK\r\nConnection: Keep-Alive\r\nContent-Length: 1\r\n\r\na) c.test_loopback_http_response << %Q(HTTP/1.0 200 OK\r\nConnection: Keep-Alive\r\nContent-Length: 1\r\n\r\nb) - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.set_auth('http://www.example.org/', 'admin', 'admin') # Do NTLM negotiation c.get('http://www.example.org/foo') @@ -488,7 +488,7 @@ def test_negotiate_and_basic assert_match(%r(Authorization: NTLM), str) assert_not_match(%r(Authorization: Basic), str) # ditto for other resource that is protected with NTLM - c.debug_dev = str = '' + c.debug_dev = str = ''.dup c.get('http://www.example.org/foo/subdir') assert_not_match(%r(Authorization: NTLM), str) assert_not_match(%r(Authorization: Basic), str) diff --git a/test/test_hexdump.rb b/test/test_hexdump.rb index 7e4c5649..091b167a 100644 --- a/test/test_hexdump.rb +++ b/test/test_hexdump.rb @@ -5,8 +5,7 @@ class TestHexDump < Test::Unit::TestCase def test_encode - str = "\032l\277\370\2429\216\236\351[{\{\262\350\274\376" - str.force_encoding('BINARY') if str.respond_to?(:force_encoding) + str = "\032l\277\370\2429\216\236\351[{\{\262\350\274\376".b assert_equal(["00000000 1a6cbff8 a2398e9e e95b7b7b b2e8bcfe .l...9...[{{...."], HexDump.encode(str)) end end if defined?(RUBY_ENGINE) && RUBY_ENGINE != "rbx" && RUBY_VERSION >= "1.9.0" diff --git a/test/test_http-access2.rb b/test/test_http-access2.rb index 05fae3f4..b7ac6d18 100644 --- a/test/test_http-access2.rb +++ b/test/test_http-access2.rb @@ -24,7 +24,7 @@ def teardown def test_initialize setup_proxyserver escape_noproxy do - @proxyio.string = "" + @proxyio.truncate(0) @client = HTTPAccess2::Client.new(proxyurl) assert_equal(urify(proxyurl), @client.proxy) assert_equal(200, @client.head(serverurl).status) @@ -34,7 +34,7 @@ def test_initialize def test_agent_name @client = HTTPAccess2::Client.new(nil, "agent_name_foo") - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -44,7 +44,7 @@ def test_agent_name def test_from @client = HTTPAccess2::Client.new(nil, nil, "from_bar") - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -53,7 +53,7 @@ def test_from end def test_debug_dev - str = "" + str = "".dup @client.debug_dev = str assert(str.empty?) @client.get(serverurl) @@ -62,7 +62,7 @@ def test_debug_dev def _test_protocol_version_http09 @client.protocol_version = 'HTTP/0.9' - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl + 'hello') lines = str.split(/(?:\r?\n)+/) @@ -76,7 +76,7 @@ def _test_protocol_version_http09 def test_protocol_version_http10 @client.protocol_version = 'HTTP/1.0' - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl + 'hello') lines = str.split(/(?:\r?\n)+/) @@ -88,7 +88,7 @@ def test_protocol_version_http10 end def test_protocol_version_http11 - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -97,7 +97,7 @@ def test_protocol_version_http11 assert_equal("GET / HTTP/1.1", lines[3]) assert_equal("Host: localhost:#{serverport}", lines[7]) @client.protocol_version = 'HTTP/1.1' - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -105,7 +105,7 @@ def test_protocol_version_http11 assert_equal("! CONNECTION ESTABLISHED", lines[2]) assert_equal("GET / HTTP/1.1", lines[3]) @client.protocol_version = 'HTTP/1.0' - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -130,12 +130,12 @@ def test_proxy @client.proxy = uri assert_equal(uri, @client.proxy) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = nil assert_equal(200, @client.head(serverurl).status) assert(@proxyio.string.empty?) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(!@proxyio.string.empty?) @@ -143,7 +143,7 @@ def test_proxy end def test_noproxy_for_localhost - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(@proxyio.string.empty?) @@ -154,36 +154,36 @@ def test_no_proxy escape_noproxy do # proxy is not set. @client.no_proxy = 'localhost' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = nil assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # @client.no_proxy = 'foobar' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ =~ @proxyio.string) # @client.no_proxy = 'foobar,localhost:baz' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # @client.no_proxy = 'foobar,localhost:443' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ =~ @proxyio.string) # @client.no_proxy = "foobar,localhost:443:localhost:#{serverport},baz" - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) @@ -314,14 +314,14 @@ def test_post_body end def test_extra_headers - str = "" + str = "".dup @client.debug_dev = str @client.head(serverurl, nil, {"ABC" => "DEF"}) lines = str.split(/(?:\r?\n)+/) assert_equal("= Request", lines[0]) assert_match("ABC: DEF", lines[4]) # - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl, nil, [["ABC", "DEF"], ["ABC", "DEF"]]) lines = str.split(/(?:\r?\n)+/) diff --git a/test/test_httpclient.rb b/test/test_httpclient.rb index 8a595651..74406ef2 100644 --- a/test/test_httpclient.rb +++ b/test/test_httpclient.rb @@ -20,7 +20,7 @@ def teardown def test_initialize setup_proxyserver escape_noproxy do - @proxyio.string = "" + @proxyio.truncate(0) @client = HTTPClient.new(proxyurl) assert_equal(urify(proxyurl), @client.proxy) assert_equal(200, @client.head(serverurl).status) @@ -30,7 +30,7 @@ def test_initialize def test_agent_name @client = HTTPClient.new(nil, "agent_name_foo") - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -40,7 +40,7 @@ def test_agent_name def test_from @client = HTTPClient.new(nil, nil, "from_bar") - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -49,7 +49,7 @@ def test_from end def test_debug_dev - str = "" + str = "".dup @client.debug_dev = str assert_equal(str.object_id, @client.debug_dev.object_id) assert(str.empty?) @@ -58,7 +58,7 @@ def test_debug_dev end def test_debug_dev_stream - str = "" + str = "".dup @client.debug_dev = str conn = @client.get_async(serverurl) Thread.pass while !conn.finished? @@ -67,7 +67,7 @@ def test_debug_dev_stream def test_protocol_version_http09 @client.protocol_version = 'HTTP/0.9' - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup @client.test_loopback_http_response << "hello\nworld\n" res = @client.get(serverurl + 'hello') assert_equal('0.9', res.http_version) @@ -88,7 +88,7 @@ def test_protocol_version_http10 assert_equal(nil, @client.protocol_version) @client.protocol_version = 'HTTP/1.0' assert_equal('HTTP/1.0', @client.protocol_version) - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl + 'hello') lines = str.split(/(?:\r?\n)+/) @@ -100,7 +100,7 @@ def test_protocol_version_http10 end def test_header_accept_by_default - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -108,7 +108,7 @@ def test_header_accept_by_default end def test_header_accept - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl, :header => {:Accept => 'text/html'}) lines = str.split(/(?:\r?\n)+/) @@ -116,7 +116,7 @@ def test_header_accept end def test_header_symbol - str = "" + str = "".dup @client.debug_dev = str @client.post(serverurl + 'servlet', :header => {:'Content-Type' => 'application/json'}, :body => 'hello') lines = str.split(/(?:\r?\n)+/).grep(/^Content-Type/) @@ -124,7 +124,7 @@ def test_header_symbol end def test_host_given - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -134,7 +134,7 @@ def test_host_given assert_equal("Host: localhost:#{serverport}", lines[7]) # @client.reset_all - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl, nil, {'Host' => 'foo'}) lines = str.split(/(?:\r?\n)+/) @@ -166,7 +166,7 @@ def test_redirect_without_location_should_gracefully_fail def test_protocol_version_http11 assert_equal(nil, @client.protocol_version) - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -176,7 +176,7 @@ def test_protocol_version_http11 assert_equal("Host: localhost:#{serverport}", lines[7]) @client.protocol_version = 'HTTP/1.1' assert_equal('HTTP/1.1', @client.protocol_version) - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -184,7 +184,7 @@ def test_protocol_version_http11 assert_equal("! CONNECTION ESTABLISHED", lines[2]) assert_equal("GET / HTTP/1.1", lines[3]) @client.protocol_version = 'HTTP/1.0' - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl) lines = str.split(/(?:\r?\n)+/) @@ -209,14 +209,14 @@ def test_proxy @client.proxy = uri assert_equal(uri, @client.proxy) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = nil assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup assert_equal(200, @client.head(serverurl).status) assert(/accept/ =~ @proxyio.string) assert(/Host: localhost:#{serverport}/ =~ str) @@ -225,13 +225,13 @@ def test_proxy def test_host_header @client.proxy = proxyurl - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" assert_equal(200, @client.head('http://www.example.com/foo').status) # ensure no ':80' is added. some servers dislike that. assert(/\r\nHost: www\.example\.com\r\n/ =~ str) # - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" assert_equal(200, @client.head('http://www.example.com:12345/foo').status) # ensure ':12345' exists. @@ -273,7 +273,7 @@ def test_empty_proxy_env end def test_noproxy_for_localhost - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) @@ -286,36 +286,36 @@ def test_no_proxy assert_equal(nil, @client.no_proxy) @client.no_proxy = 'localhost' assert_equal('localhost', @client.no_proxy) - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = nil assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # @client.no_proxy = 'foobar' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ =~ @proxyio.string) # @client.no_proxy = 'foobar,localhost:baz' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) # @client.no_proxy = 'foobar,localhost:443' - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ =~ @proxyio.string) # @client.no_proxy = "foobar,localhost:443:localhost:#{serverport},baz" - @proxyio.string = "" + @proxyio.truncate(0) @client.proxy = proxyurl assert_equal(200, @client.head(serverurl).status) assert(/accept/ !~ @proxyio.string) @@ -323,28 +323,28 @@ def test_no_proxy end def test_no_proxy_with_initial_dot - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" @client.no_proxy = '' @client.proxy = proxyurl @client.head('http://www.foo.com') assert(/CONNECT TO localhost/ =~ str, 'via proxy') # - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" @client.no_proxy = '.foo.com' @client.proxy = proxyurl @client.head('http://www.foo.com') assert(/CONNECT TO www.foo.com/ =~ str, 'no proxy because .foo.com matches with www.foo.com') # - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" @client.no_proxy = '.foo.com' @client.proxy = proxyurl @client.head('http://foo.com') assert(/CONNECT TO localhost/ =~ str, 'via proxy because .foo.com does not matche with foo.com') # - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup @client.test_loopback_http_response << "HTTP/1.0 200 OK\r\n\r\n" @client.no_proxy = 'foo.com' @client.proxy = proxyurl @@ -370,7 +370,7 @@ def test_cookie_update_while_authentication \r hello EOS - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup @client.set_auth("http://www.example.org/baz/", 'admin', 'admin') assert_equal('hello', @client.get('http://www.example.org/baz/foo').content) assert_match(/^Cookie: foo=bar/, str) @@ -411,7 +411,7 @@ def test_loopback_response assert_equal('message body 1', @client.get_content('http://somewhere')) assert_equal('message body 2', @client.get_content('http://somewhere')) # - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup @client.test_loopback_response << 'message body 3' assert_equal('message body 3', @client.get_content('http://somewhere')) assert_match(/message body 3/, str) @@ -597,12 +597,10 @@ def test_get_content_with_base_url assert(called) end - GZIP_CONTENT = "\x1f\x8b\x08\x00\x1a\x96\xe0\x4c\x00\x03\xcb\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36\x05\x00\x00\x00" - DEFLATE_CONTENT = "\x78\x9c\xcb\x48\xcd\xc9\xc9\x07\x00\x06\x2c\x02\x15" - DEFLATE_NOHEADER_CONTENT = "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15" - [GZIP_CONTENT, DEFLATE_CONTENT, DEFLATE_NOHEADER_CONTENT].each do |content| - content.force_encoding('BINARY') if content.respond_to?(:force_encoding) - end + GZIP_CONTENT = "\x1f\x8b\x08\x00\x1a\x96\xe0\x4c\x00\x03\xcb\x48\xcd\xc9\xc9\x07\x00\x86\xa6\x10\x36\x05\x00\x00\x00".b + DEFLATE_CONTENT = "\x78\x9c\xcb\x48\xcd\xc9\xc9\x07\x00\x06\x2c\x02\x15".b + DEFLATE_NOHEADER_CONTENT = "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15".b + def test_get_gzipped_content @client.transparent_gzip_decompression = false content = @client.get_content(serverurl + 'compressed?enc=gzip') @@ -867,7 +865,7 @@ def test_post end def test_post_empty - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup # nil body means 'no content' that is allowed but WEBrick cannot handle it. @client.post(serverurl + 'servlet', :body => nil) # request does not have 'Content-Type' @@ -1092,7 +1090,7 @@ def file.original_filename def test_patch assert_equal("patch", @client.patch(serverurl + 'servlet', '').content) param = {'1'=>'2', '3'=>'4'} - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup res = @client.patch(serverurl + 'servlet', param) assert_equal(param, params(res.header["x-query"][0])) assert_equal('Content-Type: application/x-www-form-urlencoded', str.split(/\r?\n/)[5]) @@ -1122,7 +1120,7 @@ def test_patch_async def test_put assert_equal("put", @client.put(serverurl + 'servlet', '').content) param = {'1'=>'2', '3'=>'4'} - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup res = @client.put(serverurl + 'servlet', param) assert_equal(param, params(res.header["x-query"][0])) assert_equal('Content-Type: application/x-www-form-urlencoded', str.split(/\r?\n/)[5]) @@ -1169,7 +1167,7 @@ def test_delete_with_query_and_body # Not prohibited by spec, but normally it's ignored def test_delete_with_body param = {'1'=>'2', '3'=>'4'} - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup assert_equal("delete", @client.delete(serverurl + 'servlet', param).content) assert_equal({'1' => ['2'], '3' => ['4']}, HTTP::Message.parse(str.split(/\r?\n\r?\n/)[2])) end @@ -1309,14 +1307,14 @@ def test_post_body end def test_extra_headers - str = "" + str = "".dup @client.debug_dev = str @client.head(serverurl, nil, {"ABC" => "DEF"}) lines = str.split(/(?:\r?\n)+/) assert_equal("= Request", lines[0]) assert_match("ABC: DEF", lines[4]) # - str = "" + str = "".dup @client.debug_dev = str @client.get(serverurl, nil, [["ABC", "DEF"], ["ABC", "DEF"]]) lines = str.split(/(?:\r?\n)+/) @@ -1326,7 +1324,7 @@ def test_extra_headers end def test_http_custom_date_header - @client.debug_dev = (str = "") + @client.debug_dev = (str = "".dup) _res = @client.get(serverurl + 'hello', :header => {'Date' => 'foo'}) lines = str.split(/(?:\r?\n)+/) assert_equal('Date: foo', lines[4]) @@ -1419,7 +1417,7 @@ def test_cookies def test_eof_error_length io = StringIO.new('') def io.gets(*arg) - @buf ||= ["HTTP/1.0 200 OK\n", "content-length: 123\n", "\n"] + @buf ||= ["HTTP/1.0 200 OK\n".dup, "content-length: 123\n".dup, "\n".dup] @buf.shift end def io.readpartial(size, buf) @@ -1447,7 +1445,7 @@ def io.eof? def test_eof_error_rest io = StringIO.new('') def io.gets(*arg) - @buf ||= ["HTTP/1.0 200 OK\n", "\n"] + @buf ||= ["HTTP/1.0 200 OK\n".dup, "\n".dup] @buf.shift end def io.readpartial(size, buf) @@ -1871,7 +1869,7 @@ def test_charset if RUBY_VERSION >= "1.9.3" def test_continue - @client.debug_dev = str = '' + @client.debug_dev = str = ''.dup res = @client.get(serverurl + 'continue', :header => {:Expect => '100-continue'}) assert_equal(200, res.status) assert_equal('done!', res.body) diff --git a/test/test_ssl.rb b/test/test_ssl.rb index 650d03af..1ec52c04 100644 --- a/test/test_ssl.rb +++ b/test/test_ssl.rb @@ -38,7 +38,7 @@ def test_proxy_ssl @client.ssl_config.set_client_cert_file(path('client.cert'), path('client.key')) @client.ssl_config.add_trust_ca(path('ca.cert')) @client.ssl_config.add_trust_ca(path('subca.cert')) - @client.debug_dev = str = "" + @client.debug_dev = str = "".dup assert_equal(200, @client.get(@url).status) assert(/accept/ =~ @proxyio.string, 'proxy is not used') assert(/Host: localhost:#{serverport}/ =~ str) @@ -77,7 +77,7 @@ def test_sync end def test_debug_dev - str = @client.debug_dev = '' + str = @client.debug_dev = ''.dup cfg = @client.ssl_config cfg.client_cert = path("client.cert") cfg.client_key = path("client.key")