Class: Merb::Request
- Includes:
- ControllerExceptions
- Defined in:
- lib/merb-core/dispatch/request.rb,
lib/merb-core/dispatch/dispatcher.rb
Direct Known Subclasses
Constant Summary collapse
- METHODS =
%w{get post put delete head options}
- @@mutex =
Mutex.new
Constants included from ControllerExceptions
ControllerExceptions::STATUS_CODES
Instance Attribute Summary collapse
-
#env ⇒ Object
:api: private.
-
#route ⇒ Object
:api: private.
-
#route_params ⇒ Object
readonly
:api: private.
-
#start ⇒ Object
readonly
Returns the value of attribute start.
Class Method Summary collapse
-
.new(env, *args) ⇒ Object
Memoizes the new request object into env so we can memoize things into ivars in the request.
Instance Method Summary collapse
-
#_process_block_return(retval) ⇒ Object
Notes Processes the return value of a deferred router block and returns the current route params for the current request evaluation.
-
#accept ⇒ Object
Returns String:: The accepted response types.
-
#accept_charset ⇒ Object
Returns String:: The accepted character sets.
-
#accept_encoding ⇒ Object
Returns String:: The accepted encodings.
-
#accept_language ⇒ Object
Returns String:: The accepted language.
-
#cache_control ⇒ Object
Returns String:: HTTP cache control.
-
#connection ⇒ Object
Returns String:: The HTTP connection.
-
#content_length ⇒ Object
Returns Fixnum:: The request content length.
-
#content_type ⇒ Object
Returns String:: The request content type.
-
#controller ⇒ Object
Returns the controller object for initialization and dispatching the request.
-
#domain(tld_length = 1) ⇒ Object
Parameters tld_length<Fixnum>:: Number of domains levels to inlclude in the top level domain.
- #exceptions ⇒ Object
-
#find_route! ⇒ Object
Notes Find route using requested URI and merges route parameters (:action, :controller and named segments) into request params hash.
-
#full_uri ⇒ Object
Returns String:: The full URI, including protocol and host.
-
#gateway ⇒ Object
Returns String:: The gateway.
-
#handle ⇒ Array[Integer, Hash, #each]
private
Handles request routing and action dispatch.
-
#handled? ⇒ Boolean
If @route_params is an Array, then it will be the rack response.
-
#host ⇒ Object
Returns String:: The full hostname including the port.
-
#if_modified_since ⇒ Object
Returns Value of If-Modified-Since request header.
-
#if_none_match ⇒ Object
Returns Value of If-None-Match request header.
-
#initialize(rack_env) ⇒ Request
constructor
Initialize the request object.
-
#keep_alive ⇒ Object
Returns String:: Value of HTTP_KEEP_ALIVE.
-
#matched! ⇒ Object
Sets the request as matched.
-
#matched? ⇒ Boolean
Checks whether or not the request has been matched to a route.
-
#message ⇒ Object
Returns String:: Returns the redirect message Base64 unencoded.
-
#method ⇒ Object
Returns Symbol:: The name of the request method, e.g.
-
#params ⇒ Object
Returns Mash:: All request parameters.
-
#path ⇒ Object
Returns String:: The URI without the query string.
-
#path_info ⇒ Object
Returns String:: The path info.
-
#port ⇒ Object
Returns Fixnum:: The server port.
-
#protocol ⇒ Object
Returns String:: The protocol, i.e.
-
#query_string ⇒ Object
Returns String:: The query string.
-
#rack_response ⇒ Object
Returns (Array, Hash):: the route params for the matched route.
-
#raw_post ⇒ Object
Returns String:: The raw post.
-
#referer ⇒ Object
Returns String:: The HTTP referer.
-
#remote_ip ⇒ Object
Returns String:: The remote IP address.
-
#reset_params! ⇒ Object
Notes Resets the params to a nil value.
-
#script_name ⇒ Object
Returns String:: The script name.
-
#server_name ⇒ Object
Returns String:: The server name.
-
#server_software ⇒ Object
Returns String:: The server software.
-
#ssl? ⇒ Boolean
Returns Boolean::: True if the request is an SSL request.
-
#subdomains(tld_length = 1) ⇒ Object
Parameters tld_length<Fixnum>:: Number of domains levels to inlclude in the top level domain.
-
#uri ⇒ Object
Returns String:: The request URI.
-
#user_agent ⇒ Object
Returns String:: The HTTP user agent.
-
#version ⇒ Object
Returns String:: The HTTP version.
-
#xml_http_request? ⇒ Boolean
(also: #xhr?, #ajax?)
Returns Boolean:: If the request is an XML HTTP request.
Constructor Details
#initialize(rack_env) ⇒ Request
Initialize the request object.
Parameters
- http_request<~params:~[], ~body:IO>
-
An object like an HTTP Request.
:api: private
36 37 38 39 40 |
# File 'lib/merb-core/dispatch/request.rb', line 36 def initialize(rack_env) @env = rack_env @body = rack_env[Merb::Const::RACK_INPUT] @route_params = {} end |
Instance Attribute Details
#env ⇒ Object
:api: private
8 9 10 |
# File 'lib/merb-core/dispatch/request.rb', line 8 def env @env end |
#route ⇒ Object
:api: private
8 9 10 |
# File 'lib/merb-core/dispatch/request.rb', line 8 def route @route end |
#route_params ⇒ Object (readonly)
:api: private
10 11 12 |
# File 'lib/merb-core/dispatch/request.rb', line 10 def route_params @route_params end |
#start ⇒ Object (readonly)
Returns the value of attribute start.
39 40 41 |
# File 'lib/merb-core/dispatch/dispatcher.rb', line 39 def start @start end |
Class Method Details
.new(env, *args) ⇒ Object
Memoizes the new request object into env so we can memoize things into ivars in the request
Parameters
- env<Hash>
-
A rack environment
- *args<Array>
-
Other arguments passed to the superclass
Returns
- Merb::Request
-
The new Merb::Request
:api: public
53 54 55 56 57 58 59 |
# File 'lib/merb-core/dispatch/request.rb', line 53 def self.new(env, *args) if self == Merb::Request env["merb.request"] ||= super else super end end |
Instance Method Details
#_process_block_return(retval) ⇒ Object
Notes
Processes the return value of a deferred router block and returns the current route params for the current request evaluation
:api: private
147 148 149 150 151 152 153 154 |
# File 'lib/merb-core/dispatch/request.rb', line 147 def _process_block_return(retval) # If the return value is an array, then it is a redirect # so we must set the request as a redirect and extract # the redirect params and return it as a hash so that the # dispatcher can handle it matched! if retval.is_a?(Array) retval end |
#accept ⇒ Object
Returns
- String
-
The accepted response types. Defaults to “/”.
:api: private
512 513 514 |
# File 'lib/merb-core/dispatch/request.rb', line 512 def accept @env[Merb::Const::HTTP_ACCEPT].blank? ? "*/*" : @env[Merb::Const::HTTP_ACCEPT] end |
#accept_charset ⇒ Object
Returns
- String
-
The accepted character sets.
:api: public
488 489 490 |
# File 'lib/merb-core/dispatch/request.rb', line 488 def accept_charset @env[Merb::Const::HTTP_ACCEPT_CHARSET] end |
#accept_encoding ⇒ Object
Returns
- String
-
The accepted encodings.
:api: private
440 441 442 |
# File 'lib/merb-core/dispatch/request.rb', line 440 def accept_encoding @env[Merb::Const::HTTP_ACCEPT_ENCODING] end |
#accept_language ⇒ Object
Returns
- String
-
The accepted language.
:api: public
464 465 466 |
# File 'lib/merb-core/dispatch/request.rb', line 464 def accept_language @env[Merb::Const::HTTP_ACCEPT_LANGUAGE] end |
#cache_control ⇒ Object
Returns
- String
-
HTTP cache control.
:api: public
456 457 458 |
# File 'lib/merb-core/dispatch/request.rb', line 456 def cache_control @env[Merb::Const::HTTP_CACHE_CONTROL] end |
#connection ⇒ Object
Returns
- String
-
The HTTP connection.
:api: private
520 521 522 |
# File 'lib/merb-core/dispatch/request.rb', line 520 def connection @env[Merb::Const::HTTP_CONNECTION] end |
#content_length ⇒ Object
Returns
- Fixnum
-
The request content length.
:api: public
544 545 546 |
# File 'lib/merb-core/dispatch/request.rb', line 544 def content_length @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i end |
#content_type ⇒ Object
Returns
- String
-
The request content type.
:api: private
536 537 538 |
# File 'lib/merb-core/dispatch/request.rb', line 536 def content_type @env[Merb::Const::UPCASE_CONTENT_TYPE] end |
#controller ⇒ Object
Returns the controller object for initialization and dispatching the request.
Returns
- Class
-
The controller class matching the routed request,
e.g. Posts.
:api: private
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/merb-core/dispatch/request.rb', line 69 def controller unless params[:controller] raise ControllerExceptions::NotFound, "Route matched, but route did not specify a controller.\n" + "Did you forgot to add :controller => \"people\" or :controller " + "segment to route definition?\nHere is what's specified:\n" + route.inspect end path = [params[:namespace], params[:controller]].compact.join(Merb::Const::SLASH) controller = path.snake_case.to_const_string begin Object.full_const_get(controller) rescue NameError => e msg = "Controller class not found for controller `#{path}'" Merb.logger.warn!(msg) raise ControllerExceptions::NotFound, msg end end |
#domain(tld_length = 1) ⇒ Object
Parameters
- tld_length<Fixnum>
-
Number of domains levels to inlclude in the top level domain. Defaults to 1.
Returns
- String
-
The full domain name without the port number.
:api: public
610 611 612 |
# File 'lib/merb-core/dispatch/request.rb', line 610 def domain(tld_length = 1) host.split(Merb::Const::DOT).last(1 + tld_length).join(Merb::Const::DOT).sub(/:\d+$/,'') end |
#exceptions ⇒ Object
89 90 91 |
# File 'lib/merb-core/dispatch/request.rb', line 89 def exceptions env["merb.exceptions"] end |
#find_route! ⇒ Object
Notes
Find route using requested URI and merges route parameters (:action, :controller and named segments) into request params hash.
:api: private
136 137 138 139 |
# File 'lib/merb-core/dispatch/request.rb', line 136 def find_route! @route, @route_params = Merb::Router.route_for(self) params.merge! @route_params if @route_params.is_a?(Hash) end |
#full_uri ⇒ Object
Returns
- String
-
The full URI, including protocol and host
:api: public
408 409 410 |
# File 'lib/merb-core/dispatch/request.rb', line 408 def full_uri protocol + "://" + host + uri end |
#gateway ⇒ Object
Returns
- String
-
The gateway.
:api: public
504 505 506 |
# File 'lib/merb-core/dispatch/request.rb', line 504 def gateway @env[Merb::Const::GATEWAY_INTERFACE] end |
#handle ⇒ Array[Integer, Hash, #each]
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Handles request routing and action dispatch
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/merb-core/dispatch/dispatcher.rb', line 46 def handle @start = env["merb.request_start"] = Time.now Merb.logger.info { "Started request handling: #{start.to_s}" } find_route! return rack_response if handled? klass = controller unless klass < Controller raise NotFound, "Controller '#{klass}' not found.\n" \ "If Merb tries to find a controller for static files, " \ "you may need to check your Rackup file, see the Problems " \ "section at: http://wiki.merbivore.com/pages/rack-middleware" end Merb.logger.debug { "Routed to: #{klass::_filter_params(params).inspect}" } if klass.abstract? raise NotFound, "The '#{klass}' controller has no public actions" end dispatch_action(klass, params[:action]) rescue Object => exception dispatch_exception(exception) end |
#handled? ⇒ Boolean
If @route_params is an Array, then it will be the rack response. In this case, the request is considered handled.
Returns
- Boolean
-
true if @route_params is an Array, false otherwise.
:api: private
191 192 193 |
# File 'lib/merb-core/dispatch/request.rb', line 191 def handled? @route_params.is_a?(Array) end |
#host ⇒ Object
Returns
- String
-
The full hostname including the port.
:api: public
582 583 584 585 |
# File 'lib/merb-core/dispatch/request.rb', line 582 def host @env[Merb::Const::HTTP_X_FORWARDED_HOST] || @env[Merb::Const::HTTP_HOST] || @env[Merb::Const::SERVER_NAME] end |
#if_modified_since ⇒ Object
Returns
Value of If-Modified-Since request header.
:api: private
626 627 628 629 630 |
# File 'lib/merb-core/dispatch/request.rb', line 626 def if_modified_since if time = @env[Merb::Const::HTTP_IF_MODIFIED_SINCE] Time.rfc2822(time) end end |
#if_none_match ⇒ Object
Returns
Value of If-None-Match request header.
:api: private
618 619 620 |
# File 'lib/merb-core/dispatch/request.rb', line 618 def if_none_match @env[Merb::Const::HTTP_IF_NONE_MATCH] end |
#keep_alive ⇒ Object
Returns
- String
-
Value of HTTP_KEEP_ALIVE.
:api: public
480 481 482 |
# File 'lib/merb-core/dispatch/request.rb', line 480 def keep_alive @env[Merb::Const::HTTP_KEEP_ALIVE] end |
#matched! ⇒ Object
Sets the request as matched. This will abort evaluating any further deferred procs.
:api: private
160 161 162 |
# File 'lib/merb-core/dispatch/request.rb', line 160 def matched! @matched = true end |
#matched? ⇒ Boolean
Checks whether or not the request has been matched to a route.
:api: private
167 168 169 |
# File 'lib/merb-core/dispatch/request.rb', line 167 def matched? @matched end |
#message ⇒ Object
Returns
- String
-
Returns the redirect message Base64 unencoded.
:api: public
324 325 326 327 328 329 330 331 |
# File 'lib/merb-core/dispatch/request.rb', line 324 def return {} unless params[:_message] begin Marshal.load(params[:_message].unpack("m").first) rescue ArgumentError, TypeError {} end end |
#method ⇒ Object
Returns
- Symbol
-
The name of the request method, e.g. :get.
Notes
If the method is post, then the blocks specified in http_method_overrides will be checked for the masquerading method. The block will get the controller yielded to it. The first matching workaround wins. To disable this behavior, set http_method_overrides = []
:api: public
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/merb-core/dispatch/request.rb', line 105 def method @method ||= begin request_method = @env[Merb::Const::REQUEST_METHOD].downcase.to_sym case request_method when :get, :head, :put, :delete, :options request_method when :post m = nil self.class.http_method_overrides.each do |o| m ||= o.call(self); break if m end m.downcase! if m METHODS.include?(m) ? m.to_sym : :post else raise "Unknown REQUEST_METHOD: #{@env[Merb::Const::REQUEST_METHOD]}" end end end |
#params ⇒ Object
Returns
- Mash
-
All request parameters.
Notes
The order of precedence for the params is XML, JSON, multipart, body and request string.
:api: public
310 311 312 313 314 315 316 317 318 |
# File 'lib/merb-core/dispatch/request.rb', line 310 def params @params ||= begin h = body_and_query_params.merge(route_params) h.merge!(multipart_params) if self.class.parse_multipart_params && multipart_params h.merge!(json_params) if self.class.parse_json_params && json_params h.merge!(xml_params) if self.class.parse_xml_params && xml_params h end end |
#path ⇒ Object
Returns
- String
-
The URI without the query string. Strips trailing “/” and reduces duplicate “/” to a single “/”.
:api: public
554 555 556 557 558 559 560 |
# File 'lib/merb-core/dispatch/request.rb', line 554 def path # Merb::Const::SLASH is / # Merb::Const::QUESTION_MARK is ? path = (uri.empty? ? Merb::Const::SLASH : uri.split(Merb::Const::QUESTION_MARK).first).squeeze(Merb::Const::SLASH) path = path[0..-2] if (path[-1] == ?/) && path.size > 1 path end |
#path_info ⇒ Object
Returns
- String
-
The path info.
:api: public
566 567 568 |
# File 'lib/merb-core/dispatch/request.rb', line 566 def path_info @path_info ||= Merb::Parse.unescape(@env[Merb::Const::PATH_INFO]) end |
#port ⇒ Object
Returns
- Fixnum
-
The server port.
:api: public
574 575 576 |
# File 'lib/merb-core/dispatch/request.rb', line 574 def port @env[Merb::Const::SERVER_PORT].to_i end |
#protocol ⇒ Object
Returns
- String
-
The protocol, i.e. either “https” or “http” depending on the HTTPS header.
:api: public
384 385 386 |
# File 'lib/merb-core/dispatch/request.rb', line 384 def protocol ssl? ? Merb::Const::HTTPS : Merb::Const::HTTP end |
#query_string ⇒ Object
Returns
- String
-
The query string.
:api: private
528 529 530 |
# File 'lib/merb-core/dispatch/request.rb', line 528 def query_string @env[Merb::Const::QUERY_STRING] end |
#rack_response ⇒ Object
Returns
- (Array, Hash)
-
the route params for the matched route.
Notes
If the response is an Array then it is considered a direct Rack response to be sent back as a response. Otherwise, the route_params is a Hash with routing data (controller, action, et al).
:api: private
180 181 182 |
# File 'lib/merb-core/dispatch/request.rb', line 180 def rack_response @route_params end |
#raw_post ⇒ Object
Returns
- String
-
The raw post.
:api: private
345 346 347 348 |
# File 'lib/merb-core/dispatch/request.rb', line 345 def raw_post @body.rewind if @body.respond_to?(:rewind) @raw_post ||= @body.read end |
#referer ⇒ Object
Returns
- String
-
The HTTP referer.
:api: public
400 401 402 |
# File 'lib/merb-core/dispatch/request.rb', line 400 def referer @env[Merb::Const::HTTP_REFERER] end |
#remote_ip ⇒ Object
Returns
- String
-
The remote IP address.
:api: public
364 365 366 367 368 369 370 371 372 373 374 375 376 |
# File 'lib/merb-core/dispatch/request.rb', line 364 def remote_ip return @env[Merb::Const::HTTP_CLIENT_IP] if @env.include?(Merb::Const::HTTP_CLIENT_IP) if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip| ip =~ Merb::Const::LOCAL_IP_REGEXP end return remote_ips.first.strip unless remote_ips.empty? end return @env[Merb::Const::REMOTE_ADDR] end |
#reset_params! ⇒ Object
Notes
Resets the params to a nil value.
:api: private
337 338 339 |
# File 'lib/merb-core/dispatch/request.rb', line 337 def reset_params! @params = nil end |
#script_name ⇒ Object
Returns
- String
-
The script name.
:api: public
448 449 450 |
# File 'lib/merb-core/dispatch/request.rb', line 448 def script_name @env[Merb::Const::SCRIPT_NAME] end |
#server_name ⇒ Object
Returns
- String
-
The server name.
:api: public
432 433 434 |
# File 'lib/merb-core/dispatch/request.rb', line 432 def server_name @env[Merb::Const::SERVER_NAME] end |
#server_software ⇒ Object
Returns
- String
-
The server software.
:api: public
472 473 474 |
# File 'lib/merb-core/dispatch/request.rb', line 472 def server_software @env[Merb::Const::SERVER_SOFTWARE] end |
#ssl? ⇒ Boolean
Returns
- Boolean:
-
True if the request is an SSL request.
:api: public
392 393 394 |
# File 'lib/merb-core/dispatch/request.rb', line 392 def ssl? @env[Merb::Const::UPCASE_HTTPS] == 'on' || @env[Merb::Const::HTTP_X_FORWARDED_PROTO] == Merb::Const::HTTPS end |
#subdomains(tld_length = 1) ⇒ Object
Parameters
- tld_length<Fixnum>
-
Number of domains levels to inlclude in the top level domain. Defaults to 1.
Returns
- Array
-
All the subdomain parts of the host.
:api: public
596 597 598 599 |
# File 'lib/merb-core/dispatch/request.rb', line 596 def subdomains(tld_length = 1) parts = host.split(Merb::Const::DOT) parts[0..-(tld_length+2)] end |
#uri ⇒ Object
Returns
- String
-
The request URI.
:api: public
416 417 418 |
# File 'lib/merb-core/dispatch/request.rb', line 416 def uri @env[Merb::Const::REQUEST_PATH] || @env[Merb::Const::REQUEST_URI] || path_info end |
#user_agent ⇒ Object
Returns
- String
-
The HTTP user agent.
:api: public
424 425 426 |
# File 'lib/merb-core/dispatch/request.rb', line 424 def user_agent @env[Merb::Const::HTTP_USER_AGENT] end |
#version ⇒ Object
Returns
- String
-
The HTTP version
:api: private
496 497 498 |
# File 'lib/merb-core/dispatch/request.rb', line 496 def version @env[Merb::Const::HTTP_VERSION] end |
#xml_http_request? ⇒ Boolean Also known as: xhr?, ajax?
Returns
- Boolean
-
If the request is an XML HTTP request.
:api: public
354 355 356 |
# File 'lib/merb-core/dispatch/request.rb', line 354 def xml_http_request? not Merb::Const::XML_HTTP_REQUEST_REGEXP.match(@env[Merb::Const::HTTP_X_REQUESTED_WITH]).nil? end |