http_response: make this a module, not a class
[rainbows.git] / lib / rainbows / http_response.rb
blob811a793cb7c26dfaef791f385b6013e412251c39
1 # -*- encoding: binary -*-
2 require 'time' # for Time#httpdate
4 # :stopdoc:
5 module Rainbows::HttpResponse
7   CODES = Unicorn::HttpResponse::CODES
9   def self.header_string(status, headers, out)
10     status = CODES[status.to_i] || status
12     headers.each do |key, value|
13       next if %r{\A(?:X-Rainbows-|Connection\z|Date\z|Status\z)}i =~ key
14       if value =~ /\n/
15         # avoiding blank, key-only cookies with /\n+/
16         out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" })
17       else
18         out << "#{key}: #{value}\r\n"
19       end
20     end
22     "HTTP/1.1 #{status}\r\n" \
23     "Date: #{Time.now.httpdate}\r\n" \
24     "Status: #{status}\r\n" \
25     "#{out.join('')}\r\n"
26   end
28   def self.write(socket, rack_response, out = [])
29     status, headers, body = rack_response
30     out and socket.write(header_string(status, headers, out))
32     body.each { |chunk| socket.write(chunk) }
33     ensure
34       body.respond_to?(:close) and body.close
35   end
36 end
37 # :startdoc: