In actionpack/lib/action_controller/cgi_process.rb there's this code
which uses #write to send the output to the client.
def out(output = $stdout)
convert_content_type!(@headers)
output.binmode if output.respond_to?(:binmode)
output.sync = false if output.respond_to?(:sync=)
begin
output.write(@cgi.header(@headers))
if @cgi.send(:env_table)['REQUEST_METHOD'] == 'HEAD'
return
elsif @body.respond_to?(:call)
output.flush if output.respond_to?(:flush)
@body.call(self, output)
In actionpack/lib/action_controller/streaming.rb #syswrite will be used
if it is available, thereby switching from #write to #syswrite
{{
File.open(path, 'rb') do |file|
if output.respond_to?(:syswrite)
begin
while true
output.syswrite(file.sysread(len))
end
rescue EOFError
end
}}
At least in working with C code and stdio, you don't want to switch
between fwrite() and write() without flushing.
The following patch forces a flush if a Proc is given, just to be on the
safe side.