Skip to content

Commit

Permalink
Add header flag to prevent overriding error responses
Browse files Browse the repository at this point in the history
Currently for an non-200 page, Slimmer will replace the response body
with templates from Static. This certain apps like email-alert-frontend
need to present custom error page (e.g. 422). This allows an app to tell
Slimmer not to replace the body.
  • Loading branch information
theseanything committed Apr 7, 2020
1 parent 47001b1 commit 4a5172a
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 15 deletions.
40 changes: 25 additions & 15 deletions lib/slimmer/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def skip_slimmer_header?(response)
!!response.headers[Headers::SKIP_HEADER]
end

def ignore_error_header?(response)
!!response.headers[Headers::IGNORE_ERROR_HEADER]
end

def s(body)
return body.to_s unless body.respond_to?(:each)

Expand All @@ -84,26 +88,32 @@ def rewrite_response(env, response)
# Store the request id so it can be passed on with any template requests
GovukRequestId.value = env["HTTP_GOVUK_REQUEST_ID"]

rewritten_body = case response.status
when 200
@skin.success request, response, s(response.body)
when 403
@skin.error "403", s(response.body), request.env
when 404
@skin.error "404", s(response.body), request.env
when 410
@skin.error "410", s(response.body), request.env
else
@skin.error "500", s(response.body), request.env
end

rewritten_body = [rewritten_body] unless rewritten_body.respond_to?(:each)
response.body = rewritten_body
body = rewritten_body(request, response)

body = [body] unless body.respond_to?(:each)
response.body = body
response.headers["Content-Length"] = content_length(response.body)

response.finish
end

def rewritten_body(request, response)
return @skin.success request, response, s(response.body) if ignore_error_header?(response)

case response.status
when 200
@skin.success request, response, s(response.body)
when 403
@skin.error "403", s(response.body), request.env
when 404
@skin.error "404", s(response.body), request.env
when 410
@skin.error "410", s(response.body), request.env
else
@skin.error "500", s(response.body), request.env
end
end

def strip_slimmer_headers(headers)
headers.reject { |k, _v| k =~ /\A#{Headers::HEADER_PREFIX}/ }
end
Expand Down
6 changes: 6 additions & 0 deletions lib/slimmer/headers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module Headers
skip: "Skip",
template: "Template",
remove_search: "Remove-Search",
ignore_error: "Ignore-Error",
}.freeze

# @private
Expand Down Expand Up @@ -55,10 +56,15 @@ module Headers
# @private
REMOVE_SEARCH_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:remove_search]}".freeze

# @private
IGNORE_ERROR_HEADER = "#{HEADER_PREFIX}-#{SLIMMER_HEADER_MAPPING[:ignore_error]}".freeze


# Set the "slimmer headers" to configure the page
#
# @param hash [Hash] the options
# @option hash [String] application_name
# @option hash [String] ignore_error
# @option hash [String] format
# @option hash [String] organisations
# @option hash [String] page_owner
Expand Down
1 change: 1 addition & 0 deletions test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ def given_response(code, body, headers = {}, app_options = {})

template_name = case code
when 200 then "core_layout"
when 422 then "core_layout"
when 404 then "404"
when 410 then "410"
else "500"
Expand Down
21 changes: 21 additions & 0 deletions test/typical_usage_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,27 @@ def test_should_replace_the_title_using_the_app_response
end
end

class IgnoreErrorTest < SlimmerIntegrationTest
given_response 422, %{
<html>
<head><title>422 Session expired</title>
<meta name="something" content="yes">
<script src="blah.js"></script>
<link href="app.css" rel="stylesheet" type="text/css">
</head>
<body class="body_class">
<div id="wrapper"><p class='message'>Your session expired</p></div>
</body>
</html>
<html>
}, "X-Slimmer-Ignore-Error" => "true"


def test_should_include_the_existing_error_message
assert_rendered_in_template "p.message", /^Your session expired/
end
end

class ArbitraryWrapperIdTest < SlimmerIntegrationTest
given_response 200, %{
<html>
Expand Down

0 comments on commit 4a5172a

Please sign in to comment.