Project

General

Profile

Backport #7831 ยป net.http.user_handled_content_encoding.patch

Patch to allow users to control content-encoding - drbrain (Eric Hodel), 02/12/2013 09:10 AM

View differences:

lib/net/http/generic_request.rb (working copy)
raise ArgumentError, "HTTP request path is empty" if path.empty?
@path = path
@decode_content = false
if @response_has_body and Net::HTTP::HAVE_ZLIB then
if !initheader ||
!initheader.keys.any? { |k|
%w[accept-encoding range].include? k.downcase
} then
@decode_content = true
initheader = initheader ? initheader.dup : {}
initheader["accept-encoding"] =
"gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
......
attr_reader :path
attr_reader :uri
# Automatically set to false if the user sets the Accept-Encoding header.
# This indicates they wish to handle Content-encoding in responses
# themselves.
attr_reader :decode_content
def inspect
"\#<#{self.class} #{@method}>"
end
##
# Don't automatically decode response content-encoding if the user indicates
# they want to handle it.
def []=(key, val) # :nodoc:
@decode_content = false if key.downcase == 'accept-encoding'
super key, val
end
def request_body_permitted?
@request_has_body
end
......
if IO.select([sock.io], nil, nil, sock.continue_timeout)
res = Net::HTTPResponse.read_new(sock)
unless res.kind_of?(Net::HTTPContinue)
res.decode_content = @decode_content
throw :response, res
end
end
lib/net/http/response.rb (working copy)
@body = nil
@read = false
@uri = nil
@decode_content = false
end
# The HTTP version supported by the server.
......
# if a URI was used to create the request.
attr_reader :uri
# Set to true automatically when the request did not contain an
# Accept-Encoding header from the user.
attr_accessor :decode_content
def inspect
"#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
end
......
def inflater # :nodoc:
return yield @socket unless Net::HTTP::HAVE_ZLIB
return yield @socket unless @decode_content
return yield @socket if self['content-range']
case self['content-encoding']
lib/net/http.rb (working copy)
req.exec @socket, @curr_http_version, edit_path(req.path)
begin
res = HTTPResponse.read_new(@socket)
res.decode_content = req.decode_content
end while res.kind_of?(HTTPContinue)
res.uri = req.uri
test/net/http/test_http.rb (working copy)
def test_request
start {|http|
_test_request__GET http
_test_request__accept_encoding http
_test_request__file http
# _test_request__range http # WEBrick does not support Range: header.
_test_request__HEAD http
......
end
assert_equal $test_net_http_data.size, res.body.size
assert_equal $test_net_http_data, res.body
assert res.decode_content, 'Bug #7831'
}
end
def _test_request__accept_encoding(http)
req = Net::HTTP::Get.new('/', 'accept-encoding' => 'deflate')
http.request(req) {|res|
assert_kind_of Net::HTTPResponse, res
assert_kind_of String, res.body
unless self.is_a?(TestNetHTTP_v1_2_chunked)
assert_not_nil res['content-length']
assert_equal $test_net_http_data.size, res['content-length'].to_i
end
assert_equal $test_net_http_data.size, res.body.size
assert_equal $test_net_http_data, res.body
refute res.decode_content, 'Bug #7831'
}
end
test/net/http/test_http_request.rb (working copy)
assert_equal expected, req.to_hash
end
def test_initialize_accept_encoding
req1 = Net::HTTP::Get.new '/'
assert req1.decode_content, 'Bug #7831 - automatically decode content'
req2 = Net::HTTP::Get.new '/', 'accept-encoding' => 'identity'
refute req2.decode_content,
'Bug #7381 - do not decode content if the user overrides'
end
def test_header_set
req = Net::HTTP::Get.new '/'
assert req.decode_content, 'Bug #7831 - automatically decode content'
req['accept-encoding'] = 'identity'
refute req.decode_content,
'Bug #7831 - do not decode content if the user overrides'
end
end
test/net/http/test_httpresponse.rb (working copy)
EOS
res = Net::HTTPResponse.read_new(io)
res.decode_content = true
body = nil
......
EOS
res = Net::HTTPResponse.read_new(io)
res.decode_content = true
body = nil
......
end
end
def test_read_body_content_encoding_deflate_disabled
io = dummy_io(<<EOS)
HTTP/1.1 200 OK
Connection: close
Content-Encoding: deflate
Content-Length: 13
x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15
EOS
res = Net::HTTPResponse.read_new(io)
res.decode_content = false # user set accept-encoding in request
body = nil
res.reading_body io, true do
body = res.read_body
end
assert_equal 'deflate', res['content-encoding'], 'Bug #7831'
assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body, 'Bug #7381'
end
def test_read_body_content_encoding_deflate_no_length
io = dummy_io(<<EOS)
HTTP/1.1 200 OK
......
EOS
res = Net::HTTPResponse.read_new(io)
res.decode_content = true
body = nil
    (1-1/1)