Class: Reel::Response::Writer

Inherits:
Object
  • Object
show all
Defined in:
lib/reel/response_writer.rb

Constant Summary collapse

CRLF =
"\r\n"

Instance Method Summary collapse

Constructor Details

#initialize(socket) ⇒ Writer



6
7
8
# File 'lib/reel/response_writer.rb', line 6

def initialize(socket)
  @socket = socket
end

Instance Method Details

#finish_responseObject

Finish the response and reset the response state to header



20
21
22
# File 'lib/reel/response_writer.rb', line 20

def finish_response
  @socket << "0#{CRLF * 2}"
end

#handle_response(response) ⇒ Object

Takes a Reel::Response and renders it back over the socket.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/reel/response_writer.rb', line 26

def handle_response(response)
  @socket << render_header(response)
  if response.respond_to?(:render)
    response.render(@socket)
  else
    case response.body
    when String
      @socket << response.body
    when IO
      begin
        if defined?(JRUBY_VERSION) && JRUBY_VERSION <= "1.6.7"
          # JRuby 1.6.7 doesn't support IO.copy_stream :(
          while data = response.body.read(4096)
            @socket << data
          end
        else
          # Use OS sendfile via IO.copy_stream
          # FIXME: should use Celluloid::IO.copy_stream and allow these
          # calls to be multiplexed through Celluloid::IO's reactor
          # Until then we need a thread for each of these responses
          Celluloid.defer { IO.copy_stream(response.body, @socket.to_io) }
          # @socket currently not being converted to appropriate IO object automatically.
          # Convert the object in advance to still enjoy IO.copy_stream coverage.
        end
      ensure
        response.body.close
      end
    when Enumerable
      response.body.each do |chunk|
        write(chunk)
      end

      finish_response
    end
  end
end

#write(chunk) ⇒ Object

Write body chunks directly to the connection



11
12
13
14
15
16
17
# File 'lib/reel/response_writer.rb', line 11

def write(chunk)
  chunk_header = chunk.bytesize.to_s(16)
  @socket << chunk_header + CRLF
  @socket << chunk + CRLF
rescue IOError, Errno::EPIPE, Errno::ECONNRESET => ex
  raise Reel::SocketError, ex.to_s
end