Initialize the request object.
http_request<~params:~[], ~body:IO> | An object like an HTTP Request. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 36 36: def initialize(rack_env) 37: @env = rack_env 38: @body = rack_env[Merb::Const::RACK_INPUT] 39: @route_params = {} 40: end
Memoizes the new request object into env so we can memoize things into ivars in the request
env | A rack environment |
*args | Other arguments passed to the superclass |
Merb::Request | The new Merb::Request |
:api: public
# File lib/merb-core/dispatch/request.rb, line 53 53: def self.new(env, *args) 54: if self == Merb::Request 55: env["merb.request"] ||= super 56: else 57: super 58: end 59: end
Processes the return value of a deferred router block and returns the current route params for the current request evaluation
:api: private
# File lib/merb-core/dispatch/request.rb, line 147 147: def _process_block_return(retval) 148: # If the return value is an array, then it is a redirect 149: # so we must set the request as a redirect and extract 150: # the redirect params and return it as a hash so that the 151: # dispatcher can handle it 152: matched! if retval.is_a?(Array) 153: retval 154: end
String | The accepted response types. Defaults to “/“. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 512 512: def accept 513: @env[Merb::Const::HTTP_ACCEPT].blank? ? "*/*" : @env[Merb::Const::HTTP_ACCEPT] 514: end
String | The accepted character sets. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 488 488: def accept_charset 489: @env[Merb::Const::HTTP_ACCEPT_CHARSET] 490: end
String | The accepted encodings. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 440 440: def accept_encoding 441: @env[Merb::Const::HTTP_ACCEPT_ENCODING] 442: end
String | The accepted language. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 464 464: def accept_language 465: @env[Merb::Const::HTTP_ACCEPT_LANGUAGE] 466: end
String | HTTP cache control. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 456 456: def cache_control 457: @env[Merb::Const::HTTP_CACHE_CONTROL] 458: end
String | The HTTP connection. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 520 520: def connection 521: @env[Merb::Const::HTTP_CONNECTION] 522: end
Fixnum | The request content length. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 544 544: def content_length 545: @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i 546: end
String | The request content type. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 536 536: def content_type 537: @env[Merb::Const::UPCASE_CONTENT_TYPE] 538: end
Returns the controller object for initialization and dispatching the request.
Class | The controller class matching the routed request, |
e.g. Posts.
:api: private
# File lib/merb-core/dispatch/request.rb, line 69 69: def controller 70: unless params[:controller] 71: raise ControllerExceptions::NotFound, 72: "Route matched, but route did not specify a controller.\n" + 73: "Did you forgot to add :controller => \"people\" or :controller " + 74: "segment to route definition?\nHere is what's specified:\n" + 75: route.inspect 76: end 77: path = [params[:namespace], params[:controller]].compact.join(Merb::Const::SLASH) 78: controller = path.snake_case.to_const_string 79: 80: begin 81: Object.full_const_get(controller) 82: rescue NameError => e 83: msg = "Controller class not found for controller `#{path}'" 84: Merb.logger.warn!(msg) 85: raise ControllerExceptions::NotFound, msg 86: end 87: end
tld_length | Number of domains levels to inlclude in the top level domain. Defaults to 1. |
String | The full domain name without the port number. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 610 610: def domain(tld_length = 1) 611: host.split(Merb::Const::DOT).last(1 + tld_length).join(Merb::Const::DOT).sub(/:\d+$/,'') 612: end
# File lib/merb-core/dispatch/request.rb, line 89 89: def exceptions 90: env["merb.exceptions"] 91: end
Find route using requested URI and merges route parameters (:action, :controller and named segments) into request params hash.
:api: private
# File lib/merb-core/dispatch/request.rb, line 136 136: def find_route! 137: @route, @route_params = Merb::Router.route_for(self) 138: params.merge! @route_params if @route_params.is_a?(Hash) 139: end
String | The full URI, including protocol and host |
:api: public
# File lib/merb-core/dispatch/request.rb, line 408 408: def full_uri 409: protocol + "://" + host + uri 410: end
String | The gateway. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 504 504: def gateway 505: @env[Merb::Const::GATEWAY_INTERFACE] 506: end
Handles request routing and action dispatch
@return [Array[Integer, Hash, #]] A Rack response
@api private
# File lib/merb-core/dispatch/dispatcher.rb, line 46 46: def handle 47: @start = env["merb.request_start"] = Time.now 48: Merb.logger.info { "Started request handling: #{start.to_s}" } 49: 50: find_route! 51: return rack_response if handled? 52: 53: klass = controller 54: 55: unless klass < Controller 56: raise NotFound, 57: "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" 58: end 59: 60: Merb.logger.debug { "Routed to: #{klass::_filter_params(params).inspect}" } 61: 62: if klass.abstract? 63: raise NotFound, "The '#{klass}' controller has no public actions" 64: end 65: 66: dispatch_action(klass, params[:action]) 67: rescue Object => exception 68: dispatch_exception(exception) 69: end
If @route_params is an Array, then it will be the rack response. In this case, the request is considered handled.
Boolean | true if @route_params is an Array, false otherwise. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 191 191: def handled? 192: @route_params.is_a?(Array) 193: end
String | The full hostname including the port. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 582 582: def host 583: @env[Merb::Const::HTTP_X_FORWARDED_HOST] || @env[Merb::Const::HTTP_HOST] || 584: @env[Merb::Const::SERVER_NAME] 585: end
Value of If-Modified-Since request header.
:api: private
# File lib/merb-core/dispatch/request.rb, line 626 626: def if_modified_since 627: if time = @env[Merb::Const::HTTP_IF_MODIFIED_SINCE] 628: Time.rfc2822(time) 629: end 630: end
Value of If-None-Match request header.
:api: private
# File lib/merb-core/dispatch/request.rb, line 618 618: def if_none_match 619: @env[Merb::Const::HTTP_IF_NONE_MATCH] 620: end
String | Value of HTTP_KEEP_ALIVE. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 480 480: def keep_alive 481: @env[Merb::Const::HTTP_KEEP_ALIVE] 482: end
Sets the request as matched. This will abort evaluating any further deferred procs.
:api: private
# File lib/merb-core/dispatch/request.rb, line 160 160: def matched! 161: @matched = true 162: end
Checks whether or not the request has been matched to a route.
:api: private
# File lib/merb-core/dispatch/request.rb, line 167 167: def matched? 168: @matched 169: end
String | Returns the redirect message Base64 unencoded. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 324 324: def message 325: return {} unless params[:_message] 326: begin 327: Marshal.load(params[:_message].unpack("m").first) 328: rescue ArgumentError, TypeError 329: {} 330: end 331: end
Symbol | The name of the request method, e.g. :get. |
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
# File lib/merb-core/dispatch/request.rb, line 105 105: def method 106: @method ||= begin 107: request_method = @env[Merb::Const::REQUEST_METHOD].downcase.to_sym 108: case request_method 109: when :get, :head, :put, :delete, :options 110: request_method 111: when :post 112: m = nil 113: self.class.http_method_overrides.each do |o| 114: m ||= o.call(self); break if m 115: end 116: m.downcase! if m 117: METHODS.include?(m) ? m.to_sym : :post 118: else 119: raise "Unknown REQUEST_METHOD: #{@env[Merb::Const::REQUEST_METHOD]}" 120: end 121: end 122: end
Mash | All request parameters. |
The order of precedence for the params is XML, JSON, multipart, body and request string.
:api: public
# File lib/merb-core/dispatch/request.rb, line 310 310: def params 311: @params ||= begin 312: h = body_and_query_params.merge(route_params) 313: h.merge!(multipart_params) if self.class.parse_multipart_params && multipart_params 314: h.merge!(json_params) if self.class.parse_json_params && json_params 315: h.merge!(xml_params) if self.class.parse_xml_params && xml_params 316: h 317: end 318: end
String | The URI without the query string. Strips trailing “/” and reduces duplicate “/” to a single “/”. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 554 554: def path 555: # Merb::Const::SLASH is / 556: # Merb::Const::QUESTION_MARK is ? 557: path = (uri.empty? ? Merb::Const::SLASH : uri.split(Merb::Const::QUESTION_MARK).first).squeeze(Merb::Const::SLASH) 558: path = path[0..2] if (path[1] == //) && path.size > 1 559: path 560: end
String | The path info. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 566 566: def path_info 567: @path_info ||= Merb::Parse.unescape(@env[Merb::Const::PATH_INFO]) 568: end
Fixnum | The server port. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 574 574: def port 575: @env[Merb::Const::SERVER_PORT].to_i 576: end
String | The protocol, i.e. either “https” or “http” depending on the HTTPS header. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 384 384: def protocol 385: ssl? ? Merb::Const::HTTPS : Merb::Const::HTTP 386: end
String | The query string. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 528 528: def query_string 529: @env[Merb::Const::QUERY_STRING] 530: end
(Array, Hash) | the route params for the matched route. |
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
# File lib/merb-core/dispatch/request.rb, line 180 180: def rack_response 181: @route_params 182: end
String | The raw post. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 345 345: def raw_post 346: @body.rewind if @body.respond_to?(:rewind) 347: @raw_post ||= @body.read 348: end
String | The HTTP referer. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 400 400: def referer 401: @env[Merb::Const::HTTP_REFERER] 402: end
String | The remote IP address. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 364 364: def remote_ip 365: return @env[Merb::Const::HTTP_CLIENT_IP] if @env.include?(Merb::Const::HTTP_CLIENT_IP) 366: 367: if @env.include?(Merb::Const::HTTP_X_FORWARDED_FOR) then 368: remote_ips = @env[Merb::Const::HTTP_X_FORWARDED_FOR].split(',').reject do |ip| 369: ip =~ Merb::Const::LOCAL_IP_REGEXP 370: end 371: 372: return remote_ips.first.strip unless remote_ips.empty? 373: end 374: 375: return @env[Merb::Const::REMOTE_ADDR] 376: end
Resets the params to a nil value.
:api: private
# File lib/merb-core/dispatch/request.rb, line 337 337: def reset_params! 338: @params = nil 339: end
String | The script name. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 448 448: def script_name 449: @env[Merb::Const::SCRIPT_NAME] 450: end
String | The server name. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 432 432: def server_name 433: @env[Merb::Const::SERVER_NAME] 434: end
String | The server software. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 472 472: def server_software 473: @env[Merb::Const::SERVER_SOFTWARE] 474: end
Boolean: | True if the request is an SSL request. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 392 392: def ssl? 393: @env[Merb::Const::UPCASE_HTTPS] == 'on' || @env[Merb::Const::HTTP_X_FORWARDED_PROTO] == Merb::Const::HTTPS 394: end
tld_length | Number of domains levels to inlclude in the top level domain. Defaults to 1. |
Array | All the subdomain parts of the host. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 596 596: def subdomains(tld_length = 1) 597: parts = host.split(Merb::Const::DOT) 598: parts[0..-(tld_length+2)] 599: end
String | The request URI. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 416 416: def uri 417: @env[Merb::Const::REQUEST_PATH] || @env[Merb::Const::REQUEST_URI] || path_info 418: end
String | The HTTP user agent. |
:api: public
# File lib/merb-core/dispatch/request.rb, line 424 424: def user_agent 425: @env[Merb::Const::HTTP_USER_AGENT] 426: end
String | The HTTP version |
:api: private
# File lib/merb-core/dispatch/request.rb, line 496 496: def version 497: @env[Merb::Const::HTTP_VERSION] 498: end
Mash | The parameters gathered from the query string and the request body, with parameters in the body taking precedence. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 231 231: def body_and_query_params 232: # ^-- FIXME a better name for this method 233: @body_and_query_params ||= begin 234: h = query_params 235: h.merge!(body_params) if body_params 236: h.to_mash 237: end 238: end
Parameters passed in the body of the request. Ajax calls from prototype.js and other libraries pass content this way.
Hash | The parameters passed in the body. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 217 217: def body_params 218: @body_params ||= begin 219: if content_type && content_type.match(Merb::Const::FORM_URL_ENCODED_REGEXP) # or content_type.nil? 220: Merb::Parse.query(raw_post) 221: end 222: end 223: end
Setup the controller and call the chosen action
@param klass [Merb::Controller] The controller class to dispatch to. @param action [Symbol] The action to dispatch. @param status [Integer] The status code to respond with.
@return [Array[Integer, Hash, #]] A Rack response
@api private
# File lib/merb-core/dispatch/dispatcher.rb, line 84 84: def dispatch_action(klass, action_name, status=200) 85: @env["merb.status"] = status 86: @env["merb.action_name"] = action_name 87: 88: if Dispatcher.use_mutex 89: @@mutex.synchronize { klass.call(env) } 90: else 91: klass.call(env) 92: end 93: end
Re-route the request to the Exception controller if it is available
You can handle exceptions by implementing actions for specific exceptions such as not_found or for entire classes of exceptions such as client_error. You can also implement handlers for exceptions outside the Merb exception hierarchy (e.g. StandardError is caught in standard_error).
@param exception [Object] The exception object that was created when
trying to dispatch the original controller.
@return [Array[Integer, Hash, #]] A Rack response
@api private
# File lib/merb-core/dispatch/dispatcher.rb, line 109 109: def dispatch_exception(exception) 110: if(exception.is_a?(Merb::ControllerExceptions::Base) && 111: !exception.is_a?(Merb::ControllerExceptions::ServerError)) 112: Merb.logger.info(Merb.exception(exception)) 113: else 114: Merb.logger.error(Merb.exception(exception)) 115: end 116: 117: exceptions = env["merb.exceptions"] = [exception] 118: 119: begin 120: e = exceptions.first 121: 122: if action_name = e.action_name 123: dispatch_action(Exceptions, action_name, e.class.status) 124: else 125: dispatch_action(Dispatcher::DefaultException, :index, e.class.status) 126: end 127: rescue Object => dispatch_issue 128: if e.same?(dispatch_issue) || exceptions.size > 5 129: dispatch_action(Dispatcher::DefaultException, :index, e.class.status) 130: else 131: Merb.logger.error("Dispatching #{e.class} raised another error.") 132: Merb.logger.error(Merb.exception(dispatch_issue)) 133: 134: exceptions.unshift dispatch_issue 135: retry 136: end 137: end 138: end
Hash | Parameters from body if this is a JSON request. |
If the JSON object parses as a Hash, it will be merged with the parameters hash. If it parses to anything else (such as an Array, or if it inflates to an Object) it will be accessible via the inflated_object parameter.
:api: private
# File lib/merb-core/dispatch/request.rb, line 274 274: def json_params 275: @json_params ||= begin 276: if Merb::Const::JSON_MIME_TYPE_REGEXP.match(content_type) 277: begin 278: jobj = JSON.parse(raw_post) 279: jobj = jobj.to_mash if jobj.is_a?(Hash) 280: rescue JSON::ParserError 281: jobj = Mash.new 282: end 283: jobj.is_a?(Hash) ? jobj : { :inflated_object => jobj } 284: end 285: end 286: end
ControllerExceptions::MultiPartParseError | Unable to parse the multipart form data. |
Hash | The parsed multipart parameters. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 248 248: def multipart_params 249: @multipart_params ||= 250: begin 251: # if the content-type is multipart 252: # parse the multipart. Otherwise return {} 253: if (Merb::Const::MULTIPART_REGEXP =~ content_type) 254: Merb::Parse.multipart(@body, $1, content_length) 255: else 256: {} 257: end 258: rescue ControllerExceptions::MultiPartParseError => e 259: @multipart_params = {} 260: raise e 261: end 262: end
Hash | Parameters passed from the URL like ?blah=hello. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 206 206: def query_params 207: @query_params ||= Merb::Parse.query(query_string || '') 208: end
Hash | Parameters from body if this is an XML request. |
:api: private
# File lib/merb-core/dispatch/request.rb, line 292 292: def xml_params 293: @xml_params ||= begin 294: if Merb::Const::XML_MIME_TYPE_REGEXP.match(content_type) 295: Hash.from_xml(raw_post) rescue Mash.new 296: end 297: end 298: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.