module Rack::Request::Helpers
Constants
- AUTHORITY
- DEFAULT_PORTS
Default ports depending on scheme. Used to decide whether or not to include the port in a generated URI.
- FORM_DATA_MEDIA_TYPES
The set of form-data media-types. Requests that do not indicate one of the media types present in this list will not be eligible for form-data / param parsing.
- HTTP_X_FORWARDED_FOR
The address of the client which connected to the proxy.
- HTTP_X_FORWARDED_HOST
The contents of the host/:authority header sent to the proxy.
- HTTP_X_FORWARDED_PORT
The port used to connect to the proxy.
- HTTP_X_FORWARDED_PROTO
The protocol used to connect to the proxy.
- HTTP_X_FORWARDED_SCHEME
The value of the scheme sent to the proxy.
- HTTP_X_FORWARDED_SSL
Another way for specifing https scheme was used.
- PARSEABLE_DATA_MEDIA_TYPES
The set of media-types. Requests that do not indicate one of the media types present in this list will not be eligible for param parsing like soap attachments or generic multiparts
Public Instance Methods
Returns the data received in the query string.
# File lib/rack/request.rb, line 425 def GET if get_header(RACK_REQUEST_QUERY_STRING) == query_string get_header(RACK_REQUEST_QUERY_HASH) else query_hash = parse_query(query_string, '&;') set_header(RACK_REQUEST_QUERY_STRING, query_string) set_header(RACK_REQUEST_QUERY_HASH, query_hash) end end
Returns the data received in the request body.
This method support both application/x-www-form-urlencoded and multipart/form-data.
# File lib/rack/request.rb, line 439 def POST if get_header(RACK_INPUT).nil? raise "Missing rack.input" elsif get_header(RACK_REQUEST_FORM_INPUT) == get_header(RACK_INPUT) get_header(RACK_REQUEST_FORM_HASH) elsif form_data? || parseable_data? unless set_header(RACK_REQUEST_FORM_HASH, parse_multipart) form_vars = get_header(RACK_INPUT).read # Fix for Safari Ajax postings that always append \0 # form_vars.sub!(/\0\z/, '') # performance replacement: form_vars.slice!(-1) if form_vars.end_with?("\0") set_header RACK_REQUEST_FORM_VARS, form_vars set_header RACK_REQUEST_FORM_HASH, parse_query(form_vars, '&') get_header(RACK_INPUT).rewind end set_header RACK_REQUEST_FORM_INPUT, get_header(RACK_INPUT) get_header RACK_REQUEST_FORM_HASH else {} end end
shortcut for request.params[key]
# File lib/rack/request.rb, line 531 def [](key) if $VERBOSE warn("Request#[] is deprecated and will be removed in a future version of Rack. Please use request.params[] instead") end params[key.to_s] end
shortcut for request.params[key] = value
Note that modifications will not be persisted in the env. Use #update_param or #delete_param if you want to destructively modify params.
# File lib/rack/request.rb, line 542 def []=(key, value) if $VERBOSE warn("Request#[]= is deprecated and will be removed in a future version of Rack. Please use request.params[]= instead") end params[key.to_s] = value end
# File lib/rack/request.rb, line 518 def accept_encoding parse_http_accept_header(get_header("HTTP_ACCEPT_ENCODING")) end
# File lib/rack/request.rb, line 522 def accept_language parse_http_accept_header(get_header("HTTP_ACCEPT_LANGUAGE")) end
# File lib/rack/request.rb, line 501 def base_url "#{scheme}://#{host_with_port}" end
# File lib/rack/request.rb, line 149 def body; get_header(RACK_INPUT) end
The character set of the request body if a “charset” media type parameter was given, or nil if no “charset” was specified. Note that, per RFC2616, text/* media types that specify no explicit charset are to be considered ISO-8859-1.
# File lib/rack/request.rb, line 399 def content_charset media_type_params['charset'] end
# File lib/rack/request.rb, line 158 def content_length; get_header('CONTENT_LENGTH') end
# File lib/rack/request.rb, line 270 def content_type content_type = get_header('CONTENT_TYPE') content_type.nil? || content_type.empty? ? nil : content_type end
Checks the HTTP request method (or verb) to see if it was of type DELETE
# File lib/rack/request.rb, line 180 def delete?; request_method == DELETE end
Destructively delete a parameter, whether it's in #GET or #POST. Returns the value of the deleted parameter.
If the parameter is in both #GET and #POST, the #POST value takes precedence since that's how params works.
env['rack.input']
is not touched.
# File lib/rack/request.rb, line 496 def delete_param(k) post_value, get_value = self.POST.delete(k), self.GET.delete(k) post_value || get_value end
Determine whether the request body contains form-data by checking the
request Content-Type for one of the media-types:
“application/x-www-form-urlencoded” or “multipart/form-data”. The list of
form-data media types can be modified through the
FORM_DATA_MEDIA_TYPES
array.
A request body is also assumed to contain form-data when no Content-Type header is provided and the #request_method is #POST.
# File lib/rack/request.rb, line 411 def form_data? type = media_type meth = get_header(RACK_METHODOVERRIDE_ORIGINAL_METHOD) || get_header(REQUEST_METHOD) (meth == POST && type.nil?) || FORM_DATA_MEDIA_TYPES.include?(type) end
# File lib/rack/request.rb, line 329 def forwarded_for if value = get_header(HTTP_X_FORWARDED_FOR) split_header(value).map do |authority| split_authority(wrap_ipv6(authority))[1] end end end
# File lib/rack/request.rb, line 337 def forwarded_port if value = get_header(HTTP_X_FORWARDED_PORT) split_header(value).map(&:to_i) end end
# File lib/rack/request.rb, line 514 def fullpath query_string.empty? ? path : "#{path}?#{query_string}" end
Checks the HTTP request method (or verb) to see if it was of type #GET
# File lib/rack/request.rb, line 183 def get?; request_method == GET end
Checks the HTTP request method (or verb) to see if it was of type HEAD
# File lib/rack/request.rb, line 186 def head?; request_method == HEAD end
Returns a formatted host, suitable for being used in a URI.
# File lib/rack/request.rb, line 295 def host split_authority(self.authority)[0] end
# File lib/rack/request.rb, line 284 def host_with_port(authority = self.authority) host, _, port = split_authority(authority) if port == DEFAULT_PORTS[self.scheme] host else authority end end
Returns an address suitable for being to resolve to an address. In the case
of a domain name or IPv4 address, the result is the same as
host
. In the case of IPv6 or future address formats, the
square brackets are removed.
# File lib/rack/request.rb, line 303 def hostname split_authority(self.authority)[1] end
# File lib/rack/request.rb, line 353 def ip remote_addresses = split_header(get_header('REMOTE_ADDR')) external_addresses = reject_trusted_ip_addresses(remote_addresses) unless external_addresses.empty? return external_addresses.first end if forwarded_for = self.forwarded_for unless forwarded_for.empty? # The forwarded for addresses are ordered: client, proxy1, proxy2. # So we reject all the trusted addresses (proxy*) and return the # last client. Or if we trust everyone, we just return the first # address. return reject_trusted_ip_addresses(forwarded_for).last || forwarded_for.first end end # If all the addresses are trusted, and we aren't forwarded, just return # the first remote address, which represents the source of the request. remote_addresses.first end
Checks the HTTP request method (or verb) to see if it was of type LINK
# File lib/rack/request.rb, line 192 def link?; request_method == LINK end
# File lib/rack/request.rb, line 159 def logger; get_header(RACK_LOGGER) end
The media type (type/subtype) portion of the CONTENT_TYPE header without any media type parameters. e.g., when CONTENT_TYPE is “text/plain;charset=utf-8”, the media-type is “text/plain”.
For more information on the use of media types in HTTP, see: www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
# File lib/rack/request.rb, line 382 def media_type MediaType.type(content_type) end
The media type parameters provided in CONTENT_TYPE as a Hash, or an empty Hash if no CONTENT_TYPE or media-type parameters were provided. e.g., when the CONTENT_TYPE is “text/plain;charset=utf-8”, this method responds with the following Hash:
{ 'charset' => 'utf-8' }
# File lib/rack/request.rb, line 391 def media_type_params MediaType.params(content_type) end
# File lib/rack/request.rb, line 161 def multithread?; get_header(RACK_MULTITHREAD) end
Checks the HTTP request method (or verb) to see if it was of type OPTIONS
# File lib/rack/request.rb, line 189 def options?; request_method == OPTIONS end
The union of #GET and #POST data.
Note that modifications will not be persisted in the env. Use #update_param or #delete_param if you want to destructively modify params.
# File lib/rack/request.rb, line 467 def params self.GET.merge(self.POST) end
Determine whether the request body contains data by checking the request #media_type against registered parse-data media-types
# File lib/rack/request.rb, line 420 def parseable_data? PARSEABLE_DATA_MEDIA_TYPES.include?(media_type) end
Checks the HTTP request method (or verb) to see if it was of type PATCH
# File lib/rack/request.rb, line 195 def patch?; request_method == PATCH end
# File lib/rack/request.rb, line 510 def path script_name + path_info end
# File lib/rack/request.rb, line 153 def path_info; get_header(PATH_INFO).to_s end
# File lib/rack/request.rb, line 154 def path_info=(s); set_header(PATH_INFO, s.to_s) end
# File lib/rack/request.rb, line 307 def port if authority = self.authority _, _, port = split_authority(self.authority) if port return port end end if forwarded_port = self.forwarded_port return forwarded_port.first end if scheme = self.scheme if port = DEFAULT_PORTS[self.scheme] return port end end self.server_port end
Checks the HTTP request method (or verb) to see if it was of type #POST
# File lib/rack/request.rb, line 198 def post?; request_method == POST end
Checks the HTTP request method (or verb) to see if it was of type PUT
# File lib/rack/request.rb, line 201 def put?; request_method == PUT end
# File lib/rack/request.rb, line 157 def query_string; get_header(QUERY_STRING).to_s end
the referer of the client
# File lib/rack/request.rb, line 164 def referer; get_header('HTTP_REFERER') end
# File lib/rack/request.rb, line 156 def request_method; get_header(REQUEST_METHOD) end
# File lib/rack/request.rb, line 209 def scheme if get_header(HTTPS) == 'on' 'https' elsif get_header(HTTP_X_FORWARDED_SSL) == 'on' 'https' elsif forwarded_scheme forwarded_scheme else get_header(RACK_URL_SCHEME) end end
# File lib/rack/request.rb, line 150 def script_name; get_header(SCRIPT_NAME).to_s end
# File lib/rack/request.rb, line 151 def script_name=(s); set_header(SCRIPT_NAME, s.to_s) end
# File lib/rack/request.rb, line 245 def server_name get_header(SERVER_NAME) end
# File lib/rack/request.rb, line 249 def server_port if port = get_header(SERVER_PORT) Integer(port) end end
# File lib/rack/request.rb, line 167 def session fetch_header(RACK_SESSION) do |k| set_header RACK_SESSION, default_session end end
# File lib/rack/request.rb, line 173 def session_options fetch_header(RACK_SESSION_OPTIONS) do |k| set_header RACK_SESSION_OPTIONS, {} end end
# File lib/rack/request.rb, line 349 def ssl? scheme == 'https' || scheme == 'wss' end
Checks the HTTP request method (or verb) to see if it was of type TRACE
# File lib/rack/request.rb, line 204 def trace?; request_method == TRACE end
# File lib/rack/request.rb, line 526 def trusted_proxy?(ip) Rack::Request.ip_filter.call(ip) end
Checks the HTTP request method (or verb) to see if it was of type UNLINK
# File lib/rack/request.rb, line 207 def unlink?; request_method == UNLINK end
Destructively update a parameter, whether it's in #GET and/or #POST. Returns nil.
The parameter is updated wherever it was previous defined, so #GET, #POST, or both. If it wasn't previously defined, it's inserted into #GET.
env['rack.input']
is not touched.
# File lib/rack/request.rb, line 476 def update_param(k, v) found = false if self.GET.has_key?(k) found = true self.GET[k] = v end if self.POST.has_key?(k) found = true self.POST[k] = v end unless found self.GET[k] = v end end
Tries to return a remake of the original request URL as a string.
# File lib/rack/request.rb, line 506 def url base_url + fullpath end
# File lib/rack/request.rb, line 160 def user_agent; get_header('HTTP_USER_AGENT') end
like Hash#values_at
# File lib/rack/request.rb, line 551 def values_at(*keys) keys.map { |key| params[key] } end
# File lib/rack/request.rb, line 275 def xhr? get_header("HTTP_X_REQUESTED_WITH") == "XMLHttpRequest" end
Private Instance Methods
# File lib/rack/request.rb, line 640 def allowed_scheme(header) header if ALLOWED_SCHEMES.include?(header) end
# File lib/rack/request.rb, line 557 def default_session; {}; end
# File lib/rack/request.rb, line 644 def extract_proto_header(header) if header if (comma_index = header.index(',')) header[0, comma_index] else header end end end
# File lib/rack/request.rb, line 635 def forwarded_scheme allowed_scheme(get_header(HTTP_X_FORWARDED_SCHEME)) || allowed_scheme(extract_proto_header(get_header(HTTP_X_FORWARDED_PROTO))) end
# File lib/rack/request.rb, line 573 def parse_http_accept_header(header) header.to_s.split(/\s*,\s*/).map do |part| attribute, parameters = part.split(/\s*;\s*/, 2) quality = 1.0 if parameters and /\Aq=([\d.]+)/ =~ parameters quality = $1.to_f end [attribute, quality] end end
# File lib/rack/request.rb, line 592 def parse_multipart Rack::Multipart.extract_multipart(self, query_parser) end
# File lib/rack/request.rb, line 588 def parse_query(qs, d = '&') query_parser.parse_nested_query(qs, d) end
# File lib/rack/request.rb, line 584 def query_parser Utils.default_query_parser end
# File lib/rack/request.rb, line 631 def reject_trusted_ip_addresses(ip_addresses) ip_addresses.reject { |ip| trusted_proxy?(ip) } end
# File lib/rack/request.rb, line 596 def split_header(value) value ? value.strip.split(/[,\s]+/) : [] end
Assist with compatibility when processing `X-Forwarded-For`.
# File lib/rack/request.rb, line 560 def wrap_ipv6(host) # Even thought IPv6 addresses should be wrapped in square brackets, # sometimes this is not done in various legacy/underspecified headers. # So we try to fix this situation for compatibility reasons. # Try to detect IPv6 addresses which aren't escaped yet: if !host.start_with?('[') && host.count(':') > 1 "[#{host}]" else host end end