When working through an issue, I found myself a little confused stumbling upon some code like this:
```rb
cookies[...] = {
# ...
domain: %w(.site.io .site.com)
}
```
In my mind I was thinking "is this some weird part of the cookie spec? or is this Rails?" and the docs didn't offer much insight into how it works. Going back into the commit where that line was added, the folks who added it were confused to until someone linked to the source.
I figured that clarifying this in the docs would be useful. Of course, people should know how cookies work before fiddling with them (unlike me), but since cookies are so sensitive, I think the docs should opt for being explicit about this.
Co-Authored-By: Norm Provost <norman.provost@intercom.io>
The method add_template_helper is private and used only in one place.
I guess its purpose was to remove the noise of module_eval at the cost
of an indirection.
However, Module#include is public since Ruby 2.1, and the indirection
is no longer justified for my taste. The loop in the caller is more
straightforward now.
PR #38211 introduced a bug where URLs with query_params
will fail to validate authenticity token.
This PR changes changes fullpath to path to fix the bug.
I've also added a test with query_params
`helper_method` was taking `**kwargs` on all definitions by default.
ruby will assume that this means you want keyword args and call
`to_hash` on what you pass if the object responds to `to_hash`. Instead
we should only take keyword args if the helper method defined intends
to pass keyword args.
This also fixes a warning when you pass a hash to your helper method,
```
warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
```
Also, this would be a good candidate for using `...`, but since `send`
requires the method as the first argument, we can't use it here.
PATH_INFO will never contain query parameters (that is the contract with
the webserver), so there is no reason to call URI.parse on it. In
addition, clients can send garbage paths that raise an exception when
being parsed rather than just failing the auth token check.
* Fix ActionController::TestSession#id to return Rack::Session::SessionId instance
* test SessionId#public_id
* test session["session_id"]
Co-authored-by: Benjamin Quorning <22333+bquorning@users.noreply.github.com>
While trying to fix#16433, we made the middleware deletions always
happen at the end. While this works for the case of deleting the
Rack::Runtime middleware, it makes operations like the following
misbehave.
```ruby
gem "bundler", "< 1.16"
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "rails", github: "rails/rails"
end
require "action_controller/railtie"
class TestApp < Rails::Application
config.root = __dir__
secrets.secret_key_base = "secret_key_base"
config.logger = Logger.new($stdout)
Rails.logger = config.logger
middleware.insert_after ActionDispatch::Session::CookieStore, ::Rails::Rack::Logger, config.log_tags
middleware.delete ::Rails::Rack::Logger
end
require "minitest/autorun"
require "rack/test"
class BugTest < Minitest::Test
include Rack::Test::Methods
def test_returns_success
get "/"
assert last_response.ok?
end
private
def app
Rails.application
end
end
```
In the case ☝️ the ::Rails::Rack::Logger would be deleted instead of
moved, because the order of middleware stack building execution will be:
```ruby
[:insert, ActionDispatch::Session::CookieStore, [::Rails::Rack::Logger]]
[:delete, ::Rails::Rack::Logger, [config.log_tags]]
```
This is pretty surprising and hard to reason about behaviour, unless you
go spelunking into the Rails configuration code.
I have a few solutions in mind and all of them have their drawbacks.
1. Introduce a `Rails::Configuration::MiddlewareStackProxy#delete!` that
delays the deleted operations. This will make `#delete` to be executed
in order. The drawback here is backwards incompatible behavior and a new
public method.
2. Just revert to the old operations. This won't allow people to delete
the `Rack::Runtime` middleware.
3. Legitimize the middleware moving with the new `#move_after` and
`#move_before` methods. This does not breaks any backwards
compatibility, but includes 2 new methods to the middleware stack.
I have implemented `3.` in this pull request.
Happy holidays! 🎄
When the route definition has parameters, we can supply a regex for
validation purposes:
get "/a/:b" => "test#index", constraints: { b: /abc/ }, as: test
This regex is going to be used to check the supplied values during
link generation:
test_path("abc") # check "abc" against /abc/ regex
The link generation code checks each parameter. To properly validate the
parameter, it creates a new regex with start and end of string modifiers:
/\A#{original_regex}\Z/
This means for each link generation the code stringifies the existing
regex and creates a new one. When a new regex is created, it needs to be
compiled, for large regexes this can take quite a bit of time.
This change memoizes the generated regex for each route when constrains
are given. It also removes the RegexCaseComparator class since it is not
in use anymore.
Scenario: we have a REMOTE_ADDR of `127.0.0.1`, and X-Forwarded-For is
`A, B, C`.
Without any relevant trust, the `remote_ip` is `C`.
If `C` is trusted, then the `remote_ip` is `B`.
If `B` and `C` are trusted, then the `remote_ip` is `A`.
If all of `A`, `B`, and `C` are trusted, then the `remote_ip` should
still be `A`: if our trust was sufficient to get that far out before,
trusting something else should not have us fall back to `127.0.0.1`.
It is this last situation that we're correcting here:
We trust `A` to give us accurate X-Forwarded-For information, yet it has
chosen to leave it unset. Therefore, `A` is telling us that it is itself
the client.
The rendering template is processing as */* but in the log is
"Processing by Controller#action as "
This change add the */* for the log and showing as
"Processing by Controller#action as */*"
when there not founds for the extension of format.
- Original issue was reported in https://github.com/rails/rails/issues/38094
and a fix attempted in https://github.com/rails/rails/pull/38126 but
it's not the proper fix I think.
TL;DR Is that `ActionView::Base.default_formats` holds a copy of
mime symbols at the time ActionView::Base is loaded.
So if you try to register mime types after ActionView Base is loaded
then it won't work.
```ruby
ActionView::Base.default_formats ||= Mime::SET.symbols # Note that this is automatically done when ActionView get loaded 22483b86a6/actionpack/lib/action_dispatch.rb (L117)
Mime::Type.register_alias "application/xhtml+xml", :foobar
puts ActionView::base.defaults_formats.include?(:foobar) # => false
```
Same issue if you try to unregister a mime after ActionView is loaded.
That's what was happening in the flaky test:
```
Mime::Type.register_alias "application/xhtml+xml", :foobar
ActionView::Base.default_formats ||= Mime::SET.symbols
puts ActionView::base.defaults_formats.include?(:foobar) # => true
Mime::Type.unregister(:foobar)
puts ActionView::base.defaults_formats.include?(:foobar) # => true
```
### Solution
Return a refence to `@symbols` which is updated each time a new mime is
registered/unregistered.
Rather than replace `ENV['TRAVIS']` with `ENV['CI']`, I think we can
remove this condition because `ENV['TRAVIS']` is not valid at Buildkite
then Rails CI has been running with `PROCESS_COUNT` about 9 month
since this e485c14a3e
Before 2169bd3d2a, a template's source was
encoded in place when it was compiled, and the `source_extract` method
could rely on `Template#source` to return a properly encoded string.
Now that `Template#source` always returns a new copy of the template
source with no encoding, `source_extract` should call `encode!` itself.