From b2ede64a89a5837a047e75f21a1522324a614514 Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Thu, 28 Sep 2006 19:13:55 +0000 Subject: 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 --- actionpack/lib/action_controller/base.rb | 27 +++++++- actionpack/lib/action_controller/status_codes.rb | 79 ++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 actionpack/lib/action_controller/status_codes.rb (limited to 'actionpack/lib/action_controller') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index e9d415085a..bd2256f44d 100755 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -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 diff --git a/actionpack/lib/action_controller/status_codes.rb b/actionpack/lib/action_controller/status_codes.rb new file mode 100644 index 0000000000..c6461914ae --- /dev/null +++ b/actionpack/lib/action_controller/status_codes.rb @@ -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 \ No newline at end of file -- cgit v1.2.3