Bug #21786
Updated by Eregon (Benoit Daloze) 2 days ago
When response_body_encoding is set to a String value (e.g., 'UTF-8'), and the HTTP response body is nil due to network failures, read_body attempts to call force_encoding on nil at line 360, raising NoMethodError. The issue occurs because String values fall through to the else branch which calls detect_encoding(@body) without checking if @body is nil. Line 360 should verify @body is not nil before calling force_encoding. Category: lib Target version:current Reproducible script: ```ruby require 'net/http' # Monkey patch to simulate nil body scenario class Net::HTTP::Response alias_method :original_reading_body, :reading_body def reading_body(sock, reqmethodallowbody) @socket = sock @body_exist = false # Force nil body begin yield self.body # Triggers the bug ensure @socket = nil end end end # Trigger the bug http = Net::HTTP.new('example.com', 443) http.use_ssl = true http.response_body_encoding = 'UTF-8' # String triggers else branch begin http.request(Net::HTTP::Get.new('/')) rescue NoMethodError => e puts "BUG: #{e.message}" puts "Location: #{e.backtrace.first}" end # Expected: Graceful handling # Actual: NoMethodError: undefined method `force_encoding' for nil:NilClass # from lib/net/http/response.rb:360:in `read_body' ``` Suggested fix: In lib/net/http/response.rb line 360, change: ```ruby @body.force_encoding(enc) if enc ``` to: ```ruby @body.force_encoding(enc) if enc && @body ```