Skip to content

Commit

Permalink
Use expected casing for x-cascade headers in router
Browse files Browse the repository at this point in the history
This commit changes the router to use the expected casing for the
x-cascade header: in Rack 2, this is mixed-case, and in Rack 3, this is
lower case.

This also fixes rails#47096.
  • Loading branch information
adrianna-chang-shopify committed Jul 28, 2023
1 parent 596c2a0 commit 2401b33
Show file tree
Hide file tree
Showing 13 changed files with 28 additions and 25 deletions.
2 changes: 2 additions & 0 deletions actionpack/lib/action_dispatch/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Constants
LOCATION = "Location"
FEATURE_POLICY = "Feature-Policy"
X_REQUEST_ID = "X-Request-Id"
X_CASCADE = "X-Cascade"
SERVER_TIMING = "Server-Timing"
STRICT_TRANSPORT_SECURITY = "Strict-Transport-Security"
else
Expand All @@ -23,6 +24,7 @@ module Constants
LOCATION = "location"
FEATURE_POLICY = "feature-policy"
X_REQUEST_ID = "x-request-id"
X_CASCADE = "x-cascade"
SERVER_TIMING = "server-timing"
STRICT_TRANSPORT_SECURITY = "strict-transport-security"
end
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/http/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def commit_cookie_jar! # :nodoc:

PASS_NOT_FOUND = Class.new { # :nodoc:
def self.action(_); self; end
def self.call(_); [404, { "X-Cascade" => "pass" }, []]; end
def self.call(_); [404, { Constants::X_CASCADE => "pass" }, []]; end
def self.action_encoding_template(action); false; end
}

Expand Down
4 changes: 2 additions & 2 deletions actionpack/lib/action_dispatch/journey/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def serve(req)

_, headers, _ = response = route.app.serve(req)

if "pass" == headers["X-Cascade"]
if "pass" == headers[Constants::X_CASCADE]
req.script_name = script_name
req.path_info = path_info
req.path_parameters = set_params
Expand All @@ -60,7 +60,7 @@ def serve(req)
return response
end

[404, { "X-Cascade" => "pass" }, ["Not Found"]]
[404, { Constants::X_CASCADE => "pass" }, ["Not Found"]]
end

def recognize(rails_req)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def initialize(app, routes_app = nil, response_format = :default, interceptors =
def call(env)
_, headers, body = response = @app.call(env)

if headers["X-Cascade"] == "pass"
if headers[Constants::X_CASCADE] == "pass"
body.close if body.respond_to?(:close)
raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}"
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def render_html(status)
if found || File.exist?(path)
render_format(status, "text/html", File.read(path))
else
[404, { "X-Cascade" => "pass" }, []]
[404, { Constants::X_CASCADE => "pass" }, []]
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def render_exception(request, wrapper)
request.path_info = "/#{status}"
request.request_method = "GET"
response = @exceptions_app.call(request.env)
response[1]["X-Cascade"] == "pass" ? pass_response(status) : response
response[1][Constants::X_CASCADE] == "pass" ? pass_response(status) : response
rescue Exception => failsafe_error
$stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"

Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/routing/mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def matches?(req)
end

def serve(req)
return [ 404, { "X-Cascade" => "pass" }, [] ] unless matches?(req)
return [ 404, { Constants::X_CASCADE => "pass" }, [] ] unless matches?(req)

@strategy.call @app, req
end
Expand Down
2 changes: 1 addition & 1 deletion actionpack/lib/action_dispatch/routing/route_set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def serve(req)
if @raise_on_name_error
raise
else
[404, { "X-Cascade" => "pass" }, []]
[404, { Constants::X_CASCADE => "pass" }, []]
end
end

Expand Down
3 changes: 2 additions & 1 deletion actionpack/test/controller/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,8 @@ def self.call(*)
get "bar", to: "application_integration_test/test#index", as: :bar

mount MountedApp => "/mounted", :as => "mounted"
get "fooz" => proc { |env| [ 200, { "X-Cascade" => "pass" }, [ "omg" ] ] }, :anchor => false
get "fooz" => proc { |env| [ 200, { ActionDispatch::Constants::X_CASCADE => "pass" }, [ "omg" ] ] },
:anchor => false
get "fooz", to: "application_integration_test/test#index"
end

