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

How to decompress gzip encoded response properly? #664

Closed
WeissGotsman opened this issue Jul 17, 2017 · 9 comments
Closed

How to decompress gzip encoded response properly? #664

WeissGotsman opened this issue Jul 17, 2017 · 9 comments

Comments

@WeissGotsman
Copy link

WeissGotsman commented Jul 17, 2017

for beast version 76,

the following code is modified from the http client example, with gzip enabled. but I failed to decompress it either with the boost iostream interface or zlib interface, I also tried to save the response body string into a .gz file and try to decompress it with 7-zip, but get a CRC error.

https://pastebin.com/DiUME7Z1

My question is: is the response body in standard gzip format, when Content-Encoding: gzip, how to decompress it properly? Most http request library does not require manual decompression.

@vinniefalco
Copy link
Member

vinniefalco commented Jul 17, 2017

Most http request library does not require manual decompression.

Beast only removes the chunk-encoding. You are responsible for everything else, including gzip. Beast is not a "http request library" its a low-level protocol layering on top of HTTP. I don't know the details of gzip encoding so I'm afraid I won't be of much help. However, if you get it working you should consider publishing it as part of a utilities library that works with Beast.

@WeissGotsman
Copy link
Author

WeissGotsman commented Jul 17, 2017

I tried to compress the std::string of the uncompressed http response body (from www.example.com) with the boost iostream interface using gzip, the first 10 bytes differ from the gzipped http response body

@vinniefalco
Copy link
Member

Perhaps this is related to the "gzip header?" Does HTTP use the header when using the gzip transfer-coding? These links might help:
https://stackoverflow.com/questions/5280633/gzip-compression-of-chunked-encoding-response
https://stackoverflow.com/questions/1838699/how-can-i-decompress-a-gzip-stream-with-zlib
If you use the straight zlib API, you can add 32 to windowBits to auto-detect the header, as mentioned in the link immediately above.

@WeissGotsman
Copy link
Author

WeissGotsman commented Jul 17, 2017

It looks like the www.example.com server only use "Content-Encoding: gzip".
There is no "Transfer-Encoding: gzip" found in the response

@WeissGotsman
Copy link
Author

the answer in your second link is correct, change line 42 of my code from
if (inflateInit(&zs) != Z_OK)
to
if (inflateInit2(&zs, MAX_WBITS + 16) != Z_OK)
works

@vinniefalco
Copy link
Member

Aha!!! Nice!!

@WeissGotsman
Copy link
Author

@vinniefalco
Copy link
Member

I don't see how that integrates with Beast?

@WeissGotsman
Copy link
Author

CURL's code serves as a reference on how to setup the zlib correctly, even through boost::iostreams

//decompress with boost's interface
boost::iostreams::array_source src{ res.body.data(), res.body.size() };
boost::iostreams::filtering_istream is;

//boost::iostreams::zlib_params zparams{};
if (res["Content-Encoding"] == "deflate")
{
	std::cout << "decompressing " << res["Content-Encoding"] << std::endl;
	std::cout << "-------------------------------------------------" << '\n';
	is.push(boost::iostreams::zlib_decompressor{ -MAX_WBITS });			// deflate
}
else if (res["Content-Encoding"] == "gzip")
{
	std::cout << "decompressing " << res["Content-Encoding"] << std::endl;
	std::cout << "-------------------------------------------------" << '\n';
	is.push(boost::iostreams::gzip_decompressor{});						// gzip
}
else if (res["Content-Encoding"] == "")
{
	std::cout << "uncompressed " << res["Content-Encoding"] << std::endl;
	std::cout << "-------------------------------------------------" << '\n';
}

is.push(src);		
boost::iostreams::copy(is, std::cout);

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

No branches or pull requests

2 participants