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)
27 27
    raise ArgumentError, "HTTP request path is empty" if path.empty?
28 28
    @path = path
29 29

  
30
    @decode_content = false
31

  
30 32
    if @response_has_body and Net::HTTP::HAVE_ZLIB then
31 33
      if !initheader ||
32 34
         !initheader.keys.any? { |k|
33 35
           %w[accept-encoding range].include? k.downcase
34 36
         } then
37
        @decode_content = true
35 38
        initheader = initheader ? initheader.dup : {}
36 39
        initheader["accept-encoding"] =
37 40
          "gzip;q=1.0,deflate;q=0.6,identity;q=0.3"
......
51 54
  attr_reader :path
52 55
  attr_reader :uri
53 56

  
57
  # Automatically set to false if the user sets the Accept-Encoding header.
58
  # This indicates they wish to handle Content-encoding in responses
59
  # themselves.
60
  attr_reader :decode_content
61

  
54 62
  def inspect
55 63
    "\#<#{self.class} #{@method}>"
56 64
  end
57 65

  
66
  ##
67
  # Don't automatically decode response content-encoding if the user indicates
68
  # they want to handle it.
69

  
70
  def []=(key, val) # :nodoc:
71
    @decode_content = false if key.downcase == 'accept-encoding'
72

  
73
    super key, val
74
  end
75

  
58 76
  def request_body_permitted?
59 77
    @request_has_body
60 78
  end
......
291 309
      if IO.select([sock.io], nil, nil, sock.continue_timeout)
292 310
        res = Net::HTTPResponse.read_new(sock)
293 311
        unless res.kind_of?(Net::HTTPContinue)
312
          res.decode_content = @decode_content
294 313
          throw :response, res
295 314
        end
296 315
      end
lib/net/http/response.rb (working copy)
80 80
    @body = nil
81 81
    @read = false
82 82
    @uri  = nil
83
    @decode_content = false
83 84
  end
84 85

  
85 86
  # The HTTP version supported by the server.
......
98 99
  # if a URI was used to create the request.
99 100
  attr_reader :uri
100 101

  
102
  # Set to true automatically when the request did not contain an
103
  # Accept-Encoding header from the user.
104
  attr_accessor :decode_content
105

  
101 106
  def inspect
102 107
    "#<#{self.class} #{@code} #{@message} readbody=#{@read}>"
103 108
  end
......
242 247

  
243 248
  def inflater # :nodoc:
244 249
    return yield @socket unless Net::HTTP::HAVE_ZLIB
250
    return yield @socket unless @decode_content
245 251
    return yield @socket if self['content-range']
246 252

  
247 253
    case self['content-encoding']
lib/net/http.rb (working copy)
1410 1410
          req.exec @socket, @curr_http_version, edit_path(req.path)
1411 1411
          begin
1412 1412
            res = HTTPResponse.read_new(@socket)
1413
            res.decode_content = req.decode_content
1413 1414
          end while res.kind_of?(HTTPContinue)
1414 1415

  
1415 1416
          res.uri = req.uri
test/net/http/test_http.rb (working copy)
419 419
  def test_request
420 420
    start {|http|
421 421
      _test_request__GET http
422
      _test_request__accept_encoding http
422 423
      _test_request__file http
423 424
      # _test_request__range http   # WEBrick does not support Range: header.
424 425
      _test_request__HEAD http
......
440 441
      end
441 442
      assert_equal $test_net_http_data.size, res.body.size
442 443
      assert_equal $test_net_http_data, res.body
444

  
445
      assert res.decode_content, 'Bug #7831'
446
    }
447
  end
448

  
449
  def _test_request__accept_encoding(http)
450
    req = Net::HTTP::Get.new('/', 'accept-encoding' => 'deflate')
451
    http.request(req) {|res|
452
      assert_kind_of Net::HTTPResponse, res
453
      assert_kind_of String, res.body
454
      unless self.is_a?(TestNetHTTP_v1_2_chunked)
455
        assert_not_nil res['content-length']
456
        assert_equal $test_net_http_data.size, res['content-length'].to_i
457
      end
458
      assert_equal $test_net_http_data.size, res.body.size
459
      assert_equal $test_net_http_data, res.body
460

  
461
      refute res.decode_content, 'Bug #7831'
443 462
    }
444 463
  end
445 464

  
test/net/http/test_http_request.rb (working copy)
53 53
    assert_equal expected, req.to_hash
54 54
  end
55 55

  
56
  def test_initialize_accept_encoding
57
    req1 = Net::HTTP::Get.new '/'
58

  
59
    assert req1.decode_content, 'Bug #7831 - automatically decode content'
60

  
61
    req2 = Net::HTTP::Get.new '/', 'accept-encoding' => 'identity'
62

  
63
    refute req2.decode_content,
64
           'Bug #7381 - do not decode content if the user overrides'
65
  end
66

  
67
  def test_header_set
68
    req = Net::HTTP::Get.new '/'
69

  
70
    assert req.decode_content, 'Bug #7831 - automatically decode content'
71

  
72
    req['accept-encoding'] = 'identity'
73

  
74
    refute req.decode_content,
75
           'Bug #7831 - do not decode content if the user overrides'
76
  end
77

  
56 78
end
57 79

  
test/net/http/test_httpresponse.rb (working copy)
86 86
EOS
87 87

  
88 88
    res = Net::HTTPResponse.read_new(io)
89
    res.decode_content = true
89 90

  
90 91
    body = nil
91 92

  
......
118 119
EOS
119 120

  
120 121
    res = Net::HTTPResponse.read_new(io)
122
    res.decode_content = true
121 123

  
122 124
    body = nil
123 125

  
......
134 136
    end
135 137
  end
136 138

  
139
  def test_read_body_content_encoding_deflate_disabled
140
    io = dummy_io(<<EOS)
141
HTTP/1.1 200 OK
142
Connection: close
143
Content-Encoding: deflate
144
Content-Length: 13
145

  
146
x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15
147
EOS
148

  
149
    res = Net::HTTPResponse.read_new(io)
150
    res.decode_content = false # user set accept-encoding in request
151

  
152
    body = nil
153

  
154
    res.reading_body io, true do
155
      body = res.read_body
156
    end
157

  
158
    assert_equal 'deflate', res['content-encoding'], 'Bug #7831'
159
    assert_equal "x\x9C\xCBH\xCD\xC9\xC9\a\x00\x06,\x02\x15", body, 'Bug #7381'
160
  end
161

  
137 162
  def test_read_body_content_encoding_deflate_no_length
138 163
    io = dummy_io(<<EOS)
139 164
HTTP/1.1 200 OK
......
144 169
EOS
145 170

  
146 171
    res = Net::HTTPResponse.read_new(io)
172
    res.decode_content = true
147 173

  
148 174
    body = nil
149 175