From a7c89b0e3fc8f55c9ac2336d422d0988a6978de1 Mon Sep 17 00:00:00 2001 From: Nicholas Guriev Date: Fri, 23 Oct 2020 21:13:47 +0300 Subject: [PATCH] Do not reopen stdout while image resizing On Linux, some web-servers (Apache in particular) close file with fd = 1 and offer something else as stdout. Notable difference can be seen with a pipe and an immediate redirection. Consider: $ REQUEST_URI=/avatar/68b329da9893e34099c7d8ad5cb9c940 libravatarserv | cat > /tmp/response1.out $ REQUEST_URI=/avatar/68b329da9893e34099c7d8ad5cb9c940 libravatarserv > /tmp/response2.out $ diff -s /tmp/response{1,2}.out Binary files /tmp/response1.out and /tmp/response2.out differ Solution. The output should be identical in both cases. So do not let ImageMagick to open /dev/stdout by itself, instead write the resulted image to an in-memory buffer and then to a file associated with the "cout" global object. --- src/image.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/image.cpp b/src/image.cpp index 38c5bc3..3791883 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -73,7 +73,11 @@ void image::write(Image &image) string magick = image.image.magick(); std::transform(magick.begin(), magick.end(), magick.begin(), ::tolower); - cout << "Content-Type: image/" << magick << endl << endl; - cout.flush(); // We need to flush before we use /dev/stdout directly. - image.image.write("/dev/stdout"); + Magick::Blob res_buffer; + image.image.magick(magick); // force the same format + image.image.write(&res_buffer); + + cout << "Content-Type: image/" << magick << endl; + cout << "Content-Length: " << res_buffer.length() << endl << endl; + cout.write(static_cast(res_buffer.data()), res_buffer.length()); }