The `'wasm-unsafe-eval'` keyword for the Content Security Policy allows the
loading and execution of WebAssembly modules without the need to allow unsafe
JavaScript execution via `'unsafe-eval'`. A mapping is added so that the symbol
`:wasm_unsafe_evel` can be used for this keyword in the policy configuration in
`config/initializers/content_security_policy.rb`.
Fixes MIME parsing raising errors on valid parameters #51594.
Mime type lookups were updated to handle custom registered types as part of #48397.
This fix the strips out custom media range parameters before falling back to the default type creation.
`save_and_open_page` is a capybara helper that lets developers
inspect the status of the page at any given point in their
test. This is helpful when trying to keep a short feedback loop while
working on a test.
This change adds a similar helper with matching signature to
integration tests.
RFC 9110 specifies:
The server MUST send an Upgrade header field in a 426 response
to indicate the required protocol(s)
https://httpwg.org/specs/rfc9110.html#status.426
Status 406 Not Acceptable is more appropriate because it indicates the
resource
does not have a current representation that would be acceptable
to the user agent, according to the proactive negotiation header
fields received in the request
https://httpwg.org/specs/rfc9110.html#status.406
With the proactive negociation section mentionining:
implicit characteristics, such as the client's network address
or parts of the User-Agent field.
https://httpwg.org/specs/rfc9110.html#proactive.negotiation
The `:to` option for routes can once again be a String without a
controller if the controller is implicitly provided by a nesting
`controller` or `resources` call.
Passing relative paths into form_for and related helpers led to invalid
token generations, as the tokens did not match the request.path on the
POST endpoint. Variants, such as:
form_for url:
* ""
* "./"
* "./post_one"
* "post_one"
are now handled according to [RFC 3986 5.2 - 5.4](https://tools.ietf.org/html/rfc3986#section-5.2)
Limitations: double dots are not handled (../../path)
relevant issue: #31191
Given that the limiter implementation provided by Kredis is a simple
increment with a limit, all `ActiveSupport::Cache` already provide that
same capability, with a wide range of backing stores, and not just Redis.
This even allow to use SolidCache has a backend if you so desire.
If we feel particularly fancy, we could also accept a more generic
limiter interface to better allow users to swap the implementation
for better algorithms such as leaky-bucket etc.
Adds support for with_routing test helpers in ActionDispatch::IntegrationTest.
Previously, this helper didn't work in an integration context because
the rack app and integration session under test were not mutated.
Because controller tests are integration tests by default, we should
support test routes for these kinds of test cases as well.
When the webdrivers gem is not present (which is the default scenario in
Rails 7.1+), the Selenium `driver_path` starts out as `nil`. This means
the driver is located lazily, and deferred until a system test is run.
If parallel testing is used, this leads to a race condition, where each
worker process tries to resolve the driver simultaneously. The result is
an error as described in #49906.
This commit fixes the race condition by changing the implementation of
`Browser#preload`. The previous implementation worked when `driver_path`
was set to a Proc by the `webdrivers` gem, but doesn't work when the
`webdrivers` gem is not being used and the `driver_path` is `nil`.
`Browser#preload` now uses the `DriverFinder` utility provided by the
`selenium-webdriver` gem to eagerly resolve the driver path if needed.
This will ensures that `driver_path` is set before parallel test workers
are forked.
Fixes#49906.
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
Ruby 3.3.0 is going to start warning for racc not being specififed as a
dependency, and Ruby 3.4.0 will raise if it is not specified.
This commit prevents those issues by adding racc to the Action Pack
gemspec, since `racc/parser` is a runtime dependency of the Journey
parser.
When [rails/rails#20868][] changed the `ActionController::Parameters`
ancestory from `HashWithIndifferentAccess` to `Object`, support for
`#deep_merge` and `#deep_merge!` were omitted.
This commit restores support by integrating with
[ActiveSupport::DeepMergeable](./activesupport/lib/active_support/deep_mergeable.rb).
[rails/rails#20868]: https://github.com/rails/rails/pull/20868
Co-authored-by: Jonathan Hefner <jonathan@hefner.pro>
This commit adds `extract_value` method to `ActionController::Parameters`
as a primary way to extract composite `id` values serialized from
`ActiveRecord::Base#to_param` called on a model with a composite primary key.
Both `Nokogiri` and `Minitest` have merged the PRs mentioned to
integrate support for Ruby's Pattern matching
(https://github.com/sparklemotion/nokogiri/pull/2523 and
https://github.com/minitest/minitest/pull/936, respectively).
This commit adds coverage for those new assertions, and incorporates
examples into the documentation for the `response.parsed_body` method.
In order to incorporate pattern-matching support for JSON responses,
this commit changes the response parser to call `JSON.parse` with
[object_class: ActiveSupport::HashWithIndifferentAccess][object_class],
since String instances for `Hash` keys are incompatible with Ruby's
syntactically pattern matching.
For example:
```ruby
irb(main):001:0> json = {"key" => "value"}
=> {"key"=>"value"}
irb(main):002:0> json in {key: /value/}
=> false
irb(main):001:0> json = {"key" => "value"}
=> {"key"=>"value"}
irb(main):002:0> json in {"key" => /value/}
.../3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/lib/irb/workspace.rb:113:in `eval': (irb):2: syntax error, unexpected terminator, expecting literal content or tSTRING_DBEG or tSTRING_DVAR or tLABEL_END (SyntaxError)
json in {"key" => /value/}
^
.../ruby/3.2.0/lib/ruby/gems/3.2.0/gems/irb-1.7.4/exe/irb:9:in `<top (required)>'
.../ruby/3.2.0/bin/irb:25:in `load'
.../ruby/3.2.0/bin/irb:25:in `<main>'
```
When the Hash maps String keys to Symbol keys, it's able to be pattern
matched:
```ruby
irb(main):005:0> json = {"key" => "value"}.with_indifferent_access
=> {"key"=>"value"}
irb(main):006:0> json in {key: /value/}
=> true
```
[object_class]: https://docs.ruby-lang.org/en/3.2/JSON.html#module-JSON-label-Parsing+Options
Previously, when a Request had a non-authorized HTTP_HOST but an
authorized HTTP_X_FORWARDED_HOST, the HTTP_X_FORWARDED_HOST value would
be displayed as the one being blocked. However, this could be confusing
for users since that value would already be added to `config.hosts`.
This commit addresses the issue by tweaking how the blocked host is
displayed. Instead of always displaying Request#host (which will return
X_FORWARDED_HOST when present whether or not that's the host being
blocked), each host being blocked will be displayed on its own.
Co-authored-by: Daniel Schlosser <Eusebius1920@users.noreply.github.com>
The naming difference between the test harness' [file_fixture][] helper
made available through Active Support (along with the
`file_fixture_path` configuration value) and the integration test
harness' [fixture_file_upload][] is a constant source of confusion and
surprise.
Since Active Support is more ubiquitous, this commit renames the
`fixture_file_upload` method to `file_fixture_upload` to match the order
of words in `file_fixture` and `file_fixture_path`.
To preserve backwards compatibility, declare a `fixture_file_upload`
alias to be preserved into the future (or removed at a future point in
time).
[file_fixture]: https://edgeapi.rubyonrails.org/classes/ActiveSupport/Testing/FileFixtures.html#method-i-file_fixture
[fixture_file_upload]: https://edgeapi.rubyonrails.org/classes/ActionDispatch/TestProcess/FixtureFile.html#method-i-fixture_file_upload
Accept headers allow parameters to be passed. They can contain quotes
that need to be handled differently. These quoted strings can contain
commas, which are not considered as delimiters of accept headers.
Additionally, all parameters before the q-parameter should be used to
lookup the media-type as well. If no media-type with the parameters is
found, a fallback is introduced to the media-type without any parameters
to keep the same functionality as before.
Fix#48052
The url_for helper now supports a new option called `bind_params`.
This is very useful in situations where you only want to add a required
param that is part of the route's URL but for other route not append an
extraneous query param.
Given the following router...
```ruby
Rails.application.routes.draw do
scope ":account_id" do
get 'dashboard' => 'pages#dashboard', as: :dashboard
get 'search/:term' => 'search#search', as: :search
end
delete 'signout' => 'sessions#destroy', as: :signout
end
```
And given the following `ApplicationController`
```ruby
class ApplicationController < ActionController::Base
def default_url_options
{ bind_params: { account_id: "foo" } }
end
end
```
The standard URLHelpers will now behave as follows:
```ruby
dashboard_path # => /foo/dashboard
dashboard_path(account_id: "bar") # => /bar/dashboard
signout_path # => /signout
signout_path(account_id: "bar") # => /signout?account_id=bar
search_path("quin") # => /foo/search/quin
```
Background
----------
During integration tests, it is desirable for the application to respond
as closely as possible to the way it would in production. This improves
confidence that the application behavior acts as it should.
In Rails tests, one major mismatch between the test and production
environments is that exceptions raised during an HTTP request (e.g.
`ActiveRecord::RecordNotFound`) are re-raised within the test rather
than rescued and then converted to a 404 response.
Setting `config.action_dispatch.show_exceptions` to `true` will make the
test environment act like production, however, when an unexpected
internal server error occurs, the test will be left with a opaque 500
response rather than presenting a useful stack trace. This makes
debugging more difficult.
This leaves the developer with choosing between higher quality
integration tests or an improved debugging experience on a failure.
I propose that we can achieve both.
Solution
--------
Change the configuration option `config.action_dispatch.show_exceptions`
from a boolean to one of 3 values: `:all`, `:rescuable`, `:none`. The
values `:all` and `:none` behaves the same as the previous `true` and
`false` respectively. What was previously `true` (now `:all`) continues
to be the default for non-test environments.
The new `:rescuable` value is the new default for the test environment.
It will show exceptions in the response only for rescuable exceptions as
defined by `ActionDispatch::ExceptionWrapper.rescue_responses`. In the
event of an unexpected internal server error, the exception that caused
the error will still be raised within the test so as to provide a useful
stack trace and a good debugging experience.
This commit adds support for `:message_pack` and `:message_pack_allow_marshal`
as serializers for `config.action_dispatch.cookies_serializer`, just
like `config.active_support.message_serializer`.
The `:message_pack` serializer can fall back to deserializing with
`AS::JSON`, and the `:message_pack_allow_marshal` serializer can fall
back to deserializing with `AS::JSON` or `Marshal`. Additionally, the
`:marshal`, `:json`, and `:hybrid` / `:json_allow_marshal` serializers
can now fall back to deserializing with `AS::MessagePack`. These
behaviors make it easier to migrate between cookies serializers.