Skip to content

Commit

Permalink
Respond with 406 when a browser is blocked by allow_browser
Browse files Browse the repository at this point in the history
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
  • Loading branch information
etiennebarrie committed Apr 11, 2024
1 parent 93df871 commit 1dc7620
Show file tree
Hide file tree
Showing 7 changed files with 11 additions and 10 deletions.
2 changes: 1 addition & 1 deletion actionpack/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

* Add `allow_browser` to set minimum browser versions for the application.

A browser that's blocked will by default be served the file in `public/426.html` with a HTTP status code of "426 Upgrade Required".
A browser that's blocked will by default be served the file in `public/406-unsupported-browser.html` with a HTTP status code of "406 Not Acceptable".

```ruby
class ApplicationController < ActionController::Base
Expand Down
7 changes: 4 additions & 3 deletions actionpack/lib/action_controller/metal/allow_browser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ module ClassMethods
# versions specified. This means that all other browsers, as well as agents that
# aren't reporting a user-agent header, will be allowed access.
#
# A browser that's blocked will by default be served the file in public/426.html
# with a HTTP status code of "426 Upgrade Required".
# A browser that's blocked will by default be served the file in
# public/406-unsupported-browser.html with a HTTP status code of "406 Not
# Acceptable".
#
# In addition to specifically named browser versions, you can also pass
# `:modern` as the set to restrict support to browsers natively supporting webp
Expand Down Expand Up @@ -43,7 +44,7 @@ module ClassMethods
# # In addition to the browsers blocked by ApplicationController, also block Opera below 104 and Chrome below 119 for the show action.
# allow_browser versions: { opera: 104, chrome: 119 }, only: :show
# end
def allow_browser(versions:, block: -> { render file: Rails.root.join("public/426.html"), layout: false, status: :upgrade_required }, **options)
def allow_browser(versions:, block: -> { render file: Rails.root.join("public/406-unsupported-browser.html"), layout: false, status: :not_acceptable }, **options)
before_action -> { allow_browser(versions: versions, block: block) }, **options
end
end
Expand Down
2 changes: 1 addition & 1 deletion railties/lib/rails/generators/rails/app/app_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -495,8 +495,8 @@ def delete_app_views_if_api_option
def delete_public_files_if_api_option
if options[:api]
remove_file "public/404.html"
remove_file "public/406-unsupported-browser.html"
remove_file "public/422.html"
remove_file "public/426.html"
remove_file "public/500.html"
remove_file "public/icon.png"
remove_file "public/icon.svg"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Your browser is not supported (426)</title>
<title>Your browser is not supported (406)</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
.rails-default-error-page {
Expand Down Expand Up @@ -55,7 +55,7 @@
</head>

<body class="rails-default-error-page">
<!-- This file lives in public/426.html -->
<!-- This file lives in public/406-unsupported-browser.html -->
<div class="dialog">
<div>
<h1>Your browser is not supported.</h1>
Expand Down
2 changes: 1 addition & 1 deletion railties/test/generators/api_app_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def skipped_files
test/helpers
public/404.html
public/422.html
public/426.html
public/406-unsupported-browser.html
public/500.html
public/icon.png
public/icon.svg
Expand Down
2 changes: 1 addition & 1 deletion railties/test/generators/app_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@
lib/tasks/.keep
log/.keep
public/404.html
public/406-unsupported-browser.html
public/422.html
public/426.html
public/500.html
public/icon.png
public/icon.svg
Expand Down
2 changes: 1 addition & 1 deletion railties/test/generators/plugin_generator_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@
test/dummy/lib/assets/.keep
test/dummy/log/.keep
test/dummy/public/404.html
test/dummy/public/406-unsupported-browser.html
test/dummy/public/422.html
test/dummy/public/426.html
test/dummy/public/500.html
test/dummy/public/icon.png
test/dummy/public/icon.svg
Expand Down

0 comments on commit 1dc7620

Please sign in to comment.