Skip to content

Commit

Permalink
reflect changes in Rack::Utils::HTTP_STATUS_CODES
Browse files Browse the repository at this point in the history
Applications may want to alter the message associated with HTTP
status codes in Rack::Utils::HTTP_STATUS_CODES.  Avoid memoizing
status lines ahead-of-time

Note: this introduces a minor performance regression, but ought to
be unnoticeable unless you're running "Hello world"-type apps.
  • Loading branch information
Eric Wong committed Jun 30, 2015
1 parent 1db9a82 commit b0d10d4
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
15 changes: 7 additions & 8 deletions lib/unicorn/http_response.rb
Expand Up @@ -10,25 +10,24 @@
# is the job of Rack, with the exception of the "Date" and "Status" header.
module Unicorn::HttpResponse

# Every standard HTTP code mapped to the appropriate message.
CODES = Rack::Utils::HTTP_STATUS_CODES.inject({}) { |hash,(code,msg)|
hash[code] = "#{code} #{msg}"
hash
}
CRLF = "\r\n"

# internal API, code will always be common-enough-for-even-old-Rack
def err_response(code, response_start_sent)
"#{response_start_sent ? '' : 'HTTP/1.1 '}#{CODES[code]}\r\n\r\n"
"#{response_start_sent ? '' : 'HTTP/1.1 '}" \
"#{code} #{Rack::Utils::HTTP_STATUS_CODES[code]}\r\n\r\n"
end

# writes the rack_response to socket as an HTTP response
def http_response_write(socket, status, headers, body,
response_start_sent=false)
hijack = nil

http_response_start = response_start_sent ? '' : 'HTTP/1.1 '
if headers
buf = "#{http_response_start}#{CODES[status.to_i] || status}\r\n" \
code = status.to_i
msg = Rack::Utils::HTTP_STATUS_CODES[code]
start = response_start_sent ? ''.freeze : 'HTTP/1.1 '.freeze
buf = "#{start}#{msg ? %Q(#{code} #{msg}) : status}\r\n" \
"Date: #{httpdate}\r\n" \
"Connection: close\r\n"
headers.each do |key, value|
Expand Down
20 changes: 20 additions & 0 deletions test/unit/test_response.rb
Expand Up @@ -79,4 +79,24 @@ def test_unknown_status_pass_through
headers = out.string.split(/\r\n\r\n/).first.split(/\r\n/)
assert %r{\AHTTP/\d\.\d 666 I AM THE BEAST\z}.match(headers[0])
end

def test_modified_rack_http_status_codes_late
r, w = IO.pipe
pid = fork do
r.close
# Users may want to globally override the status text associated
# with an HTTP status code in their app.
Rack::Utils::HTTP_STATUS_CODES[200] = "HI"
http_response_write(w, 200, {}, [])
w.close
end
w.close
assert_equal "HTTP/1.1 200 HI\r\n", r.gets
r.read # just drain the pipe
pid, status = Process.waitpid2(pid)
assert_predicate status, :success?
ensure
r.close
w.close unless w.closed?
end
end

0 comments on commit b0d10d4

Please sign in to comment.