Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 258 lines (215 sloc) 8.741 kb
d2ed32d @jeremy Parse url-encoded and multipart requests ourselves instead of delegating...
jeremy authored
1 require 'tempfile'
2 require 'stringio'
3 require 'strscan'
4
e8550ee @jeremy Cherry-pick core extensions
jeremy authored
5 require 'active_support/core_ext/hash/indifferent_access'
e1b5e3c Break up inflector to reduce the dependency burden on dependency-les met...
Yehuda Katz authored
6 require 'active_support/core_ext/string/access'
d446392 @pixeltrix Add additional HTTP request methods from the following RFCs:
pixeltrix authored
7 require 'active_support/inflector'
018dafe @josh Allow autoloads to opt out of eager loading
josh authored
8 require 'action_dispatch/http/headers'
525fd3a @vatrai TODO fix explicitly loading exceptations, autoload removed
vatrai authored
9 require 'action_controller/metal/exceptions'
0a9bc59 @technoweenie Raise UnknownHttpMethod exception for unknown HTTP methods. Closes #1030...
technoweenie authored
10
319ae46 @josh Move HTTP libs and middleware into ActionDispatch component
josh authored
11 module ActionDispatch
e1f73aa @josh Inherit ActionController::Request from Rack::Request
josh authored
12 class Request < Rack::Request
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
13 include ActionDispatch::Http::Cache::Request
14 include ActionDispatch::Http::MimeNegotiation
15 include ActionDispatch::Http::Parameters
31fddf2 @josevalim Tidy up new filter_parameters implementation.
josevalim authored
16 include ActionDispatch::Http::FilterParameters
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
17 include ActionDispatch::Http::Upload
18 include ActionDispatch::Http::URL
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
19
5b88014 @dhh Only show dump of regular env methods on exception screen (not all the r...
dhh authored
20 LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze
21 ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
22 PATH_TRANSLATED REMOTE_HOST
e1f73aa @josh Inherit ActionController::Request from Rack::Request
josh authored
23 REMOTE_IDENT REMOTE_USER REMOTE_ADDR
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
24 SERVER_NAME SERVER_PROTOCOL
25
26 HTTP_ACCEPT HTTP_ACCEPT_CHARSET HTTP_ACCEPT_ENCODING
27 HTTP_ACCEPT_LANGUAGE HTTP_CACHE_CONTROL HTTP_FROM
5b88014 @dhh Only show dump of regular env methods on exception screen (not all the r...
dhh authored
28 HTTP_NEGOTIATE HTTP_PRAGMA ].freeze
d182b6e @joshk removed deprecated methods, and related tests, from ActionPack
joshk authored
29
5b88014 @dhh Only show dump of regular env methods on exception screen (not all the r...
dhh authored
30 ENV_METHODS.each do |env|
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
31 class_eval <<-METHOD, __FILE__, __LINE__ + 1
d8c77fa @vijaydev document meta method
vijaydev authored
32 def #{env.sub(/^HTTP_/n, '').downcase} # def accept_charset
33 @env["#{env}"] # @env["HTTP_ACCEPT_CHARSET"]
34 end # end
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
35 METHOD
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
36 end
37
38 def key?(key)
39 @env.key?(key)
40 end
41
d446392 @pixeltrix Add additional HTTP request methods from the following RFCs:
pixeltrix authored
42 # List of HTTP request methods from the following RFCs:
43 # Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt)
44 # HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt)
45 # Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt)
46 # Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
47 # Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
48 # Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
49 # PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
50 RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
51 RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
52 RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
53 RFC3648 = %w(ORDERPATCH)
54 RFC3744 = %w(ACL)
55 RFC5323 = %w(SEARCH)
56 RFC5789 = %w(PATCH)
57
58 HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
59 HTTP_METHOD_LOOKUP = Hash.new { |h, m| h[m] = m.underscore.to_sym if HTTP_METHODS.include?(m) }
b7529ed @jeremy Simplifying usage of ETags and Last-Modified and conditional GET request...
jeremy authored
60
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
61 # Returns the HTTP \method that the application should see.
62 # In the case where the \method was overridden by a middleware
63 # (for instance, if a HEAD request was converted to a GET,
64 # or if a _method parameter was used to determine the \method
65 # the application should use), this \method returns the overridden
66 # value, not the original.
0a9bc59 @technoweenie Raise UnknownHttpMethod exception for unknown HTTP methods. Closes #1030...
technoweenie authored
67 def request_method
78ac9c2 @tenderlove dry up method checking in the request object
tenderlove authored
68 @request_method ||= check_method(env["REQUEST_METHOD"])
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
69 end
70
71 # Returns a symbol form of the #request_method
72 def request_method_symbol
73 HTTP_METHOD_LOOKUP[request_method]
0a9bc59 @technoweenie Raise UnknownHttpMethod exception for unknown HTTP methods. Closes #1030...
technoweenie authored
74 end
75
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
76 # Returns the original value of the environment's REQUEST_METHOD,
77 # even if it was overridden by middleware. See #request_method for
78 # more information.
db045db @dhh Initial
dhh authored
79 def method
78ac9c2 @tenderlove dry up method checking in the request object
tenderlove authored
80 @method ||= check_method(env["rack.methodoverride.original_method"] || env['REQUEST_METHOD'])
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
81 end
82
83 # Returns a symbol form of the #method
84 def method_symbol
85 HTTP_METHOD_LOOKUP[method]
db045db @dhh Initial
dhh authored
86 end
87
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
88 # Is this a GET (or HEAD) request?
237272e @travisp Fix ActionDispatch::Request method explanations
travisp authored
89 # Equivalent to <tt>request.request_method_symbol == :get</tt>.
db045db @dhh Initial
dhh authored
90 def get?
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
91 HTTP_METHOD_LOOKUP[request_method] == :get
db045db @dhh Initial
dhh authored
92 end
93
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
94 # Is this a POST request?
237272e @travisp Fix ActionDispatch::Request method explanations
travisp authored
95 # Equivalent to <tt>request.request_method_symbol == :post</tt>.
db045db @dhh Initial
dhh authored
96 def post?
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
97 HTTP_METHOD_LOOKUP[request_method] == :post
db045db @dhh Initial
dhh authored
98 end
99
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
100 # Is this a PUT request?
237272e @travisp Fix ActionDispatch::Request method explanations
travisp authored
101 # Equivalent to <tt>request.request_method_symbol == :put</tt>.
db045db @dhh Initial
dhh authored
102 def put?
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
103 HTTP_METHOD_LOOKUP[request_method] == :put
db045db @dhh Initial
dhh authored
104 end
105
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
106 # Is this a DELETE request?
237272e @travisp Fix ActionDispatch::Request method explanations
travisp authored
107 # Equivalent to <tt>request.request_method_symbol == :delete</tt>.
db045db @dhh Initial
dhh authored
108 def delete?
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
109 HTTP_METHOD_LOOKUP[request_method] == :delete
db045db @dhh Initial
dhh authored
110 end
111
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
112 # Is this a HEAD request?
237272e @travisp Fix ActionDispatch::Request method explanations
travisp authored
113 # Equivalent to <tt>request.method_symbol == :head</tt>.
9492129 @dhh Added indifference to whether @headers["Content-Type"], @headers["Conten...
dhh authored
114 def head?
ab8bf9e @wycats * Change the object used in routing constraints to be an instance of
wycats authored
115 HTTP_METHOD_LOOKUP[method] == :head
9492129 @dhh Added indifference to whether @headers["Content-Type"], @headers["Conten...
dhh authored
116 end
db11abb @dhh Added support for POST data in form of YAML or XML, which is controller ...
dhh authored
117
0432d15 @lifo Merge with docrails.
lifo authored
118 # Provides access to the request's HTTP headers, for example:
6ef3546 @lifo Merge docrails
lifo authored
119 #
120 # request.headers["Content-Type"] # => "text/plain"
2e55095 @dhh Added that rendering will automatically insert the etag header on 200 OK...
dhh authored
121 def headers
319ae46 @josh Move HTTP libs and middleware into ActionDispatch component
josh authored
122 Http::Headers.new(@env)
2e55095 @dhh Added that rendering will automatically insert the etag header on 200 OK...
dhh authored
123 end
124
79b12a0 @drogus Add original_fullpath and original_url methods to Request
drogus authored
125 def original_fullpath
126 @original_fullpath ||= (env["ORIGINAL_FULLPATH"] || fullpath)
127 end
128
ab1407c @wycats Improve performance of commonly used request methods
wycats authored
129 def fullpath
130 @fullpath ||= super
131 end
132
79b12a0 @drogus Add original_fullpath and original_url methods to Request
drogus authored
133 def original_url
134 base_url + original_fullpath
135 end
136
b69da86 @josh Remove vendored version of Rack
josh authored
137 def media_type
77a2a3d @wycats Request#content_type exists in Rack::Request, and other parts of Rack::R...
wycats authored
138 content_mime_type.to_s
b69da86 @josh Remove vendored version of Rack
josh authored
139 end
140
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
141 # Returns the content length of the request as an integer.
142 def content_length
143 super.to_i
12cf8f3 @NZKoz Move template_format logic out to the request so it's alongside the 'reg...
NZKoz authored
144 end
145
0aa66f0 @fxn gets rid of a double negation, no need to force exactly true/false in a ...
fxn authored
146 # Returns true if the "X-Requested-With" header contains "XMLHttpRequest"
147 # (case-insensitive). All major JavaScript libraries send this header with
148 # every Ajax request.
0367317 @dhh Deprecated redirect_to_path and redirect_to_url in favor of letting redi...
dhh authored
149 def xml_http_request?
0aa66f0 @fxn gets rid of a double negation, no need to force exactly true/false in a ...
fxn authored
150 @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
0367317 @dhh Deprecated redirect_to_path and redirect_to_url in favor of letting redi...
dhh authored
151 end
3e8ba61 @josevalim Refactor even more Responder. Move mime negotiation to request and added...
josevalim authored
152 alias :xhr? :xml_http_request?
0367317 @dhh Deprecated redirect_to_path and redirect_to_url in favor of letting redi...
dhh authored
153
ab1407c @wycats Improve performance of commonly used request methods
wycats authored
154 def ip
155 @ip ||= super
156 end
157
9432163 @indirect refactor RemoteIp middleware
indirect authored
158 # Originating IP address, usually set by the RemoteIp middleware.
db045db @dhh Initial
dhh authored
159 def remote_ip
ab1407c @wycats Improve performance of commonly used request methods
wycats authored
160 @remote_ip ||= (@env["action_dispatch.remote_ip"] || ip).to_s
db045db @dhh Initial
dhh authored
161 end
162
afde6fd @dhh Added X-Request-Id tracking and TaggedLogging to easily log that and oth...
dhh authored
163 # Returns the unique request id, which is based off either the X-Request-Id header that can
164 # be generated by a firewall, load balancer, or web server or by the RequestId middleware
165 # (which sets the action_dispatch.request_id environment variable).
166 #
167 # This unique ID is useful for tracing a request from end-to-end as part of logging or debugging.
168 # This relies on the rack variable set by the ActionDispatch::RequestId middleware.
169 def uuid
170 @uuid ||= env["action_dispatch.request_id"]
171 end
172
e0179c1 @dhh Added Request#url that returns the complete URL used for the request [DH...
dhh authored
173 # Returns the lowercase name of the HTTP server software.
174 def server_software
175 (@env['SERVER_SOFTWARE'] && /^([a-zA-Z]+)/ =~ @env['SERVER_SOFTWARE']) ? $1.downcase : nil
176 end
177
6ef3546 @lifo Merge docrails
lifo authored
178 # Read the request \body. This is useful for web services that need to
4bd3e3a @jeremy Set RAW_POST_DATA when request parameters are parsed.
jeremy authored
179 # work with raw requests directly.
e0179c1 @dhh Added Request#url that returns the complete URL used for the request [DH...
dhh authored
180 def raw_post
ff0a267 @josh Build query string and POST params parser on top of Rack::Request. Also ...
josh authored
181 unless @env.include? 'RAW_POST_DATA'
182 @env['RAW_POST_DATA'] = body.read(@env['CONTENT_LENGTH'].to_i)
183 body.rewind if body.respond_to?(:rewind)
184 end
185 @env['RAW_POST_DATA']
61960e7 @dhh Added Request#port_string to get something like ":8080" back on 8080 and...
dhh authored
186 end
187
ff0a267 @josh Build query string and POST params parser on top of Rack::Request. Also ...
josh authored
188 # The request body is an IO input stream. If the RAW_POST_DATA environment
189 # variable is already set, wrap it in a StringIO.
b7529ed @jeremy Simplifying usage of ETags and Last-Modified and conditional GET request...
jeremy authored
190 def body
ff0a267 @josh Build query string and POST params parser on top of Rack::Request. Also ...
josh authored
191 if raw_post = @env['RAW_POST_DATA']
192 raw_post.force_encoding(Encoding::BINARY) if raw_post.respond_to?(:force_encoding)
193 StringIO.new(raw_post)
194 else
195 @env['rack.input']
196 end
197 end
198
199 def form_data?
77a2a3d @wycats Request#content_type exists in Rack::Request, and other parts of Rack::R...
wycats authored
200 FORM_DATA_MEDIA_TYPES.include?(content_mime_type.to_s)
b7529ed @jeremy Simplifying usage of ETags and Last-Modified and conditional GET request...
jeremy authored
201 end
540d005 @jeremy Improved AbstractRequest documentation. Closes #1483.
jeremy authored
202
b7529ed @jeremy Simplifying usage of ETags and Last-Modified and conditional GET request...
jeremy authored
203 def body_stream #:nodoc:
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
204 @env['rack.input']
db045db @dhh Initial
dhh authored
205 end
206
a12b76b @josevalim Just reading flash messages should not create a session if one does not ...
josevalim authored
207 # TODO This should be broken apart into AD::Request::Session and probably
208 # be included by the session middleware.
0494909 @josh Inherit TestSession from Session::AbstractStore and add indifferent acce...
josh authored
209 def reset_session
653acac @josevalim Solve some warnings and a failing test.
josevalim authored
210 session.destroy if session && session.respond_to?(:destroy)
0494909 @josh Inherit TestSession from Session::AbstractStore and add indifferent acce...
josh authored
211 self.session = {}
a12b76b @josevalim Just reading flash messages should not create a session if one does not ...
josevalim authored
212 @env['action_dispatch.request.flash_hash'] = nil
db045db @dhh Initial
dhh authored
213 end
214
7654082 @jeremy Major components cleanup and speedup. Closes #3527.
jeremy authored
215 def session=(session) #:nodoc:
db619c4 @wycats Sync 'rails/rails/master'
wycats authored
216 @env['rack.session'] = session
7654082 @jeremy Major components cleanup and speedup. Closes #3527.
jeremy authored
217 end
218
293bb02 @lifo Unify ActionController::AbstractRequest and ActionController::Request
lifo authored
219 def session_options=(options)
220 @env['rack.session.options'] = options
221 end
222
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
223 # Override Rack's GET method to support indifferent access
224 def GET
3eff729 make sure request parameters are accessible after rack throws an excepti...
Miles Egan authored
225 @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {})
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
226 end
227 alias :query_parameters :GET
228
229 # Override Rack's POST method to support indifferent access
230 def POST
3eff729 make sure request parameters are accessible after rack throws an excepti...
Miles Egan authored
231 @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {})
92f49b5 @josevalim Split ActionDispatch http in smaller chunks.
josevalim authored
232 end
233 alias :request_parameters :POST
234
235
cf9d6a9 @dhh Added ActionDispatch::Request#authorization to access the http authentic...
dhh authored
236 # Returns the authorization header regardless of whether it was specified directly or through one of the
237 # proxy alternatives.
238 def authorization
239 @env['HTTP_AUTHORIZATION'] ||
240 @env['X-HTTP_AUTHORIZATION'] ||
241 @env['X_HTTP_AUTHORIZATION'] ||
242 @env['REDIRECT_X_HTTP_AUTHORIZATION']
243 end
9198885 @spastorino Moves local_request? to require.local?
spastorino authored
244
245 # True if the request came from localhost, 127.0.0.1.
246 def local?
247 LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip }
248 end
78ac9c2 @tenderlove dry up method checking in the request object
tenderlove authored
249
250 private
251
252 def check_method(name)
253 HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS.to_sentence(:locale => :en)}")
254 name
255 end
52ca5da @jeremy Use StringIO and Tempfile subclasses instead of defining singleton metho...
jeremy authored
256 end
0ee1cb2 @jeremy Ruby 1.9 compat, consistent load paths
jeremy authored
257 end
Something went wrong with that request. Please try again.