Parent

Methods

Unicorn::HttpResponse

Writes a Rack response to your client using the HTTP/1.1 specification. You use it by simply doing:

  status, headers, body = rack_app.call(env)
  HttpResponse.write(socket, [ status, headers, body ])

Most header correctness (including Content-Length and Content-Type) is the job of Rack, with the exception of the “Connection: close” and “Date” headers.

A design decision was made to force the client to not pipeline or keepalive requests. HTTP/1.1 pipelining really kills the performance due to how it has to be handled and how unclear the standard is. To fix this the HttpResponse always gives a “Connection: close” header which forces the client to close right away. The bonus for this is that it gives a pretty nice speed boost to most clients since they can close their connection immediately.

Constants

CODES

Every standard HTTP code mapped to the appropriate message.

SKIP

Rack does not set/require a Date: header. We always override the Connection: and Date: headers no matter what (if anything) our Rack application sent us.

Public Class Methods

write(socket, rack_response, have_header = true) click to toggle source

writes the rack_response to socket as an HTTP response

    # File lib/unicorn/http_response.rb, line 38
38:     def self.write(socket, rack_response, have_header = true)
39:       status, headers, body = rack_response
40: 
41:       if have_header
42:         status = CODES[status.to_i] || status
43:         out = []
44: 
45:         # Don't bother enforcing duplicate supression, it's a Hash most of
46:         # the time anyways so just hope our app knows what it's doing
47:         headers.each do |key, value|
48:           next if SKIP.include?(key.downcase)
49:           if value =~ /\n/
50:             # avoiding blank, key-only cookies with /\n+/
51:             out.concat(value.split(/\n+/).map! { |v| "#{key}: #{v}\r\n" })
52:           else
53:             out << "#{key}: #{value}\r\n"
54:           end
55:         end
56: 
57:         # Rack should enforce Content-Length or chunked transfer encoding,
58:         # so don't worry or care about them.
59:         # Date is required by HTTP/1.1 as long as our clock can be trusted.
60:         # Some broken clients require a "Status" header so we accomodate them
61:         socket.write("HTTP/1.1 #{status}\r\n" \
62:                      "Date: #{Time.now.httpdate}\r\n" \
63:                      "Status: #{status}\r\n" \
64:                      "Connection: close\r\n" \
65:                      "#{out.join('')}\r\n")
66:       end
67: 
68:       body.each { |chunk| socket.write(chunk) }
69:       socket.close # flushes and uncorks the socket immediately
70:       ensure
71:         body.respond_to?(:close) and body.close
72:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.