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.
-
#exceptions ⇒ Object
:api: public.
-
#route ⇒ Object
:api: private.
-
#route_params ⇒ Object
readonly
:api: private.
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.
-
#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 ⇒ Object
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
38 39 40 41 42 |
# File 'lib/merb-core/dispatch/request.rb', line 38 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 |
#exceptions ⇒ Object
:api: public
10 11 12 |
# File 'lib/merb-core/dispatch/request.rb', line 10 def exceptions @exceptions 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
12 13 14 |
# File 'lib/merb-core/dispatch/request.rb', line 12 def route_params @route_params 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
126 127 128 129 130 131 132 133 |
# File 'lib/merb-core/dispatch/request.rb', line 126 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
491 492 493 |
# File 'lib/merb-core/dispatch/request.rb', line 491 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
467 468 469 |
# File 'lib/merb-core/dispatch/request.rb', line 467 def accept_charset @env[Merb::Const::HTTP_ACCEPT_CHARSET] end |
#accept_encoding ⇒ Object
Returns
- String
-
The accepted encodings.
:api: private
419 420 421 |
# File 'lib/merb-core/dispatch/request.rb', line 419 def accept_encoding @env[Merb::Const::HTTP_ACCEPT_ENCODING] end |
#accept_language ⇒ Object
Returns
- String
-
The accepted language.
:api: public
443 444 445 |
# File 'lib/merb-core/dispatch/request.rb', line 443 def accept_language @env[Merb::Const::HTTP_ACCEPT_LANGUAGE] end |
#cache_control ⇒ Object
Returns
- String
-
HTTP cache control.
:api: public
435 436 437 |
# File 'lib/merb-core/dispatch/request.rb', line 435 def cache_control @env[Merb::Const::HTTP_CACHE_CONTROL] end |
#connection ⇒ Object
Returns
- String
-
The HTTP connection.
:api: private
499 500 501 |
# File 'lib/merb-core/dispatch/request.rb', line 499 def connection @env[Merb::Const::HTTP_CONNECTION] end |
#content_length ⇒ Object
Returns
- Fixnum
-
The request content length.
:api: public
523 524 525 |
# File 'lib/merb-core/dispatch/request.rb', line 523 def content_length @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i end |
#content_type ⇒ Object
Returns
- String
-
The request content type.
:api: private
515 516 517 |
# File 'lib/merb-core/dispatch/request.rb', line 515 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
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# File 'lib/merb-core/dispatch/request.rb', line 52 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
589 590 591 |
# File 'lib/merb-core/dispatch/request.rb', line 589 def domain(tld_length = 1) host.split(Merb::Const::DOT).last(1 + tld_length).join(Merb::Const::DOT).sub(/:\d+$/,'') 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
115 116 117 118 |
# File 'lib/merb-core/dispatch/request.rb', line 115 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
387 388 389 |
# File 'lib/merb-core/dispatch/request.rb', line 387 def full_uri protocol + "://" + host + uri end |
#gateway ⇒ Object
Returns
- String
-
The gateway.
:api: public
483 484 485 |
# File 'lib/merb-core/dispatch/request.rb', line 483 def gateway @env[Merb::Const::GATEWAY_INTERFACE] end |
#handle ⇒ Object
Handles request routing and action dispatch.
Returns
- Merb::Controller
-
the controller that handled the action dispatch.
:api: private
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/merb-core/dispatch/dispatcher.rb', line 52 def handle start = Time.now Merb.logger.info { "Started request handling: #{start.to_s}" } find_route! return rack_response if handled? klass = controller Merb.logger.debug { "Routed to: #{params.inspect}" } 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 if klass.abstract? raise NotFound, "The '#{klass}' controller has no public actions" end controller = dispatch_action(klass, params[:action]) controller._benchmarks[:dispatch_time] = Time.now - start Merb.logger.info { controller._benchmarks.inspect } Merb.logger.flush controller.rack_response rescue Object => exception dispatch_exception(exception).rack_response 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
170 171 172 |
# File 'lib/merb-core/dispatch/request.rb', line 170 def handled? @route_params.is_a?(Array) end |
#host ⇒ Object
Returns
- String
-
The full hostname including the port.
:api: public
561 562 563 564 |
# File 'lib/merb-core/dispatch/request.rb', line 561 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
605 606 607 608 609 |
# File 'lib/merb-core/dispatch/request.rb', line 605 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
597 598 599 |
# File 'lib/merb-core/dispatch/request.rb', line 597 def if_none_match @env[Merb::Const::HTTP_IF_NONE_MATCH] end |
#keep_alive ⇒ Object
Returns
- String
-
Value of HTTP_KEEP_ALIVE.
:api: public
459 460 461 |
# File 'lib/merb-core/dispatch/request.rb', line 459 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
139 140 141 |
# File 'lib/merb-core/dispatch/request.rb', line 139 def matched! @matched = true end |
#matched? ⇒ Boolean
Checks whether or not the request has been matched to a route.
:api: private
146 147 148 |
# File 'lib/merb-core/dispatch/request.rb', line 146 def matched? @matched end |
#message ⇒ Object
Returns
- String
-
Returns the redirect message Base64 unencoded.
:api: public
303 304 305 306 307 308 309 310 |
# File 'lib/merb-core/dispatch/request.rb', line 303 def return {} unless params[:_message] begin Marshal.load(Merb::Parse.unescape(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
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/merb-core/dispatch/request.rb', line 84 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
289 290 291 292 293 294 295 296 297 |
# File 'lib/merb-core/dispatch/request.rb', line 289 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
533 534 535 536 537 538 539 |
# File 'lib/merb-core/dispatch/request.rb', line 533 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
545 546 547 |
# File 'lib/merb-core/dispatch/request.rb', line 545 def path_info @path_info ||= Merb::Parse.unescape(@env[Merb::Const::PATH_INFO]) end |
#port ⇒ Object
Returns
- Fixnum
-
The server port.
:api: public
553 554 555 |
# File 'lib/merb-core/dispatch/request.rb', line 553 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
363 364 365 |
# File 'lib/merb-core/dispatch/request.rb', line 363 def protocol ssl? ? Merb::Const::HTTPS : Merb::Const::HTTP end |
#query_string ⇒ Object
Returns
- String
-
The query string.
:api: private
507 508 509 |
# File 'lib/merb-core/dispatch/request.rb', line 507 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
159 160 161 |
# File 'lib/merb-core/dispatch/request.rb', line 159 def rack_response @route_params end |
#raw_post ⇒ Object
Returns
- String
-
The raw post.
:api: private
324 325 326 327 |
# File 'lib/merb-core/dispatch/request.rb', line 324 def raw_post @body.rewind if @body.respond_to?(:rewind) @raw_post ||= @body.read end |
#referer ⇒ Object
Returns
- String
-
The HTTP referer.
:api: public
379 380 381 |
# File 'lib/merb-core/dispatch/request.rb', line 379 def referer @env[Merb::Const::HTTP_REFERER] end |
#remote_ip ⇒ Object
Returns
- String
-
The remote IP address.
:api: public
343 344 345 346 347 348 349 350 351 352 353 354 355 |
# File 'lib/merb-core/dispatch/request.rb', line 343 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
316 317 318 |
# File 'lib/merb-core/dispatch/request.rb', line 316 def reset_params! @params = nil end |
#script_name ⇒ Object
Returns
- String
-
The script name.
:api: public
427 428 429 |
# File 'lib/merb-core/dispatch/request.rb', line 427 def script_name @env[Merb::Const::SCRIPT_NAME] end |
#server_name ⇒ Object
Returns
- String
-
The server name.
:api: public
411 412 413 |
# File 'lib/merb-core/dispatch/request.rb', line 411 def server_name @env[Merb::Const::SERVER_NAME] end |
#server_software ⇒ Object
Returns
- String
-
The server software.
:api: public
451 452 453 |
# File 'lib/merb-core/dispatch/request.rb', line 451 def server_software @env[Merb::Const::SERVER_SOFTWARE] end |
#ssl? ⇒ Boolean
Returns
- Boolean:
-
True if the request is an SSL request.
:api: public
371 372 373 |
# File 'lib/merb-core/dispatch/request.rb', line 371 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
575 576 577 578 |
# File 'lib/merb-core/dispatch/request.rb', line 575 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
395 396 397 |
# File 'lib/merb-core/dispatch/request.rb', line 395 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
403 404 405 |
# File 'lib/merb-core/dispatch/request.rb', line 403 def user_agent @env[Merb::Const::HTTP_USER_AGENT] end |
#version ⇒ Object
Returns
- String
-
The HTTP version
:api: private
475 476 477 |
# File 'lib/merb-core/dispatch/request.rb', line 475 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
333 334 335 |
# File 'lib/merb-core/dispatch/request.rb', line 333 def xml_http_request? not Merb::Const::XML_HTTP_REQUEST_REGEXP.match(@env[Merb::Const::HTTP_X_REQUESTED_WITH]).nil? end |