Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cowboy_decompress_h stream handler #1609

Closed
wants to merge 1 commit into from

Conversation

jdamanalo
Copy link
Contributor

Closes #946.

I added documentation with tentative 2.X as the version where this module is introduced. Alternatively, the documentation could also be left out much like when the other stream handlers were still experimental.

@essen essen added this to the 2.11 milestone Nov 23, 2023
@essen
Copy link
Member

essen commented Dec 5, 2023

Please rebase onto current master so that CI runs properly. I am planning to do a release with this and other things soon.

@essen
Copy link
Member

essen commented Dec 21, 2023

Just to be sure since copyright is important: no problem with me adding this to the top of the file?

diff --git a/src/cowboy_decompress_h.erl b/src/cowboy_decompress_h.erl
index ffbec25..f256223 100644
--- a/src/cowboy_decompress_h.erl
+++ b/src/cowboy_decompress_h.erl
@@ -1,3 +1,17 @@
+%% Copyright (c) 2023, jdamanalo <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
 -module(cowboy_decompress_h).
 -behavior(cowboy_stream).
 

Probably going to change to 2024 since 2.11 won't release this year.

@jdamanalo
Copy link
Contributor Author

Sure, no problem! [email protected] for my email should be more long-lived.

Copy link
Member

@essen essen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't have time to finish today so I'll leave a few questions. I'll continue early January.

Overall this is solid. Great job! Thanks. I did a few simplifications and whatnot, with the biggest change being making read_body_buffer a list of binaries, to avoid doing unneeded binary concatenations and memory allocations. We can give this list of binaries directly to the inflate functions and they won't need to convert them to a single binary. Win win. We do convert when passing the data forward to the next stream handler (whether we inflate or not).

I haven't reviewed the tests yet but after a quick look you get points for completeness.

Merry Christmas, cheers.

src/cowboy_decompress_h.erl Show resolved Hide resolved
src/cowboy_decompress_h.erl Show resolved Hide resolved
src/cowboy_decompress_h.erl Show resolved Hide resolved
@essen
Copy link
Member

essen commented Jan 3, 2024

One of the problems I see is that the handler cannot currently know that the content was decompressed because we do not modify the headers of the Req before passing it forward, and we do not add additional metadata to indicate we did so.

My immediate thought is that we should do both: update the headers to remove the content-encoding as well as add metadata to indicate what we decoded (basically copying the header value elsewhere). Another header field, content-length, will be inaccurate until the body is read fully, but cowboy_req then updates the Req with the right information.

If the plugin is enabled, we should remove the content-encoding, at least when we start reading the body. That's awkward though because you would have to read at least a little first to know whether you have content to decode afterwards...

So alternatively we could remove it in init but in that case it doesn't make sense to have a decompress_ignore option.

Another alternative would be to have a field in Req that the decompress handler always sets, even when not decompressing. This field would then help the user because:

  • if it is missing, the decompress handler was not used; no problem
  • if present and set to []: we know no content decoding took place (and we don't touch the content-encoding header)
  • if present and set to the content-encoding value (inside a list, see below): we know content decoding happened/will happen (and the content-encoding header was removed, its value we now have in this field)

If for some reason the user wants to disable content decoding between init and the reading of the body, they can easily reconstruct the headers as no information was lost (only moved around). Users that do not care about that will see the decoding happen transparently (the content-encoding header is removed).

I am thinking this needs proper documentation as well as a better name for decompress_ignore since we aren't just ignoring it, we are more "aborting" it but I'll think about a better name than that.

For the field in Req I am thinking of content_decoded that would be an ordered list of decoded encodings (so it can be expanded later on if needed). In our case we'll just create it or if it exists do [<<"gzip">>|Value].

@essen
Copy link
Member

essen commented Jan 4, 2024

I've done the above changes and renamed the option to decompress_enabled. I am updating the documentation now. All that's left after that is checking the tests, perhaps consolidating a thing or two, and we're good.

@essen
Copy link
Member

essen commented Jan 4, 2024

OK I am pushing the changes. A review would be appreciated, my changes are in fd9711d. Closing, thanks!

@essen essen closed this Jan 4, 2024
@jdamanalo
Copy link
Contributor Author

Reviewed and everything seems in order to me. I learned a lot from your extensive guidance. Thanks again, I really appreciate it! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Transparently handle gzipped request bodies
2 participants