Skip to content
This repository
Browse code

Stream Enumerable response bodies

  • Loading branch information...
commit 356da6ca806c1a49e57205300b31ddc2b5432ecf 1 parent 56fb83c
Tony Arcieri tarcieri authored
2  lib/reel/connection.rb
@@ -132,7 +132,7 @@ def write(chunk)
132 132 # Finish the response and reset the response state to header
133 133 def finish_response
134 134 raise StateError, "not in body state" if @response_state != :chunked_body
135   - @socket << "0#{Response::CRLF * 2}"
  135 + @socket << "0" << Response::CRLF * 2
136 136 @response_state = :header
137 137 end
138 138
12 lib/reel/response.rb
@@ -33,6 +33,10 @@ def initialize(status, body_or_headers = nil, body = nil)
33 33 @headers['Content-Length'] ||= @body.bytesize
34 34 when IO
35 35 @headers['Content-Length'] ||= @body.stat.size
  36 + when Enumerable
  37 + @headers['Transfer-Encoding'] ||= 'chunked'
  38 + when NilClass
  39 + else raise ArgumentError, "can't render #{@body.class} as a response body"
36 40 end
37 41
38 42 # Prevent modification through the accessor
@@ -71,6 +75,14 @@ def render(socket)
71 75 while data = @body.read(4096)
72 76 socket << data
73 77 end
  78 + when Enumerable
  79 + @body.each do |chunk|
  80 + chunk_header = chunk.bytesize.to_s(16) + CRLF
  81 + socket << chunk_header
  82 + socket << chunk
  83 + end
  84 +
  85 + socket << "0" << CRLF * 2
74 86 end
75 87 end
76 88
34 spec/reel/response_spec.rb
... ... @@ -0,0 +1,34 @@
  1 +require 'spec_helper'
  2 +
  3 +describe Reel::Response do
  4 + it "streams enumerables" do
  5 + with_socket_pair do |client, connection|
  6 + client << ExampleRequest.new.to_s
  7 + request = connection.read_request
  8 +
  9 + connection.respond Reel::Response.new(:ok, ["Hello", "World"])
  10 +
  11 + response = client.readpartial(4096)
  12 + crlf = "\r\n"
  13 + fixture = "5#{crlf}Hello5#{crlf}World0#{crlf*2}"
  14 + response[(response.length - fixture.length)..-1].should eq fixture
  15 + end
  16 + end
  17 +
  18 + def with_socket_pair
  19 + host = '127.0.0.1'
  20 + port = 10103
  21 +
  22 + server = TCPServer.new(host, port)
  23 + client = TCPSocket.new(host, port)
  24 + peer = server.accept
  25 +
  26 + begin
  27 + yield client, Reel::Connection.new(peer)
  28 + ensure
  29 + server.close
  30 + client.close
  31 + peer.close
  32 + end
  33 + end
  34 +end

0 comments on commit 356da6c

Please sign in to comment.
Something went wrong with that request. Please try again.