Class: Merb::Request
Direct Known Subclasses
Constant Summary collapse
- METHODS =
%w{get post put delete head options}
- NAME_REGEX =
/Content-Disposition:.* name="?([^\";]*)"?/ni.freeze
- CONTENT_TYPE_REGEX =
/Content-Type: (.*)\r\n/ni.freeze
- FILENAME_REGEX =
/Content-Disposition:.* filename="?([^\";]*)"?/ni.freeze
- CRLF =
"\r\n".freeze
- EOL =
CRLF
Instance Attribute Summary collapse
-
#env ⇒ Object
def env def session def route_params.
-
#route_params ⇒ Object
def env def session def route_params.
-
#session ⇒ Object
def env def session def route_params.
Class Method Summary collapse
-
.escape(s) ⇒ Object
Parameters s<String>:: String to URL escape.
-
.normalize_params(parms, name, val = nil) ⇒ Object
Converts a query string snippet to a hash and adds it to existing parameters.
-
.params_to_query_string(value, prefix = nil) ⇒ Object
Parameters value<Array, Hash, Dictionary ~to_s>:: The value for the query string.
-
.parse_multipart(request, boundary, content_length) ⇒ Object
Parameters request<IO>:: The raw request.
-
.query_parse(qs, d = '&;', preserve_order = false) ⇒ Object
Parameters qs<String>:: The query string.
-
.unescape(s) ⇒ Object
Parameter s<String>:: String to URL unescape.
Instance Method Summary collapse
-
#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.
-
#cookies ⇒ Object
Returns Hash:: The cookies for this request.
-
#domain(tld_length = 1) ⇒ Object
Parameters tld_length<Fixnum>:: Number of domains levels to inlclude in the top level domain.
-
#full_uri ⇒ Object
Returns String:: The full URI, including protocol and host.
-
#gateway ⇒ Object
Returns String:: The gateway.
-
#host ⇒ Object
Returns String:: The full hostname including the port.
-
#initialize(rack_env) ⇒ Request
constructor
Initial the request object.
-
#keep_alive ⇒ Object
Returns String:: Value of HTTP_KEEP_ALIVE.
- #message ⇒ Object
-
#method ⇒ Object
Returns Symbol:: The name of the request method, e.g.
-
#params ⇒ Object
Returns Hash:: 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.
-
#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
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
Initial the request object.
Parameters
- http_request<~params:~[], ~body:IO>
-
An object like an HTTP Request.
31 32 33 34 35 |
# File 'lib/merb-core/dispatch/request.rb', line 31 def initialize(rack_env) @env = rack_env @body = rack_env['rack.input'] @route_params = {} end |
Instance Attribute Details
#env ⇒ Object
def env def session def route_params
7 8 9 |
# File 'lib/merb-core/dispatch/request.rb', line 7 def env @env end |
#route_params ⇒ Object
def env def session def route_params
7 8 9 |
# File 'lib/merb-core/dispatch/request.rb', line 7 def route_params @route_params end |
#session ⇒ Object
def env def session def route_params
7 8 9 |
# File 'lib/merb-core/dispatch/request.rb', line 7 def session @session end |
Class Method Details
.escape(s) ⇒ Object
Parameters
- s<String>
-
String to URL escape.
returns
- String
-
The escaped string.
443 444 445 446 447 |
# File 'lib/merb-core/dispatch/request.rb', line 443 def escape(s) s.to_s.gsub(/([^ a-zA-Z0-9_.-]+)/n) { '%'+$1.unpack('H2'*$1.size).join('%').upcase }.tr(' ', '+') end |
.normalize_params(parms, name, val = nil) ⇒ Object
Converts a query string snippet to a hash and adds it to existing parameters.
Parameters
- parms<Hash>
-
Parameters to add the normalized parameters to.
- name<String>
-
The key of the parameter to normalize.
- val<String>
-
The value of the parameter.
Returns
- Hash
-
Normalized parameters
583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/merb-core/dispatch/request.rb', line 583 def normalize_params(parms, name, val=nil) name =~ %r([\[\]]*([^\[\]]+)\]*) key = $1 || '' after = $' || '' if after == "" parms[key] = val elsif after == "[]" (parms[key] ||= []) << val elsif after =~ %r(^\[\]) parms[key] ||= [] parms[key] << normalize_params({}, after, val) else parms[key] ||= {} parms[key] = normalize_params(parms[key], after, val) end parms end |
.params_to_query_string(value, prefix = nil) ⇒ Object
Parameters
- value<Array, Hash, Dictionary ~to_s>
-
The value for the query string.
- prefix<~to_s>
-
The prefix to add to the query string keys.
Returns
- String
-
The query string.
Alternatives
If the value is a string, the prefix will be used as the key.
Examples
params_to_query_string(10, "page")
# => "page=10"
params_to_query_string({ :page => 10, :word => "ruby" })
# => "page=10&word=ruby"
params_to_query_string({ :page => 10, :word => "ruby" }, "search")
# => "search[page]=10&search[word]=ruby"
params_to_query_string([ "ice-cream", "cake" ], "shopping_list")
# => "shopping_list[]=ice-cream&shopping_list[]=cake"
423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/merb-core/dispatch/request.rb', line 423 def params_to_query_string(value, prefix = nil) case value when Array value.map { |v| params_to_query_string(v, "#{prefix}[]") } * "&" when Hash, Dictionary value.map { |k, v| params_to_query_string(v, prefix ? "#{prefix}[#{Merb::Request.escape(k)}]" : Merb::Request.escape(k)) } * "&" else "#{prefix}=#{Merb::Request.escape(value)}" end end |
.parse_multipart(request, boundary, content_length) ⇒ Object
Parameters
- request<IO>
-
The raw request.
- boundary<String>
-
The boundary string.
- content_length<Fixnum>
-
The length of the content.
Raises
- ControllerExceptions::MultiPartParseError
-
Failed to parse request.
Returns
- Hash
-
The parsed request.
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
# File 'lib/merb-core/dispatch/request.rb', line 496 def parse_multipart(request, boundary, content_length) boundary = "--#{boundary}" paramhsh = {} buf = "" input = request input.binmode if defined? input.binmode boundary_size = boundary.size + EOL.size bufsize = 16384 content_length -= boundary_size status = input.read(boundary_size) return {} if status == nil || status.empty? raise ControllerExceptions::MultiPartParseError, "bad content body:\n'#{status}' should == '#{boundary + EOL}'" unless status == boundary + EOL rx = /(?:#{EOL})?#{Regexp.quote(boundary,'n')}(#{EOL}|--)/ loop { head = nil body = '' filename = content_type = name = nil read_size = 0 until head && buf =~ rx i = buf.index("\r\n\r\n") if( i == nil && read_size == 0 && content_length == 0 ) content_length = -1 break end if !head && i head = buf.slice!(0, i+2) # First \r\n buf.slice!(0, 2) # Second \r\n filename = head[FILENAME_REGEX, 1] content_type = head[CONTENT_TYPE_REGEX, 1] name = head[NAME_REGEX, 1] if filename && !filename.empty? body = Tempfile.new(:Merb) body.binmode if defined? body.binmode end next end # Save the read body part. if head && (boundary_size+4 < buf.size) body << buf.slice!(0, buf.size - (boundary_size+4)) end read_size = bufsize < content_length ? bufsize : content_length if( read_size > 0 ) c = input.read(read_size) raise ControllerExceptions::MultiPartParseError, "bad content body" if c.nil? || c.empty? buf << c content_length -= c.size end end # Save the rest. if i = buf.index(rx) body << buf.slice!(0, i) buf.slice!(0, boundary_size+2) content_length = -1 if $1 == "--" end if filename && !filename.empty? body.rewind data = { :filename => File.basename(filename), :content_type => content_type, :tempfile => body, :size => File.size(body.path) } else data = body end paramhsh = normalize_params(paramhsh,name,data) break if buf.empty? || content_length == -1 } paramhsh end |
.query_parse(qs, d = '&;', preserve_order = false) ⇒ Object
Parameters
- qs<String>
-
The query string.
- d<String>
-
The query string divider. Defaults to “&”.
- preserve_order<Boolean>
-
Preserve order of args. Defaults to false.
Returns
- Mash
-
The parsed query string (Dictionary if preserve_order is set).
Examples
query_parse("bar=nik&post[body]=heya")
# => { :bar => "nik", :post => { :body => "heya" } }
471 472 473 474 475 476 477 478 |
# File 'lib/merb-core/dispatch/request.rb', line 471 def query_parse(qs, d = '&;', preserve_order = false) qh = preserve_order ? Dictionary.new : {} (qs||'').split(/[#{d}] */n).inject(qh) { |h,p| key, value = unescape(p).split('=',2) normalize_params(h, key, value) } preserve_order ? qh : qh.to_mash end |
.unescape(s) ⇒ Object
Parameter
- s<String>
-
String to URL unescape.
returns
- String
-
The unescaped string.
454 455 456 457 458 |
# File 'lib/merb-core/dispatch/request.rb', line 454 def unescape(s) s.tr('+', ' ').gsub(/((?:%[0-9a-fA-F]{2})+)/n){ [$1.delete('%')].pack('H*') } end |
Instance Method Details
#accept ⇒ Object
Returns
- String
-
The accepted response types. Defaults to “/”.
323 324 325 |
# File 'lib/merb-core/dispatch/request.rb', line 323 def accept @env['HTTP_ACCEPT'].blank? ? "*/*" : @env['HTTP_ACCEPT'] end |
#accept_charset ⇒ Object
Returns
- String
-
The accepted character sets.
305 306 307 |
# File 'lib/merb-core/dispatch/request.rb', line 305 def accept_charset @env['HTTP_ACCEPT_CHARSET'] end |
#accept_encoding ⇒ Object
Returns
- String
-
The accepted encodings.
269 270 271 |
# File 'lib/merb-core/dispatch/request.rb', line 269 def accept_encoding @env['HTTP_ACCEPT_ENCODING'] end |
#accept_language ⇒ Object
Returns
- String
-
The accepted language.
287 288 289 |
# File 'lib/merb-core/dispatch/request.rb', line 287 def accept_language @env['HTTP_ACCEPT_LANGUAGE'] end |
#cache_control ⇒ Object
Returns
- String
-
HTTP cache control.
281 282 283 |
# File 'lib/merb-core/dispatch/request.rb', line 281 def cache_control @env['HTTP_CACHE_CONTROL'] end |
#connection ⇒ Object
Returns
- String
-
The HTTP connection.
329 330 331 |
# File 'lib/merb-core/dispatch/request.rb', line 329 def connection @env['HTTP_CONNECTION'] end |
#content_length ⇒ Object
Returns
- Fixnum
-
The request content length.
347 348 349 |
# File 'lib/merb-core/dispatch/request.rb', line 347 def content_length @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i end |
#content_type ⇒ Object
Returns
- String
-
The request content type.
341 342 343 |
# File 'lib/merb-core/dispatch/request.rb', line 341 def content_type @env['CONTENT_TYPE'] end |
#cookies ⇒ Object
Returns
- Hash
-
The cookies for this request.
188 189 190 |
# File 'lib/merb-core/dispatch/request.rb', line 188 def @cookies ||= self.class.query_parse(@env[Merb::Const::HTTP_COOKIE], ';,') 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.
398 399 400 |
# File 'lib/merb-core/dispatch/request.rb', line 398 def domain(tld_length = 1) host.split('.').last(1 + tld_length).join('.').sub(/:\d+$/,'') end |
#full_uri ⇒ Object
Returns
- String
-
The full URI, including protocol and host
245 246 247 |
# File 'lib/merb-core/dispatch/request.rb', line 245 def full_uri protocol + host + uri end |
#gateway ⇒ Object
Returns
- String
-
The gateway.
317 318 319 |
# File 'lib/merb-core/dispatch/request.rb', line 317 def gateway @env['GATEWAY_INTERFACE'] end |
#host ⇒ Object
Returns
- String
-
The full hostname including the port.
375 376 377 |
# File 'lib/merb-core/dispatch/request.rb', line 375 def host @env['HTTP_X_FORWARDED_HOST'] || @env['HTTP_HOST'] end |
#keep_alive ⇒ Object
Returns
- String
-
Value of HTTP_KEEP_ALIVE.
299 300 301 |
# File 'lib/merb-core/dispatch/request.rb', line 299 def keep_alive @env['HTTP_KEEP_ALIVE'] end |
#message ⇒ Object
172 173 174 175 176 177 178 179 |
# File 'lib/merb-core/dispatch/request.rb', line 172 def return {} unless params[:_message] begin Marshal.load(Merb::Request.unescape(params[:_message]).unpack("m").first) rescue ArgumentError {} 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 = []
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/merb-core/dispatch/request.rb', line 47 def method @method ||= begin request_method = @env['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['REQUEST_METHOD']}" end end end |
#params ⇒ Object
Returns
- Hash
-
All request parameters.
Notes
The order of precedence for the params is XML, JSON, multipart, body and request string.
162 163 164 165 166 167 168 169 170 |
# File 'lib/merb-core/dispatch/request.rb', line 162 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 “/”.
355 356 357 358 359 |
# File 'lib/merb-core/dispatch/request.rb', line 355 def path path = (uri.empty? ? '/' : uri.split('?').first).squeeze("/") path = path[0..-2] if (path[-1] == ?/) && path.size > 1 path end |
#path_info ⇒ Object
Returns
- String
-
The path info.
363 364 365 |
# File 'lib/merb-core/dispatch/request.rb', line 363 def path_info @path_info ||= self.class.unescape(@env['PATH_INFO']) end |
#port ⇒ Object
Returns
- Fixnum
-
The server port.
369 370 371 |
# File 'lib/merb-core/dispatch/request.rb', line 369 def port @env['SERVER_PORT'].to_i end |
#protocol ⇒ Object
Returns
- String
-
The protocol, i.e. either “https://” or “http://” depending on the HTTPS header.
227 228 229 |
# File 'lib/merb-core/dispatch/request.rb', line 227 def protocol ssl? ? 'https://' : 'http://' end |
#query_string ⇒ Object
Returns
- String
-
The query string.
335 336 337 |
# File 'lib/merb-core/dispatch/request.rb', line 335 def query_string @env['QUERY_STRING'] end |
#raw_post ⇒ Object
Returns
- String
-
The raw post.
194 195 196 197 |
# File 'lib/merb-core/dispatch/request.rb', line 194 def raw_post @body.rewind if @body.respond_to?(:rewind) @raw_post ||= @body.read end |
#referer ⇒ Object
Returns
- String
-
The HTTP referer.
239 240 241 |
# File 'lib/merb-core/dispatch/request.rb', line 239 def referer @env['HTTP_REFERER'] end |
#remote_ip ⇒ Object
Returns
- String
-
The remote IP address.
209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/merb-core/dispatch/request.rb', line 209 def remote_ip return @env['HTTP_CLIENT_IP'] if @env.include?('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 =~ /^unknown$|^(127|10|172\.16|192\.168)\./i end return remote_ips.first.strip unless remote_ips.empty? end return @env[Merb::Const::REMOTE_ADDR] end |
#reset_params! ⇒ Object
Resets the params to a nil value.
182 183 184 |
# File 'lib/merb-core/dispatch/request.rb', line 182 def reset_params! @params = nil end |
#script_name ⇒ Object
Returns
- String
-
The script name.
275 276 277 |
# File 'lib/merb-core/dispatch/request.rb', line 275 def script_name @env['SCRIPT_NAME'] end |
#server_name ⇒ Object
Returns
- String
-
The server name.
263 264 265 |
# File 'lib/merb-core/dispatch/request.rb', line 263 def server_name @env['SERVER_NAME'] end |
#server_software ⇒ Object
Returns
- String
-
The server software.
293 294 295 |
# File 'lib/merb-core/dispatch/request.rb', line 293 def server_software @env['SERVER_SOFTWARE'] end |
#ssl? ⇒ Boolean
Returns
- Boolean:
-
True if the request is an SSL request.
233 234 235 |
# File 'lib/merb-core/dispatch/request.rb', line 233 def ssl? @env['HTTPS'] == 'on' || @env['HTTP_X_FORWARDED_PROTO'] == '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.
386 387 388 389 |
# File 'lib/merb-core/dispatch/request.rb', line 386 def subdomains(tld_length = 1) parts = host.split('.') parts[0..-(tld_length+2)] end |
#uri ⇒ Object
Returns
- String
-
The request URI.
251 252 253 |
# File 'lib/merb-core/dispatch/request.rb', line 251 def uri @env['REQUEST_PATH'] || @env['REQUEST_URI'] end |
#user_agent ⇒ Object
Returns
- String
-
The HTTP user agent.
257 258 259 |
# File 'lib/merb-core/dispatch/request.rb', line 257 def user_agent @env['HTTP_USER_AGENT'] end |
#version ⇒ Object
Returns
- String
-
The HTTP version
311 312 313 |
# File 'lib/merb-core/dispatch/request.rb', line 311 def version @env['HTTP_VERSION'] end |
#xml_http_request? ⇒ Boolean Also known as: xhr?, ajax?
Returns
- Boolean
-
If the request is an XML HTTP request.
201 202 203 |
# File 'lib/merb-core/dispatch/request.rb', line 201 def xml_http_request? not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil? end |