lib/mizuno/rack_handler.rb
def rack_to_servlet(rack_response, response)
            # Split apart the Rack response.
            status, headers, body = rack_response

            # We assume the request is finished if we got empty headers,
            # an empty body, and we have a committed response.
            finished = (headers.empty? and \
                body.respond_to?(:empty?) and body.empty?)
            return(true) if (finished and response.isCommitted)

            # No need to send headers again if we've already shipped 
            # data out on an async request.
            unless(response.isCommitted)
                # Set the HTTP status code.
                response.setStatus(status.to_i)

                # Servlets require that we set Content-Length and
                # Content-Type differently than other headers.
                content_length = headers.delete('Content-Length') \
                    and response.setContentLength(content_length.to_i)
                content_type = headers.delete('Content-Type') \
                    and response.setContentType(content_type)

                # Add all the result headers.
                headers.each { |h, v| v.split(NEWLINE).each { |l|
                    response.addHeader(h, l) } }
            end

            # How else would we write output?
            output = response.getOutputStream

            # Turn the body into something nice and Java-y.
            if(body.respond_to?(:to_path))
                # We've been told to serve a file; use FileInputStream to
                # stream the file directly to the servlet, because this
                # is a lot faster than doing it with Ruby.
                file = java.io.File.new(body.to_path)

                # We set the content-length so we can use Keep-Alive,
                # unless this is an async request.
                response.setContentLength(file.length) \
                    unless content_length

                # Stream the file directly.
                buffer = Java::byte[4096].new
                input_stream = FileInputStream.new(file)
                while((count = input_stream.read(buffer)) != -1)
                    output.write(buffer, 0, count)
                end
                input_stream.close
            else
                body.each do |chunk|
                    output.write(chunk.to_java_bytes)
                    output.flush
                end
            end

            # Close the body if we're supposed to.
            body.close if body.respond_to?(:close)

            # All done.
            output.flush
        end
def rack_to_servlet(rack_response, response)
            # Split apart the Rack response.
            status, headers, body = rack_response

            # We assume the request is finished if we got empty headers,
            # an empty body, and we have a committed response.
            finished = (headers.empty? and \
                body.respond_to?(:empty?) and body.empty?)
            return(true) if (finished and response.isCommitted)

            # No need to send headers again if we've already shipped 
            # data out on an async request.
            unless(response.isCommitted)
                # Set the HTTP status code.
                response.setStatus(status.to_i)

                # Servlets require that we set Content-Length and
                # Content-Type differently than other headers.
                content_length = headers.delete('Content-Length') \
                    and response.setContentLength(content_length.to_i)
                content_type = headers.delete('Content-Type') \
                    and response.setContentType(content_type)

                # Add all the result headers.
                headers.each { |h, v| v.split(NEWLINE).each { |l|
                    response.addHeader(h, l) } }
            end

            # How else would we write output?
            output = response.getOutputStream

            # Turn the body into something nice and Java-y.
            if(body.respond_to?(:to_path))
                # We've been told to serve a file; use FileInputStream to
                # stream the file directly to the servlet, because this
                # is a lot faster than doing it with Ruby.
                file = java.io.File.new(body.to_path)

                # We set the content-length so we can use Keep-Alive,
                # unless this is an async request.
                response.setContentLength(file.length) \
                    unless content_length

                # Stream the file directly.
                buffer = Java::byte[4096].new
                input_stream = FileInputStream.new(file)
                while((count = input_stream.read(buffer)) != -1)
                    output.write(buffer, 0, count)
                end
                input_stream.close
            else
                body.each do |chunk|
                    output.write(chunk.to_java_bytes)
                    output.flush
                end
            end

            # Close the body if we're supposed to.
            body.close if body.respond_to?(:close)

            # All done.
            output.flush
        end
Turns a Rack response into a Servlet response; can be called
 multiple times.  Returns true if this is the full request (either
 a synchronous request or the last part of an async request),
 false otherwise.

 Note that keep-alive *only* happens if we get either a pathname
 (because we can find the length ourselves), or if we get a
 Content-Length header as part of the response.  While we can
 readily buffer the response object to figure out how long it is,
 we have no guarantee that we aren't going to be buffering
 something *huge*.

 http://docstore.mik.ua/orelly/java-ent/servlet/ch05_03.htm