I was able to fix this problem with two code changes in the boost.iostreams implementation, as follows.
Change #1: at libs/iostreams/src/gzip.cpp:65: change "state_ = s_extra;" to "state_ = s_xlen;"
Rationale: without this change, it looks like state s_xlen is never entered so the length of the extra data is not parsed. Update: I notice this change was already raised in ticket #5908, and has already been fixed in trunk.
Change #2: at libs/iostreams/src/zlib.cpp:153: change "crc_imp_ = 0;" to "crc_ = crc_imp_ = 0;"
Rationale: without this change, an empty block of data does not re-initialise the member variable crc_ of zlib_base. This causes an exception on line 447 of boost/iostreams/filter/gzip.hpp.
Could someone take a look at this and let me know if this change is really appropriate? (Or perhaps I'm doing something wrong.) I can create a bug report if desired.