Expand Down
2 changes: 1 addition & 1 deletion actionpack/test/dispatch/debug_exceptions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def call(env)

case req.path
when "/pass"
[404, { "X-Cascade" => "pass" }, self]
[404, { ActionDispatch::Constants::X_CASCADE => "pass" }, self]
when "/not_found"
controller = SimpleController.new
raise AbstractController::ActionNotFound.new(nil, controller, :ello)
Expand Down
22 changes: 11 additions & 11 deletions actionpack/test/dispatch/routing_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -430,19 +430,19 @@ def test_admin
assert_equal "queenbee#index", @response.body

get "/admin", headers: { "REMOTE_ADDR" => "10.0.0.100" }
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]

get "/admin/accounts", headers: { "REMOTE_ADDR" => "192.168.1.100" }
assert_equal "queenbee#accounts", @response.body

get "/admin/accounts", headers: { "REMOTE_ADDR" => "10.0.0.100" }
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]

get "/admin/passwords", headers: { "REMOTE_ADDR" => "192.168.1.100" }
assert_equal "queenbee#passwords", @response.body

get "/admin/passwords", headers: { "REMOTE_ADDR" => "10.0.0.100" }
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
end

def test_global
Expand Down Expand Up @@ -890,13 +890,13 @@ def test_resource_routes_with_only_and_except
assert_equal "/posts/1/comments", post_comments_path(post_id: 1)

post "/posts"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
put "/posts/1"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
delete "/posts/1"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
delete "/posts/1/comments"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
end

def test_resource_routes_only_create_update_destroy
Expand Down Expand Up @@ -1325,7 +1325,7 @@ def test_articles_with_id
assert_equal "articles#with_id", @response.body

get "/articles/123/1"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]

assert_equal "/articles/rails/1", article_with_title_path(title: "rails", id: 1)
end
Expand Down Expand Up @@ -1909,7 +1909,7 @@ def test_resource_constraints
end

get "/products/1"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
get "/products"
assert_equal "products#root", @response.body
get "/products/favorite"
Expand All @@ -1918,14 +1918,14 @@ def test_resource_constraints
assert_equal "products#show", @response.body

get "/products/1/images"
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
get "/products/0001/images"
assert_equal "images#index", @response.body
get "/products/0001/images/0001"
assert_equal "images#show", @response.body

get "/dashboard", headers: { "REMOTE_ADDR" => "10.0.0.100" }
assert_equal "pass", @response.headers["X-Cascade"]
assert_equal "pass", @response.headers["x-cascade"]
get "/dashboard", headers: { "REMOTE_ADDR" => "192.168.1.100" }
assert_equal "dashboards#show", @response.body
end
Expand Down
4 changes: 2 additions & 2 deletions actionpack/test/dispatch/show_exceptions_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -117,9 +117,9 @@ def call(env)
assert_equal "YOU FAILED", body
end

test "returns an empty response if custom exceptions app returns X-Cascade pass" do
test "returns an empty response if custom exceptions app returns x-cascade pass" do
exceptions_app = lambda do |env|
[404, { "X-Cascade" => "pass" }, []]
[404, { ActionDispatch::Constants::X_CASCADE => "pass" }, []]
end

@app = ActionDispatch::ShowExceptions.new(Boomer.new, exceptions_app)
Expand Down
4 changes: 2 additions & 2 deletions actionpack/test/journey/router_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,11 @@ def test_does_not_include_missing_keys_message
assert_no_match(/missing required keys: \[\]/, error.message)
end

def test_X_Cascade
def test_x_cascade
get "/messages(.:format)", to: "foo#bar"
resp = router.serve(rails_env("REQUEST_METHOD" => "GET", "PATH_INFO" => "/lol"))
assert_equal ["Not Found"], resp.last
assert_equal "pass", resp[1]["X-Cascade"]
assert_equal "pass", resp[1][Constants::X_CASCADE]
assert_equal 404, resp.first
end

Expand Down

0 comments on commit 2401b33

Please sign in to comment.