`Middleware#remove` works just like `Middleware#delete` but will
raise an error if the middleware isn't found.
This partly reverts 07558ff57c, where
`delete` would raise an error.
It might be expected that `delete` fails silently for some environments.
Or maybe you want to make sure a middleware isn't present.
Co-authored-by: Alex Ghiculescu <alexghiculescu@gmail.com>
As of Ruby 2.7 DidYouMean is included as a default gem, so there is no
need to check if DidYouMean is defined in the test suite. We still need
to check if the DidYouMean modules are defined in the actual code, as
someone might run Rails with DidYouMean disabled by using the
`--disable-did_you_mean` flag. This is ussually done for performance
reasons.
This commit also includes some of the changes made by Yuki in:
https://github.com/rails/rails/pull/39555
These changes include replacing Jaro with the more accurate
SpellChecker, and using DidYouMean::Correctable for simplere
corrections.
The DidYouMean::SpellChecker does have a treshold for corrections.
If there is not enough similarity it might not return a suggestion.
To stop the tests from failing some test data had to be changed.
For example, `non_existent` does not meet the treshold for `hello`, but
`ello` does:
DidYouMean::SpellChecker.new(dictionary: %w[hello]).correct('non_existent')
=> []
DidYouMean::SpellChecker.new(dictionary: %w[hello]).correct('ello')
=> ["hello"]
The treshold makes sense for spelling errors. But maybe we should add a
different SpellChecker that helps to get a suggestion even if there is
little overlap. For example for when a model only has 2 attributes
(title and body), it's helpful to get a suggestion for `name`
Co-Authored-By: Yuki Nishijima <yk.nishijima@gmail.com>
Since #39179, `selenium/webdriver` is required only when using the
`:selenium` driver. However, `ActionDispatch::SystemTesting::Browser`
references `::Selenium` as soon as it is instantiated, and thus raises
an error when using a non-`:selenium` driver.
This commit ensures that `ActionDispatch::SystemTesting::Browser` is
instantiated only when using the `:selenium` driver.
Currently if you call any `move` operation on the middleware stack with a middleware item that doesn't exist, [it will raise](53d54694e9/actionpack/test/dispatch/middleware_stack_test.rb (L102)). But the same doesn't happen if you call `delete` with a non-existant item. This makes it hard to debug issues like https://github.com/rails/rails/pull/42652 as the `delete` call fails silently.
I think `delete` should raise same as `move` does, and this PR implements that.
This would be a breaking change if someone has code calling `delete` on a non-existant middleware item, the fix would be to just remove that code since it's not doing anything.
IE 6-7-8 has bug when 'Cache-Control: no-cache' head would break file download.
It's been fixed in IE9 (which is also ancient and barely used version).
Some extra details [here][1] and [here][2].
The way this fix is implemented clashes with what's been done in PR #40324. By
adding ':public' key to cache control header set it wipes default headers.
Since IE 6-7-8 are ancient browsers - let's just get rid of this hack.
[1]: https://stackoverflow.com/q/9766639/843067
[2]: https://stackoverflow.com/q/3415370/843067
Ref: https://github.com/rails/rails/pull/42020
It's not uncommon to want to forward request parameters,
as such the `:params` paramter of `url_for` often receive
an AC::Parameters instance.
Summary
=======
Currently there is no way to set "Cache-Control: no-store" header using
built-in cache control methods ("expires_now"/"expires_in"/etc..). One of
the [top StackOverflow][1] answers currently suggests putting it directly
into header set.
Unfortunately, it cannot later be overridden in specific/individual actions by
calling say 'expires_in 5.minutes'. Resulting header in that case is
stays the same, i.e. 'Cache-Control: no-store'.
This:
1. Adds the 'no_store' method to set "Cache-Control: no-store" header.
2. Changes cache control "merge and normalize" code so default "no-store"
directive can be overridden using built in cache control methods mentioned
above.
What's the use of it
--------------------
Couple examples:
* To [prevent rendering stale content][3] if browser return button is used
('expires_now' does not help).
* To prevent browser disk cache being used. In some situations it's considered
a [privacy/security risk][4].
Other Information
=================
Mozilla developer docs for [Cache-Control][2] header.
[1]: https://stackoverflow.com/questions/10744169/rails-set-no-cache-method-cannot-disable-browser-caching-in-safari-and-opera
[2]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
[3]: https://engineering.mixmax.com/blog/chrome-back-button-cache-no-store/
[4]: https://portswigger.net/kb/issues/00700100_cacheable-https-response
Using File.stat where a file does not exist raises an exception.
Since ActionDispatch::Static does this:
def call(env)
@file_handler.attempt(env) || @app.call(env)
end
... this means that around 8 exceptions are raised and rescued on each
request which is passed to the application.
This change improves latency by ~.14 milliseconds on all applications.
Partial revert of #37265
This replaces the controller/action method of finding a path with the lookup_context which should always find the same thing as the render method finds.
before https://github.com/rails/rails/pull/40125 test names would be
set to "test" after this change controller_name was nil when using
ActionView::TestCase.
This returns ActionView::TestCase to previous behavior returning "test"
To avoid a deadlock from the buffer filling up during testing due to the
ActionController::Live test monkey patch that processes the request in
the same thread, which means there is no consumer of the queue until
the request is processed.
previously, if you specify a url parameter that is part of the path as false it would include that part of the path as parameter at the end of the url instead of in the path for example:
`get "(/optional/:optional_id)/things" => "foo#foo", as: :things`
`things_path(optional_id: false) # => /things?optional_id=false`
this is not the case for empty string,
`things_path(optional_id: '') # => "/things"
this is due to a quark in how path parameters get removed from the parameters.
we where doing `(paramter || recall).nil?` which returns nil if both values are nil however it also return nil if one value is false and the other value is nil. i.e. `(false || nil).nil # => nil` which is confusing.
After this change, `true` and `false` will be treated the same when used as optional path parameters. meaning now,
```
get '(this/:my_bool)/that' as: :that
that_path(my_bool: true) # => `/this/true/that`
that_path(my_bool: false) # => `/this/false/that`
```
fixes: https://github.com/rails/rails/issues/42280
Co-authored-by: Ryuta Kamizono <kamipo@gmail.com>