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.
This commit is contained in:
Nicholas Guriev 2020-10-23 21:13:47 +03:00
parent de7e61a2fe
commit a7c89b0e3f
No known key found for this signature in database
GPG Key ID: 49DF78A5E931E3E1
1 changed files with 7 additions and 3 deletions

View File

@ -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<const char*>(res_buffer.data()), res_buffer.length());
}