0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 20:30:23 +00:00

Add compress_threshold protocol option

Currently the compression threshold is set to 300 and hardcoded in the
codebase. There are cases where it make sense to allow this to be
configured, for instance when you want to enforce all responses to be
compressed regarldess of their size.
This commit is contained in:
Steve Domin 2018-02-17 16:43:46 +03:00 committed by Loïc Hoguin
parent 30e117a942
commit 09bf1199aa
No known key found for this signature in database
GPG key ID: 8A9DF795F6FED764
4 changed files with 17 additions and 7 deletions

View file

@ -23,6 +23,7 @@
-record(state, {
next :: any(),
threshold :: non_neg_integer() | undefined,
compress = undefined :: undefined | gzip,
deflate = undefined :: undefined | zlib:zstream()
}).
@ -31,8 +32,9 @@
-> {cowboy_stream:commands(), #state{}}.
init(StreamID, Req, Opts) ->
State0 = check_req(Req),
CompressThreshold = maps:get(compress_threshold, Opts, 300),
{Commands0, Next} = cowboy_stream:init(StreamID, Req, Opts),
fold(Commands0, State0#state{next=Next}).
fold(Commands0, State0#state{next=Next, threshold=CompressThreshold}).
-spec data(cowboy_stream:streamid(), cowboy_stream:fin(), cowboy_req:resp_body(), State)
-> {cowboy_stream:commands(), State} when State::#state{}.
@ -100,16 +102,16 @@ fold([], State, Acc) ->
fold([Response={response, _, _, {sendfile, _, _, _}}|Tail], State, Acc) ->
fold(Tail, State, [Response|Acc]);
%% We compress full responses directly, unless they are lower than
%% 300 bytes or we find we are not able to by looking at the headers.
%% @todo It might be good to allow this size to be configured?
fold([Response0={response, _, Headers, Body}|Tail], State0, Acc) ->
%% the configured threshold or we find we are not able to by looking at the headers.
fold([Response0={response, _, Headers, Body}|Tail],
State0=#state{threshold=CompressThreshold}, Acc) ->
case check_resp_headers(Headers, State0) of
State=#state{compress=undefined} ->
fold(Tail, State, [Response0|Acc]);
State1 ->
BodyLength = iolist_size(Body),
if
BodyLength =< 300 ->
BodyLength =< CompressThreshold ->
fold(Tail, State1, [Response0|Acc]);
true ->
{Response, State} = gzip_response(Response0, State1),

View file

@ -25,6 +25,7 @@
-export([system_code_change/4]).
-type opts() :: #{
compress_threshold => non_neg_integer(),
connection_type => worker | supervisor,
env => cowboy_middleware:env(),
idle_timeout => timeout(),
@ -46,7 +47,9 @@
shutdown_timeout => timeout(),
stream_handlers => [module()],
tracer_callback => cowboy_tracer_h:tracer_callback(),
tracer_match_specs => cowboy_tracer_h:tracer_match_specs()
tracer_match_specs => cowboy_tracer_h:tracer_match_specs(),
%% Open ended because configured stream handlers might add options.
_ => _
}.
-export_type([opts/0]).

View file

@ -27,6 +27,7 @@
-export([system_code_change/4]).
-type opts() :: #{
compress_threshold => non_neg_integer(),
connection_type => worker | supervisor,
enable_connect_protocol => boolean(),
env => cowboy_middleware:env(),
@ -47,7 +48,9 @@
shutdown_timeout => timeout(),
stream_handlers => [module()],
tracer_callback => cowboy_tracer_h:tracer_callback(),
tracer_match_specs => cowboy_tracer_h:tracer_match_specs()
tracer_match_specs => cowboy_tracer_h:tracer_match_specs(),
%% Open ended because configured stream handlers might add options.
_ => _
}.
-export_type([opts/0]).

View file

@ -11,6 +11,8 @@ init(Req0, State=reply) ->
cowboy_req:reply(200, #{}, lists:duplicate(100, $a), Req0);
<<"large">> ->
cowboy_req:reply(200, #{}, lists:duplicate(100000, $a), Req0);
<<"over-threshold">> ->
cowboy_req:reply(200, #{}, lists:duplicate(200, $a), Req0);
<<"content-encoding">> ->
cowboy_req:reply(200, #{<<"content-encoding">> => <<"compress">>},
lists:duplicate(100000, $a), Req0);