Project

General

Profile

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 
 ```

Back