308 status code introduced in https://tools.ietf.org/html/rfc7538
preserves the request method unlike 301 status code which would convert
POST requests to GET.
Prior to this commit, when multiple cookie domains were specified, the
first domain that was a substring of the request host was chosen. This
allowed, for example, the "example.com" domain to be chosen when the
request host was "example.com.au" or even "myexample.com".
This commit ensures a domain is chosen only if it is equal to or is a
superdomain of the request host.
Fixes#37760.
When using an external build process (webpack, grunt) it's helpful for
rails to be able to serve those assets. Brotli has better compression
than gzip and should eventually replace it for static assets.
When using an external build process (webpack, grunt) it's helpful for
rails to be able to serve those assets. Brotli has better compression
than gzip and will eventually replace it for static assets.
Rack decided to tolerate proxies which choose to attach ports to
X-Forwarded-For IPs by stripping the port:
https://github.com/rack/rack/pull/1251. Attaching a port is rare in the
wild but some proxies (notably Microsoft Azure's App Service) do it.
Without this patch, remote_ip will ignore X-Forwarded-For IPs with ports
attached and the return value is less likely to be useful.
Rails should do the same thing. The stripping logic is already available
in Rack::Request::Helpers, so change the X-Forwarded-For retrieval
method from ActionDispatch::Request#x_forwarded_for (which returns the
raw header) to #forwarded_for, which returns a stripped array of IP
addresses, or nil. There may be other benefits hiding in Rack's
implementation.
We can't call ips_from with an array (and legislating for that inside
ips_from doesn't appeal), so refactor out the bit we need to apply in
both cases (verifying the IP is acceptable to IPAddr and that it's not a
range) to a separate method called #sanitize_ips which reduces an array of
maybe-ips to an array of acceptable ones.
- We used the `fixture_path` before `file_fixture_path` was a thing,
but now that we have the latter we should use it.
`fixture_path` is solely used by Active Record so it seems wrong
to be using that in ActionPack.
Motivation is twofold:
* We are gradually removing `require_dependency` from the framework.
* Let `helper` work if `config.add_autoload_paths_to_load_path` is
disabled.
Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
`url_for` will now use "https://" as the default protocol when
`Rails.application.config.force_ssl` is set to true.
Action Mailer already behaves this way, effectively. This commit
extends that behavior application-wide.
Closes#23543.
Base64 strict-encoded CSRF tokens are not inherently websafe, which makes
them difficult to deal with. For example, the common practice of sending
the CSRF token to a browser in a client-readable cookie does not work properly
out of the box: the value has to be url-encoded and decoded to survive transport.
Now, we generate Base64 urlsafe-encoded CSRF tokens, which are inherently safe
to transport. Validation accepts both urlsafe tokens, and strict-encoded tokens
for backwards compatibility.
In a distributed configuration like rolling update, users may observe
both old and new instances during deployment. Users may be served by a
new instance and then by an old instance.
That means when the server changes `cookies_serializer` from `:marshal`
to `:hybrid` or the server changes `use_authenticated_cookie_encryption`
from `false` to `true`, users may lose their sessions if they access the
server during deployment.
We added fallbacks to downgrade the cookie format when necessary during
deployment, ensuring compatibility on both old and new instances.
Enabling `SameSite` cookie protection is an addition to CSRF protection,
where cookies won't be sent by browsers in cross-site POST requests when set to `:lax`.
`:strict` disables cookies being sent in cross-site GET or POST requests.
Passing `:none` disables this protection and is the same as previous versions albeit a `; SameSite=None` is appended to the cookie.
See upgrade instructions in config/initializers/new_framework_defaults_6_1.rb.
More info [here](https://tools.ietf.org/html/draft-west-first-party-cookies-07)
_NB: Technically already possible as Rack supports SameSite protection, this is to ensure it's applied to all cookies_
= This feature existed back in 2012 5e7d6bba79
but got reverted with the incentive that there was a better approach.
After discussions, we agreed that it's a useful feature for apps
that have a really large set of routes.
Co-authored-by: Yehuda Katz <wycats@gmail.com>
- `respond_to any` doesn't allow to specify a content type and
the content type in the response will be based on the request
format.
```ruby
def my_action
respond_to do |format|
format.html { render(html: 'hello') }
format.any { render(json: { foo: 'bar'}) }
end
end
get('my_action.csv')
# Before this patch, content type was `text/csv'
# Ather this patch, content type is correctly set to whateve we did in the `format.any` block
```
If the client specify the type of data he wants but the server
doesn't know how to handle it and return plain text (or whatever)
I don't think it make sense to falsey claim that we are returning
a `text/csv` a response where in fact we are returning something else.
Fix#37345
When a test method name includes a slash (e.g. `test "signup on the
/signup page"`) the screenshot is generated in the nested directory on
systems that use slash as a directory separator (e.g. a screenshot
called `signup_page.png` is generated within `failures_signup_on_the_`).
Nesting screenshots causes an issue with `tmp:clear` rake task:
```
== Removing old logs and tempfiles ==
rails aborted!
Errno::EISDIR: Is a directory @ apply2files - tmp/screenshots/failures_signup_on_the_
/var/lib/gems/2.5.0/gems/railties-5.2.3/lib/rails/tasks/tmp.rake:41:in `block (3 levels) in <top (required)>'
/var/lib/gems/2.5.0/gems/railties-5.2.3/lib/rails/commands/rake/rake_command.rb:23:in `block in perform'
...
Tasks: TOP => tmp:clear => tmp:screenshots:clear
```
While the error could be prevented by changing `tmp:clear` task, there's
no reason to generate deep directory structures for tests using slashes.
To prevent a similar problem on Windows, we'll also "sanitize"
backslashes.
Replacing the problamatic characters with dashes seems to be a safe
workaround, although dash is very arbitrary choice in this case.
Co-Authored-By: Louis-Michel Couture <louim_1@hotmail.com>
Problem description (quoted from @rafaelfranca's excellent explanation in https://github.com/rails/jquery-ujs/issues/318#issuecomment-88129005):
> Let say that we requested /tasks/1 using Ajax, and the previous page has the same url. When we click the back button the browser tries to get the response from its cache and it gets the javascript response. With vary we "fix" this behavior because we are telling the browser that the url is the same but it is not from the same type what will skip the cache.
And there's a Rails issue discussing about this problem as well https://github.com/rails/rails/issues/25842
Also, according to [RFC 7231 7.1.4](https://tools.ietf.org/html/rfc7231#section-7.1.4)
> An origin server SHOULD send a Vary header field when its algorithm
> for selecting a representation varies based on aspects of the request
> message other than the method and request target
we should add `Vary: Accept` header when determining content based on the `Accept` header.
Although adding such header by default could cause unnecessary cache invalidation. But this PR only adds the header if:
- The format param is not provided
- The request is a `xhr` request
- The request has accept headers and the headers are valid
So if the user
- sends request with explicit format, like `/users/1.json`
- or sends a normal request (non xhr)
- or doesn't specify accept headers
then the header won't be added.
See the discussion in https://github.com/rails/rails/issues/25842 and
https://github.com/rails/rails/pull/36213 for more details.
- According to the HTTP 1.1 spec, the 307 redirection guarantees that
the method and the body will not be changed during redirection.
This PR fixes that since follow_redirect! would always follow the
redirection my making a GET request.
Ref https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307