Class: Merb::Request
Direct Known Subclasses
Constant Summary collapse
- METHODS =
%w{get post put delete head}
- 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, ~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 = '&;') ⇒ 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.
-
#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.
-
#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.
18 19 20 21 22 |
# File 'lib/merb-core/dispatch/request.rb', line 18 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
5 6 7 |
# File 'lib/merb-core/dispatch/request.rb', line 5 def env @env end |
#route_params ⇒ Object
def env def session def route_params
5 6 7 |
# File 'lib/merb-core/dispatch/request.rb', line 5 def route_params @route_params end |
#session ⇒ Object
def env def session def route_params
5 6 7 |
# File 'lib/merb-core/dispatch/request.rb', line 5 def session @session end |
Class Method Details
.escape(s) ⇒ Object
Parameters
- s<String>
-
String to URL escape.
returns
- String
-
The escaped string.
407 408 409 410 411 |
# File 'lib/merb-core/dispatch/request.rb', line 407 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
543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'lib/merb-core/dispatch/request.rb', line 543 def normalize_params(parms, name, val=nil) name =~ %r([\[\]]*([^\[\]]+)\]*) key = $1 || '' after = $' || '' if after == "" parms[key] = val elsif after == "[]" (parms[key] ||= []) << 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, ~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"
387 388 389 390 391 392 393 394 395 396 397 398 399 400 |
# File 'lib/merb-core/dispatch/request.rb', line 387 def params_to_query_string(value, prefix = nil) case value when Array value.map { |v| params_to_query_string(v, "#{prefix}[]") } * "&" when Hash 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.
457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 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 |
# File 'lib/merb-core/dispatch/request.rb', line 457 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) 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 = '&;') ⇒ Object
Parameters
- qs<String>
-
The query string.
- d<String>
-
The query string divider. Defaults to “&”.
Returns
- Mash
-
The parsed query string.
Examples
query_parse("bar=nik&post[body]=heya")
# => { :bar => "nik", :post => { :body => "heya" } }
434 435 436 437 438 439 |
# File 'lib/merb-core/dispatch/request.rb', line 434 def query_parse(qs, d = '&;') (qs||'').split(/[#{d}] */n).inject({}) { |h,p| key, value = unescape(p).split('=',2) normalize_params(h, key, value) }.to_mash end |
.unescape(s) ⇒ Object
Parameter
- s<String>
-
String to URL unescape.
returns
- String
-
The unescaped string.
418 419 420 421 422 |
# File 'lib/merb-core/dispatch/request.rb', line 418 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 “/”.
287 288 289 |
# File 'lib/merb-core/dispatch/request.rb', line 287 def accept @env['HTTP_ACCEPT'].blank? ? "*/*" : @env['HTTP_ACCEPT'] end |
#accept_charset ⇒ Object
Returns
- String
-
The accepted character sets.
269 270 271 |
# File 'lib/merb-core/dispatch/request.rb', line 269 def accept_charset @env['HTTP_ACCEPT_CHARSET'] end |
#accept_encoding ⇒ Object
Returns
- String
-
The accepted encodings.
233 234 235 |
# File 'lib/merb-core/dispatch/request.rb', line 233 def accept_encoding @env['HTTP_ACCEPT_ENCODING'] end |
#accept_language ⇒ Object
Returns
- String
-
The accepted language.
251 252 253 |
# File 'lib/merb-core/dispatch/request.rb', line 251 def accept_language @env['HTTP_ACCEPT_LANGUAGE'] end |
#cache_control ⇒ Object
Returns
- String
-
HTTP cache control.
245 246 247 |
# File 'lib/merb-core/dispatch/request.rb', line 245 def cache_control @env['HTTP_CACHE_CONTROL'] end |
#connection ⇒ Object
Returns
- String
-
The HTTP connection.
293 294 295 |
# File 'lib/merb-core/dispatch/request.rb', line 293 def connection @env['HTTP_CONNECTION'] end |
#content_length ⇒ Object
Returns
- Fixnum
-
The request content length.
311 312 313 |
# File 'lib/merb-core/dispatch/request.rb', line 311 def content_length @content_length ||= @env[Merb::Const::CONTENT_LENGTH].to_i end |
#content_type ⇒ Object
Returns
- String
-
The request content type.
305 306 307 |
# File 'lib/merb-core/dispatch/request.rb', line 305 def content_type @env['CONTENT_TYPE'] end |
#cookies ⇒ Object
Returns
- Hash
-
The cookies for this request.
158 159 160 |
# File 'lib/merb-core/dispatch/request.rb', line 158 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.
362 363 364 |
# File 'lib/merb-core/dispatch/request.rb', line 362 def domain(tld_length = 1) host.split('.').last(1 + tld_length).join('.').sub(/:\d+$/,'') end |
#gateway ⇒ Object
Returns
- String
-
The gateway.
281 282 283 |
# File 'lib/merb-core/dispatch/request.rb', line 281 def gateway @env['GATEWAY_INTERFACE'] end |
#host ⇒ Object
Returns
- String
-
The full hostname including the port.
339 340 341 |
# File 'lib/merb-core/dispatch/request.rb', line 339 def host @env['HTTP_X_FORWARDED_HOST'] || @env['HTTP_HOST'] end |
#keep_alive ⇒ Object
Returns
- String
-
Value of HTTP_KEEP_ALIVE.
263 264 265 |
# File 'lib/merb-core/dispatch/request.rb', line 263 def keep_alive @env['HTTP_KEEP_ALIVE'] end |
#method ⇒ Object
Returns
- Symbol
-
The name of the request method, e.g. :get.
Notes
If the method is post, then the _method
param will be checked for masquerading method.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/merb-core/dispatch/request.rb', line 32 def method @method ||= begin request_method = @env['REQUEST_METHOD'].downcase.to_sym case request_method when :get, :head, :put, :delete request_method when :post if self.class.parse_multipart_params m = body_and_query_params.merge(multipart_params)['_method'] else m = body_and_query_params['_method'] 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.
141 142 143 144 145 146 147 148 149 |
# File 'lib/merb-core/dispatch/request.rb', line 141 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 “/”.
319 320 321 322 323 |
# File 'lib/merb-core/dispatch/request.rb', line 319 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.
327 328 329 |
# File 'lib/merb-core/dispatch/request.rb', line 327 def path_info @path_info ||= self.class.unescape(@env['PATH_INFO']) end |
#port ⇒ Object
Returns
- Fixnum
-
The server port.
333 334 335 |
# File 'lib/merb-core/dispatch/request.rb', line 333 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.
197 198 199 |
# File 'lib/merb-core/dispatch/request.rb', line 197 def protocol ssl? ? 'https://' : 'http://' end |
#query_string ⇒ Object
Returns
- String
-
The query string.
299 300 301 |
# File 'lib/merb-core/dispatch/request.rb', line 299 def query_string @env['QUERY_STRING'] end |
#raw_post ⇒ Object
Returns
- String
-
The raw post.
164 165 166 167 |
# File 'lib/merb-core/dispatch/request.rb', line 164 def raw_post @body.rewind if @body.respond_to?(:rewind) @raw_post ||= @body.read end |
#referer ⇒ Object
Returns
- String
-
The HTTP referer.
209 210 211 |
# File 'lib/merb-core/dispatch/request.rb', line 209 def referer @env['HTTP_REFERER'] end |
#remote_ip ⇒ Object
Returns
- String
-
The remote IP address.
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/merb-core/dispatch/request.rb', line 179 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.
152 153 154 |
# File 'lib/merb-core/dispatch/request.rb', line 152 def reset_params! @params = nil end |
#script_name ⇒ Object
Returns
- String
-
The script name.
239 240 241 |
# File 'lib/merb-core/dispatch/request.rb', line 239 def script_name @env['SCRIPT_NAME'] end |
#server_name ⇒ Object
Returns
- String
-
The server name.
227 228 229 |
# File 'lib/merb-core/dispatch/request.rb', line 227 def server_name @env['SERVER_NAME'] end |
#server_software ⇒ Object
Returns
- String
-
The server software.
257 258 259 |
# File 'lib/merb-core/dispatch/request.rb', line 257 def server_software @env['SERVER_SOFTWARE'] end |
#ssl? ⇒ Boolean
Returns
- Boolean:
-
True if the request is an SSL request.
203 204 205 |
# File 'lib/merb-core/dispatch/request.rb', line 203 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.
350 351 352 353 |
# File 'lib/merb-core/dispatch/request.rb', line 350 def subdomains(tld_length = 1) parts = host.split('.') parts[0..-(tld_length+2)] end |
#uri ⇒ Object
Returns
- String
-
The request URI.
215 216 217 |
# File 'lib/merb-core/dispatch/request.rb', line 215 def uri @env['REQUEST_URI'] || @env['REQUEST_PATH'] end |
#user_agent ⇒ Object
Returns
- String
-
The HTTP user agent.
221 222 223 |
# File 'lib/merb-core/dispatch/request.rb', line 221 def user_agent @env['HTTP_USER_AGENT'] end |
#version ⇒ Object
Returns
- String
-
The HTTP version
275 276 277 |
# File 'lib/merb-core/dispatch/request.rb', line 275 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.
171 172 173 |
# File 'lib/merb-core/dispatch/request.rb', line 171 def xml_http_request? not /XMLHttpRequest/i.match(@env['HTTP_X_REQUESTED_WITH']).nil? end |