lib/reel/response.rb in reel-0.2.0 vs lib/reel/response.rb in reel-0.3.0.pre
- old
+ new
@@ -1,7 +1,12 @@
module Reel
class Response
+
+ CONTENT_LENGTH = 'Content-Length'.freeze
+ TRANSFER_ENCODING = 'Transfer-Encoding'.freeze
+ CHUNKED = 'chunked'.freeze
+
# Use status code tables from the Http gem
STATUS_CODES = Http::Response::STATUS_CODES
SYMBOL_TO_STATUS_CODE = Http::Response::SYMBOL_TO_STATUS_CODE
CRLF = "\r\n"
@@ -18,34 +23,23 @@
else
headers = {}
@body = body_or_headers
end
- @headers = {}
- headers.each do |name, value|
- name = name.to_s
- key = name[Http::CANONICAL_HEADER]
- key ||= canonicalize_header(name)
- @headers[key] = value.to_s
- end
-
case @body
when String
- @headers['Content-Length'] ||= @body.bytesize
+ headers[CONTENT_LENGTH] ||= @body.bytesize
when IO
- @headers['Content-Length'] ||= @body.stat.size
+ headers[CONTENT_LENGTH] ||= @body.stat.size
when Enumerable
- @headers['Transfer-Encoding'] ||= 'chunked'
+ headers[TRANSFER_ENCODING] ||= CHUNKED
when NilClass
else raise TypeError, "can't render #{@body.class} as a response body"
end
- # Prevent modification through the accessor
- @headers.freeze
-
- # FIXME: real HTTP versioning
- @version = "HTTP/1.1"
+ @headers = canonicalize_headers(headers)
+ @version = http_version
end
# Set the status
def status=(status, reason=nil)
case status
@@ -69,26 +63,30 @@
case @body
when String
socket << @body
when IO
- if !defined?(JRUBY_VERSION)
- IO.copy_stream(@body, socket)
- else
- # JRuby 1.6.7 doesn't support IO.copy_stream :(
- while data = @body.read(4096)
- socket << data
+ begin
+ if !defined?(JRUBY_VERSION)
+ IO.copy_stream(@body, socket)
+ else
+ # JRuby 1.6.7 doesn't support IO.copy_stream :(
+ while data = @body.read(4096)
+ socket << data
+ end
end
+ ensure
+ @body.close
end
when Enumerable
@body.each do |chunk|
- chunk_header = chunk.bytesize.to_s(16) + CRLF
- socket << chunk_header
- socket << chunk
+ chunk_header = chunk.bytesize.to_s(16)
+ socket << chunk_header + CRLF
+ socket << chunk + CRLF
end
- socket << "0" << CRLF * 2
+ socket << "0#{CRLF * 2}"
end
end
# Convert headers into a string
# FIXME: this should probably be factored elsewhere, SRP and all
@@ -103,12 +101,20 @@
response_header << CRLF
end
private :render_header
- # Transform to canonical HTTP header capitalization
- def canonicalize_header(header)
- header.to_s.split(/[\-_]/).map(&:capitalize).join('-')
+ def canonicalize_headers headers
+ headers.inject({}) do |headers, (header, value)|
+ headers.merge Http.canonicalize_header(header) => value.to_s
+ end.freeze
end
- private :canonicalize_header
+ private :canonicalize_headers
+
+ def http_version
+ # FIXME: real HTTP versioning
+ "HTTP/1.1".freeze
+ end
+ private :http_version
+
end
end