@@ -11,14 +11,6 @@ class Response
1111 include org . jruby . rack . RackResponse
1212 java_import java . nio . channels . Channels
1313
14- @@object_polluted = begin
15- # Fixnum should not have this method, and it
16- # shouldn't be on Object
17- Fixnum . method ( 'to_channel' ) . owner == Object
18- rescue
19- false
20- end
21-
2214 def initialize ( arr )
2315 @status , @headers , @body = *arr
2416 end
@@ -36,9 +28,9 @@ def chunked?
3628 end
3729
3830 def getBody
39- b = ""
40- @body . each { |part | b << part }
41- b
31+ body = ""
32+ @body . each { |part | body << part }
33+ body
4234 ensure
4335 @body . close if @body . respond_to? ( :close )
4436 end
@@ -91,12 +83,19 @@ def write_body(response)
9183 begin
9284 if @body . respond_to? ( :call ) && ! @body . respond_to? ( :each )
9385 @body . call ( outputstream )
94- elsif @body . respond_to? ( :to_channel ) && !object_polluted_with_anyio? ( @body , :to_channel )
86+ elsif @body . respond_to? ( :to_channel ) &&
87+ ! object_polluted_with_anyio? ( @body , :to_channel )
9588 @body = @body . to_channel # so that we close the channel
9689 transfer_channel ( @body , outputstream )
97- elsif @body . respond_to? ( :to_inputstream ) && !object_polluted_with_anyio? ( @body , :to_inputstream )
90+ elsif @body . respond_to? ( :to_inputstream ) &&
91+ ! object_polluted_with_anyio? ( @body , :to_inputstream )
9892 @body = @body . to_inputstream # so that we close the stream
9993 transfer_channel ( Channels . newChannel ( @body ) , outputstream )
94+ elsif @body . respond_to? ( :body_parts ) && @body . body_parts . respond_to? ( :to_channel ) &&
95+ ! object_polluted_with_anyio? ( @body . body_parts , :to_channel )
96+ # ActionDispatch::Response "raw" body access in case it's a File
97+ @body = @body . body_parts . to_channel # so that we close the channel
98+ transfer_channel ( @body , outputstream )
10099 else
101100 # 1.8 has a String#each method but 1.9 does not :
102101 method = @body . respond_to? ( :each_line ) ? :each_line : :each
@@ -117,12 +116,16 @@ def write_body(response)
117116 end
118117 end
119118
119+ private
120+
121+ BUFFER_SIZE = 16 * 1024
122+
120123 def transfer_channel ( channel , outputstream )
121124 outputchannel = Channels . newChannel outputstream
122125 if channel . respond_to? ( :transfer_to )
123126 channel . transfer_to ( 0 , channel . size , outputchannel )
124127 else
125- buffer = java . nio . ByteBuffer . allocate ( 16384 )
128+ buffer = java . nio . ByteBuffer . allocate ( BUFFER_SIZE )
126129 while channel . read ( buffer ) != -1
127130 buffer . flip
128131 outputchannel . write ( buffer )
@@ -135,14 +138,22 @@ def transfer_channel(channel, outputstream)
135138 end
136139 end
137140
141+ @@object_polluted = begin
142+ # Fixnum should not have this method, and it
143+ # shouldn't be on Object
144+ Fixnum . method ( 'to_channel' ) . owner == Object
145+ rescue
146+ false
147+ end
148+
138149 # See http://bugs.jruby.org/5444 - we need to account for pre-1.6
139150 # JRuby where Object was polluted with #to_channel by
140151 # IOJavaAddions.AnyIO
141152 def object_polluted_with_anyio? ( obj , meth )
142- begin
153+ @@object_polluted && begin
143154 # The object should not have this method, and
144155 # it shouldn't be on Object
145- @@object_polluted && obj . method ( meth ) . owner == Object
156+ obj . method ( meth ) . owner == Object
146157 rescue
147158 false
148159 end
0 commit comments