Permalink
Browse files

Stream Enumerable response bodies

  • Loading branch information...
1 parent 56fb83c commit 356da6ca806c1a49e57205300b31ddc2b5432ecf @tarcieri tarcieri committed Jun 3, 2012
Showing with 47 additions and 1 deletion.
  1. +1 −1 lib/reel/connection.rb
  2. +12 −0 lib/reel/response.rb
  3. +34 −0 spec/reel/response_spec.rb
@@ -132,7 +132,7 @@ def write(chunk)
# Finish the response and reset the response state to header
def finish_response
raise StateError, "not in body state" if @response_state != :chunked_body
- @socket << "0#{Response::CRLF * 2}"
+ @socket << "0" << Response::CRLF * 2
@response_state = :header
end
View
@@ -33,6 +33,10 @@ def initialize(status, body_or_headers = nil, body = nil)
@headers['Content-Length'] ||= @body.bytesize
when IO
@headers['Content-Length'] ||= @body.stat.size
+ when Enumerable
+ @headers['Transfer-Encoding'] ||= 'chunked'
+ when NilClass
+ else raise ArgumentError, "can't render #{@body.class} as a response body"
end
# Prevent modification through the accessor
@@ -71,6 +75,14 @@ def render(socket)
while data = @body.read(4096)
socket << data
end
+ when Enumerable
+ @body.each do |chunk|
+ chunk_header = chunk.bytesize.to_s(16) + CRLF
+ socket << chunk_header
+ socket << chunk
+ end
+
+ socket << "0" << CRLF * 2
end
end
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe Reel::Response do
+ it "streams enumerables" do
+ with_socket_pair do |client, connection|
+ client << ExampleRequest.new.to_s
+ request = connection.read_request
+
+ connection.respond Reel::Response.new(:ok, ["Hello", "World"])
+
+ response = client.readpartial(4096)
+ crlf = "\r\n"
+ fixture = "5#{crlf}Hello5#{crlf}World0#{crlf*2}"
+ response[(response.length - fixture.length)..-1].should eq fixture
+ end
+ end
+
+ def with_socket_pair
+ host = '127.0.0.1'
+ port = 10103
+
+ server = TCPServer.new(host, port)
+ client = TCPSocket.new(host, port)
+ peer = server.accept
+
+ begin
+ yield client, Reel::Connection.new(peer)
+ ensure
+ server.close
+ client.close
+ peer.close
+ end
+ end
+end

0 comments on commit 356da6c

Please sign in to comment.