@@ -127,9 +127,26 @@ def write_response(status, headers, app_body, io_buffer, requests, client)
127127
128128 resp_info = str_headers ( env , status , headers , app_body , io_buffer , requests , client )
129129
130- if !resp_info . key? ( :content_length ) && app_body . respond_to? ( :to_ary ) && !app_body . empty?
131- body = app_body . to_ary
132- resp_info [ :content_length ] = body . inject ( 0 ) { |sum , el | sum + el . bytesize }
130+ # below converts app_body into body, dependent on app_body's characteristics, and
131+ # resp_info[:content_length] will be set if it can be determined
132+ if !resp_info [ :content_length ] && !resp_info [ :transfer_encoding ] && status != 204
133+ if app_body . respond_to? ( :to_ary )
134+ length = 0
135+ if array_body = app_body . to_ary
136+ body = array_body . map { |part | length += part . bytesize ; part }
137+ elsif app_body . is_a? ( ::File ) && app_body . respond_to? ( :size )
138+ length = app_body . size
139+ elsif app_body . respond_to? ( :each )
140+ body = [ ]
141+ app_body . each { |part | length += part . bytesize ; body << part }
142+ end
143+ resp_info [ :content_length ] = length
144+ elsif app_body . is_a? ( File ) && app_body . respond_to? ( :size )
145+ resp_info [ :content_length ] = app_body . size
146+ body = app_body
147+ else
148+ body = app_body
149+ end
133150 else
134151 body = app_body
135152 end
@@ -527,6 +544,7 @@ def str_headers(env, status, headers, res_body, io_buffer, requests, client)
527544 when TRANSFER_ENCODING
528545 resp_info [ :allow_chunked ] = false
529546 resp_info [ :content_length ] = nil
547+ resp_info [ :transfer_encoding ] = vs
530548 when HIJACK
531549 resp_info [ :response_hijack ] = vs
532550 next
0 commit comments