mirror of
https://github.com/github/rails.git
synced 2026-04-26 03:00:59 -04:00
Add ActionController::Base#head for rendering empty responses. Add support for symbolic status codes, as well as for having raw integer statuses expand with their default messages.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@5199 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
This commit is contained in:
@@ -1,5 +1,16 @@
|
||||
*SVN*
|
||||
|
||||
* Make the :status parameter expand to the default message for that status code if it is an integer. Also support symbol statuses. [Jamis Buck]. Examples:
|
||||
|
||||
head :status => 404 # expands to "404 Not Found"
|
||||
head :status => :not_found # expands to "404 Not Found"
|
||||
head :status => :created # expands to "201 Created"
|
||||
|
||||
* Add head(options = {}) for responses that have no body. [Jamis Buck]. Examples:
|
||||
|
||||
head :status => 404 # return an empty response with a 404 status
|
||||
head :location => person_path(@person), :status => 201
|
||||
|
||||
* Fix bug that kept any before_filter except the first one from being able to halt the before_filter chain. [Rick Olson]
|
||||
|
||||
* strip_links is case-insensitive. #6285 [tagoh, Bob Silva]
|
||||
|
||||
@@ -4,6 +4,7 @@ require 'action_controller/response'
|
||||
require 'action_controller/routing'
|
||||
require 'action_controller/resources'
|
||||
require 'action_controller/url_rewriter'
|
||||
require 'action_controller/status_codes'
|
||||
require 'drb'
|
||||
require 'set'
|
||||
|
||||
@@ -209,6 +210,7 @@ module ActionController #:nodoc:
|
||||
DEFAULT_RENDER_STATUS_CODE = "200 OK"
|
||||
|
||||
include Reloadable::Deprecated
|
||||
include StatusCodes
|
||||
|
||||
# Determines whether the view has access to controller internals @request, @response, @session, and @template.
|
||||
# By default, it does.
|
||||
@@ -793,7 +795,7 @@ module ActionController #:nodoc:
|
||||
|
||||
def render_text(text = nil, status = nil) #:nodoc:
|
||||
@performed_render = true
|
||||
response.headers['Status'] = (status || DEFAULT_RENDER_STATUS_CODE).to_s
|
||||
response.headers['Status'] = interpret_status(status || DEFAULT_RENDER_STATUS_CODE)
|
||||
response.body = text
|
||||
end
|
||||
|
||||
@@ -830,6 +832,29 @@ module ActionController #:nodoc:
|
||||
end
|
||||
|
||||
|
||||
# Return a response that has no content (merely headers). The options
|
||||
# argument is interpreted to be a hash of header names and values.
|
||||
# This allows you to easily return a response that consists only of
|
||||
# significant headers:
|
||||
#
|
||||
# head :status => :created, :location => person_path(@person)
|
||||
#
|
||||
# It can also be used to return exceptional conditions:
|
||||
#
|
||||
# return head(:status => :method_not_allowed) unless request.post?
|
||||
# return head(:status => :bad_request) unless valid_request?
|
||||
# render
|
||||
def head(options = {})
|
||||
status = interpret_status(options.delete(:status) || :ok)
|
||||
|
||||
options.each do |key, value|
|
||||
headers[key.to_s.dasherize.split(/-/).map { |v| v.capitalize }.join("-")] = value.to_s
|
||||
end
|
||||
|
||||
render :nothing => true, :status => status
|
||||
end
|
||||
|
||||
|
||||
# Clears the rendered results, allowing for another render to be performed.
|
||||
def erase_render_results #:nodoc:
|
||||
response.body = nil
|
||||
|
||||
79
actionpack/lib/action_controller/status_codes.rb
Normal file
79
actionpack/lib/action_controller/status_codes.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
module ActionController
|
||||
module StatusCodes
|
||||
|
||||
# Defines the standard HTTP status codes, by integer, with their
|
||||
# corresponding default message texts.
|
||||
STATUS_CODES = {
|
||||
100 => "Continue",
|
||||
101 => "Switching Protocols",
|
||||
|
||||
200 => "OK",
|
||||
201 => "Created",
|
||||
202 => "Accepted",
|
||||
203 => "Non-Authoritative Information",
|
||||
204 => "No Content",
|
||||
205 => "Reset Content",
|
||||
206 => "Partial Content",
|
||||
|
||||
300 => "Multiple Choices",
|
||||
301 => "Moved Permanently",
|
||||
302 => "Found",
|
||||
303 => "See Other",
|
||||
304 => "Not Modified",
|
||||
305 => "Use Proxy",
|
||||
307 => "Temporary Redirect",
|
||||
|
||||
400 => "Bad Request",
|
||||
401 => "Unauthorized",
|
||||
402 => "Payment Required",
|
||||
403 => "Forbidden",
|
||||
404 => "Not Found",
|
||||
405 => "Method Not Allowed",
|
||||
406 => "Not Acceptable",
|
||||
407 => "Proxy Authentication Required",
|
||||
408 => "Request Timeout",
|
||||
409 => "Conflict",
|
||||
410 => "Gone",
|
||||
411 => "Length Required",
|
||||
412 => "Precondition Failed",
|
||||
413 => "Request Entity Too Large",
|
||||
414 => "Request-URI Too Long",
|
||||
415 => "Unsupported Media Type",
|
||||
416 => "Requested Range Not Satisfiable",
|
||||
417 => "Expectation Failed",
|
||||
|
||||
500 => "Internal Server Error",
|
||||
501 => "Not Implemented",
|
||||
502 => "Bad Gateway",
|
||||
503 => "Service Unavailable",
|
||||
504 => "Gateway Timeout",
|
||||
505 => "HTTP Version Not Supported"
|
||||
}
|
||||
|
||||
# Provides a symbol-to-fixnum lookup for converting a symbol (like
|
||||
# :created or :not_implemented) into its corresponding HTTP status
|
||||
# code (like 200 or 501).
|
||||
SYMBOL_TO_STATUS_CODE = STATUS_CODES.inject({}) do |hash, (code, message)|
|
||||
hash[message.gsub(/ /, "").underscore.to_sym] = code
|
||||
hash
|
||||
end
|
||||
|
||||
# Given a status parameter, determine whether it needs to be converted
|
||||
# to a string. If it is a fixnum, use the STATUS_CODES hash to lookup
|
||||
# the default message. If it is a symbol, use the SYMBOL_TO_STATUS_CODE
|
||||
# hash to convert it.
|
||||
def interpret_status(status)
|
||||
case status
|
||||
when Fixnum then
|
||||
"#{status} #{STATUS_CODES[status]}".strip
|
||||
when Symbol then
|
||||
interpret_status(SYMBOL_TO_STATUS_CODE[status] ||
|
||||
"500 Unknown Status #{status.inspect}")
|
||||
else
|
||||
status.to_s
|
||||
end
|
||||
end
|
||||
private :interpret_status
|
||||
|
||||
end
|
||||
end
|
||||
@@ -202,6 +202,26 @@ class NewRenderTestController < ActionController::Base
|
||||
render :template => "test/hello_world.rxml"
|
||||
end
|
||||
|
||||
def head_with_location_header
|
||||
head :location => "/foo"
|
||||
end
|
||||
|
||||
def head_with_symbolic_status
|
||||
head :status => params[:status].intern
|
||||
end
|
||||
|
||||
def head_with_integer_status
|
||||
head :status => params[:status].to_i
|
||||
end
|
||||
|
||||
def head_with_string_status
|
||||
head :status => params[:status]
|
||||
end
|
||||
|
||||
def head_with_custom_header
|
||||
head :x_custom_header => "something"
|
||||
end
|
||||
|
||||
helper NewRenderTestHelper
|
||||
helper do
|
||||
def rjs_helper_method(value)
|
||||
@@ -602,4 +622,43 @@ EOS
|
||||
get :hello_world_from_rxml_using_action
|
||||
assert_equal "<html>\n <p>Hello</p>\n</html>\n", @response.body
|
||||
end
|
||||
|
||||
|
||||
def test_head_with_location_header
|
||||
get :head_with_location_header
|
||||
assert @response.body.blank?
|
||||
assert_equal "/foo", @response.headers["Location"]
|
||||
end
|
||||
|
||||
def test_head_with_custom_header
|
||||
get :head_with_custom_header
|
||||
assert @response.body.blank?
|
||||
assert_equal "something", @response.headers["X-Custom-Header"]
|
||||
end
|
||||
|
||||
def test_head_with_symbolic_status
|
||||
get :head_with_symbolic_status, :status => "ok"
|
||||
assert_equal "200 OK", @response.headers["Status"]
|
||||
|
||||
get :head_with_symbolic_status, :status => "not_found"
|
||||
assert_equal "404 Not Found", @response.headers["Status"]
|
||||
|
||||
ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE.each do |status, code|
|
||||
get :head_with_symbolic_status, :status => status.to_s
|
||||
assert_equal code, @response.response_code
|
||||
end
|
||||
end
|
||||
|
||||
def test_head_with_integer_status
|
||||
ActionController::StatusCodes::STATUS_CODES.each do |code, message|
|
||||
get :head_with_integer_status, :status => code.to_s
|
||||
assert_equal message, @response.message
|
||||
end
|
||||
end
|
||||
|
||||
def head_with_string_status
|
||||
get :head_with_string_status, :status => "404 Eat Dirt"
|
||||
assert_equal 404, @response.response_code
|
||||
assert_equal "Eat Dirt", @response.message
|
||||
end
|
||||
end
|
||||
|
||||
@@ -97,7 +97,7 @@ class SendFileTest < Test::Unit::TestCase
|
||||
define_method "test_send_#{method}_status" do
|
||||
@controller.options = { :stream => false, :status => 500 }
|
||||
assert_nothing_raised { assert_not_nil process(method) }
|
||||
assert_equal '500', @controller.headers['Status']
|
||||
assert_equal '500 Internal Server Error', @controller.headers['Status']
|
||||
end
|
||||
|
||||
define_method "test_default_send_#{method}_status" do
|
||||
|
||||
Reference in New Issue
Block a user