From fd9711d9495e4ddcd41eda7a284dfc7f37c11f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Thu, 4 Jan 2024 15:15:41 +0100 Subject: Rework and improve the decompress stream handler The read buffer was changed into an iovec to avoid doing too many binary concatenations and allocations. Decompression happens transparently: when decoding gzip, the content-encoding header is removed (we only decode when "gzip" is the only encoding so nothing remains). We always add a content_decoded key to the Req object. This key contains a list of codings that were decoded, in the reverse order in which they were. Currently it can only be empty or contain <<"gzip">> but future improvements or user handlers may see it contain more values. The option to disable decompression was renamed to decompress_enabled and defaults to true. It is no longer possible to enable/disable decompression in the middle of reading the body: this ensures that the data we pass forward is always valid. Various smaller improvements were made to the code, tests and manual pages. --- doc/src/guide/streams.asciidoc | 6 ++--- doc/src/manual/cowboy_app.asciidoc | 1 + doc/src/manual/cowboy_decompress_h.asciidoc | 34 +++++++++++++++++++---------- 3 files changed, 27 insertions(+), 14 deletions(-) (limited to 'doc') diff --git a/doc/src/guide/streams.asciidoc b/doc/src/guide/streams.asciidoc index b6e4d34..e8ddae0 100644 --- a/doc/src/guide/streams.asciidoc +++ b/doc/src/guide/streams.asciidoc @@ -66,9 +66,9 @@ enabled by default. It is a good example for writing your own handlers that will modify responses. link:man:cowboy_decompress_h(3)[cowboy_decompress_h] will -automatically decompress requests when possible. It is not -enabled by default. It is a good example for writing your -own handlers that will modify requests. +automatically decompress request bodies when possible. +It is not enabled by default. It is a good example for +writing your own handlers that will modify requests. link:man:cowboy_metrics_h(3)[cowboy_metrics_h] gathers metrics about a stream then passes them to a configurable diff --git a/doc/src/manual/cowboy_app.asciidoc b/doc/src/manual/cowboy_app.asciidoc index 8db84b1..fd833be 100644 --- a/doc/src/manual/cowboy_app.asciidoc +++ b/doc/src/manual/cowboy_app.asciidoc @@ -36,6 +36,7 @@ Stream handlers: * link:man:cowboy_stream_h(3)[cowboy_stream_h(3)] - Default stream handler * link:man:cowboy_compress_h(3)[cowboy_compress_h(3)] - Compress stream handler +* link:man:cowboy_decompress_h(3)[cowboy_decompress_h(3)] - Decompress stream handler * link:man:cowboy_metrics_h(3)[cowboy_metrics_h(3)] - Metrics stream handler * link:man:cowboy_tracer_h(3)[cowboy_tracer_h(3)] - Tracer stream handler diff --git a/doc/src/manual/cowboy_decompress_h.asciidoc b/doc/src/manual/cowboy_decompress_h.asciidoc index 63ee0ee..8598ae4 100644 --- a/doc/src/manual/cowboy_decompress_h.asciidoc +++ b/doc/src/manual/cowboy_decompress_h.asciidoc @@ -7,18 +7,26 @@ cowboy_decompress_h - Decompress stream handler == Description The module `cowboy_decompress_h` decompresses request bodies -automatically when the server supports it. Requests will -only be decompressed when their compression ratio is lower -than the configured limit. Mismatch of the content and -`content-encoding` is rejected with `400 Bad Request`. +automatically when the server supports it. + +The only compression algorithm currently supported is the +gzip algorithm. Another limitation is that decompression +is only attempted when gzip is the only content-encoding +in the request. + +This stream handler always adds a field to the Req object +with the name `content_decoded` which is treated as a +list of decoded content-encoding values. Currently this +list may only contain the `<<"gzip">>` binary if content +was decoded; or be empty otherwise. == Options [source,erlang] ---- opts() :: #{ - decompress_ratio_limit => non_neg_integer(), - decompress_ignore => boolean() + decompress_enabled => boolean(), + decompress_ratio_limit => non_neg_integer() } ---- @@ -28,17 +36,21 @@ The default value is given next to the option name: decompress_ratio_limit (20):: The max ratio of the compressed and decompressed body -before it is rejected with `413 Payload Too Large`. +before it is rejected with a `413 Payload Too Large` +error response. + This option can be updated at any time using the `set_options` stream handler command. -decompress_ignore (false):: +decompress_enabled (true):: -Whether the handler will be ignored. +Whether the handler is enabled by default. + -This option can be updated at any time using the -`set_options` stream handler command. +This option can be updated using the `set_options` +stream handler command. This allows disabling +decompression for the current stream. Attempts +to enable or disable decompression after starting +to read the body will be ignored. == Events -- cgit v1.2.3