Skip to content

Commit

Permalink
Remove the CSP response header on 304 response (#49)
Browse files Browse the repository at this point in the history
* Remove the CSP resp header on 304

* Remove OTP 24, add OTP 27
  • Loading branch information
mworrell authored Nov 14, 2024
1 parent f7bbcd1 commit 7b572b9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:

strategy:
matrix:
otp_version: [24,25,26]
otp_version: [25,26,27]
os: [ubuntu-latest]

container:
Expand Down
40 changes: 24 additions & 16 deletions src/cowmachine_controller.erl
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,17 @@

%% @doc Get default value by Key.
-spec default(DefaultID, Context) -> Result when
DefaultID:: service_available | resource_exists | auth_required | is_authorized | forbidden | upgrades_provided | allow_missing_post | malformed_request | uri_too_long | known_content_type | valid_content_headers | valid_entity_length | options | allowed_methods | known_methods | validate_content_checksum | content_types_provided | content_types_accepted | delete_resource | delete_completed | post_is_create | create_path | base_uri | process_post | language_available | charsets_provided | content_encodings_provided | transfer_encodings_provided | variances | is_conflict | multiple_choices | previously_existed | moved_permanently | moved_temporarily | last_modified | expires | generate_etag | finish_request,
Context :: cowmachine_req:context(),
Result :: no_charset | no_default | undefined | boolean() | list(binary()).
DefaultID:: service_available | resource_exists | auth_required | is_authorized |
forbidden | upgrades_provided | allow_missing_post | malformed_request |
uri_too_long | known_content_type | valid_content_headers | valid_entity_length |
options | allowed_methods | known_methods | validate_content_checksum |
content_types_provided | content_types_accepted | delete_resource | delete_completed |
post_is_create | create_path | base_uri | process_post | language_available |
charsets_provided | content_encodings_provided | transfer_encodings_provided |
variances | is_conflict | multiple_choices | previously_existed | moved_permanently |
moved_temporarily | last_modified | expires | generate_etag | finish_request,
Context :: cowmachine_req:context(),
Result :: no_charset | no_default | undefined | boolean() | list(binary()).
default(service_available, _Context) ->
true;
default(resource_exists, _Context) ->
Expand Down Expand Up @@ -134,8 +142,8 @@ default(_, _Context) ->
%% @doc Content types that are textual and should have a charset defined.

-spec is_text(ContentType) -> Result when
ContentType :: cow_http_hd:media_type(),
Result :: boolean().
ContentType :: cow_http_hd:media_type(),
Result :: boolean().
is_text({<<"text">>, _, _}) -> true;
is_text({<<"application">>, <<"json">>, _}) -> true;
is_text({<<"application">>, <<"ld+json">>, _}) -> true;
Expand All @@ -157,11 +165,11 @@ is_text(_) ->
%% @doc Export and run function `Fun'.

-spec do(Fun, State, Context) -> Result when
Fun :: atom(),
State :: cmstate(),
Context :: cowmachine_req:context(),
Result :: {ContentType, Context},
ContentType :: cow_http_hd:media_type().
Fun :: atom(),
State :: cmstate(),
Context :: cowmachine_req:context(),
Result :: {ContentType, Context},
ContentType :: cow_http_hd:media_type().
do(Fun, #cmstate{ controller = Controller }, Context) when is_atom(Fun) ->
case erlang:function_exported(Controller, Fun, 1) of
true ->
Expand All @@ -176,12 +184,12 @@ do(Fun, #cmstate{ controller = Controller }, Context) when is_atom(Fun) ->
%% @doc Export and process `State' with `Context'.

-spec do_process(ContentType, State, Context) -> Result when
ContentType :: cow_http_hd:media_type(),
State :: cmstate(),
Context :: cowmachine_req:context(),
Result :: {Res, Context},
Res :: boolean() | cowmachine_req:halt() | {error, any(), any()} | {error, any()} |
cowmachine_req:resp_body().
ContentType :: cow_http_hd:media_type(),
State :: cmstate(),
Context :: cowmachine_req:context(),
Result :: {Res, Context},
Res :: boolean() | cowmachine_req:halt() | {error, any(), any()} | {error, any()} |
cowmachine_req:resp_body().
do_process(ContentType, #cmstate{ controller = Controller }, Context) ->
case erlang:function_exported(Controller, process, 4) of
true ->
Expand Down
11 changes: 10 additions & 1 deletion src/cowmachine_decision_core.erl
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ d(DecisionID, State, Context) ->
Context :: cowmachine_req:context(),
%Result :: {State, Context}.
Result :: {term(), #cmstate{}, term()}.
respond(Code, State, Context) ->
respond(Code, State, Context0) ->
Context = maybe_drop_csp_headers(Code, Context0),
{State1, Context1} = case Code of
Ok when Ok >= 200, Ok =< 299 ->
% Response all ok
Expand Down Expand Up @@ -172,6 +173,14 @@ respond(Code, Headers, State, Context) ->
ContextHs = cowmachine_req:set_resp_headers(Headers, Context),
respond(Code, State, ContextHs).

%% @doc On 304, remove the CSP header. The UA will use the cached version, with
%% the CSP of the cached version. If we provide a new CSP then that one will
%% supercede the cached one, which will give nonce problems.
maybe_drop_csp_headers(304, Context) ->
cowmachine_req:remove_resp_header(<<"content-security-policy">>, Context);
maybe_drop_csp_headers(_Code, Context) ->
Context.

%% @throws {stop_request, Code, Reason}

error_response(Code, Reason, State, Context) ->
Expand Down

0 comments on commit 7b572b9

Please sign in to comment.