=8 #定义定义成员级别8 #否则 #定义定义内存级别最大内存级别 #endif/!最大记忆水平 #如果!已定义(断言) #定义断言(表达式)((无效)0) #endif/!断言 静态int-gz_-magic[2]={0x1f,0x8b};/*gzip魔术头*/ void\uuuu write\u magic\u头(std::stringstream&output){ char*dest=(char*)malloc(10); sprintf(目标,“%c%c%c%c%c%c%c%c%c%c”,gz_magic[0],gz_magic[1],Z_压缩,0/*标志*/,0,0,0/*时间*/,0/*xflags*/,操作系统代码); 输出写入(常量转换(dest),10); 免费(目的地); }; 整数定义标准(标准::stringstream&source,标准::stringstream&dest,整数级别=Z_最佳速度){ //2019年1月18日上午6:00 整流罩,齐平; 未签字的有; z_溪strm; /*分配放气状态*/ strm.zalloc=Z_NULL; strm.zfree=Z_NULL; strm.opaque=Z_NULL; ret=放气装置2(&strm,液位,Z)放气, -马克斯·比茨, 定义成员级别,默认策略, ZLIB_版本(int)sizeof(z_流); 如果(ret!=Z_OK) 返回ret; /*压缩到流结束*/ std::流大小n; source.seekg(0,std::ios::end);//转到流的末尾 std::streamoff size=source.tellg(); source.seekg(0,std::ios::beg);//返回流的起始 int write_len=0; 做{ [块]中的字符; n=source.rdbuf()->sgetn(in,CHUNK); strm.avail_in=(uInt)n; 尺寸-=n; flush=size,c++,web,gzip,zlib,C++,Web,Gzip,Zlib" /> =8 #定义定义成员级别8 #否则 #定义定义内存级别最大内存级别 #endif/!最大记忆水平 #如果!已定义(断言) #定义断言(表达式)((无效)0) #endif/!断言 静态int-gz_-magic[2]={0x1f,0x8b};/*gzip魔术头*/ void\uuuu write\u magic\u头(std::stringstream&output){ char*dest=(char*)malloc(10); sprintf(目标,“%c%c%c%c%c%c%c%c%c%c”,gz_magic[0],gz_magic[1],Z_压缩,0/*标志*/,0,0,0/*时间*/,0/*xflags*/,操作系统代码); 输出写入(常量转换(dest),10); 免费(目的地); }; 整数定义标准(标准::stringstream&source,标准::stringstream&dest,整数级别=Z_最佳速度){ //2019年1月18日上午6:00 整流罩,齐平; 未签字的有; z_溪strm; /*分配放气状态*/ strm.zalloc=Z_NULL; strm.zfree=Z_NULL; strm.opaque=Z_NULL; ret=放气装置2(&strm,液位,Z)放气, -马克斯·比茨, 定义成员级别,默认策略, ZLIB_版本(int)sizeof(z_流); 如果(ret!=Z_OK) 返回ret; /*压缩到流结束*/ std::流大小n; source.seekg(0,std::ios::end);//转到流的末尾 std::streamoff size=source.tellg(); source.seekg(0,std::ios::beg);//返回流的起始 int write_len=0; 做{ [块]中的字符; n=source.rdbuf()->sgetn(in,CHUNK); strm.avail_in=(uInt)n; 尺寸-=n; flush=size,c++,web,gzip,zlib,C++,Web,Gzip,Zlib" />

在web浏览器(c+;+;)中定义的zlib gzip无效响应 我有一个C++的FASTCGI应用程序。我想用gzip压缩将我的回复发送给客户端。 (ZLIB版本“1.2.11”) 以下是我的源代码示例: #pragma warning (disable : 4231) #pragma warning(disable : 4996) //3:45 PM 11/24/2018 #if !(defined(_WIN32)||defined(_WIN64)) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) #error Have to check !TODO #else #if !defined(_IOSTREAM_) #include <iostream> #endif//!_IOSTREAM_ #ifndef _WINDOWS_ #include <windows.h> #endif//!_WINDOWS_ #endif//_WIN32||_WIN64/__unix__ #if !defined(_INC_STDIO) #include <stdio.h> /* defines FILENAME_MAX, printf, sprintf */ #endif//!_INC_STDIO #ifndef _XSTRING_ #include <string>// !_XSTRING_// memcpy, memset #endif //!_XSTRING_ #if !defined(ZLIB_H) #include <zlib.h> #endif//!ZLIB_H #if !defined(_SSTREAM_) #include <sstream> // std::stringstream #endif//_SSTREAM_ #if !defined(CHUNK) #define CHUNK 16384 #endif//!CHUNK #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif//!OS_CODE #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif//!MAX_MEM_LEVEL #if !defined(assert) #define assert(expression) ((void)0) #endif//!assert static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */ void __write_magic_header(std::stringstream&output) { char*dest = (char*)malloc(10); sprintf(dest, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], Z_DEFLATED, 0 /*flags*/, 0, 0, 0, 0 /*time*/, 0 /*xflags*/, OS_CODE); output.write(const_cast<const char*>(dest), 10); free(dest); }; int ____def_strm(std::stringstream&source, std::stringstream&dest, int level = Z_BEST_SPEED) { //6:00 AM 1/18/2019 int ret, flush; unsigned have; z_stream strm; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit2_(&strm, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, (int)sizeof(z_stream)); if (ret != Z_OK) return ret; /* compress until end of stream */ std::streamsize n; source.seekg(0, std::ios::end);//Go to end of stream std::streamoff size = source.tellg(); source.seekg(0, std::ios::beg);//Back to begain of stream int write_len = 0; do { char in[CHUNK]; n = source.rdbuf()->sgetn(in, CHUNK); strm.avail_in = (uInt)n; size -= n; flush = size <= 0 ? Z_FINISH : Z_NO_FLUSH; strm.next_in = (Bytef*)in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { char out[CHUNK]; strm.avail_out = CHUNK; strm.next_out = (Bytef*)out; ret = deflate(&strm, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ have = CHUNK - strm.avail_out; dest.write(out, have); write_len += have; } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input will be used */ /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)deflateEnd(&strm); return write_len; }; void compress_gzip (std::stringstream&source, std::stringstream&output) { __write_magic_header(output); ____def_strm(source, output); return; }; void gzip_test(int loop) { std::stringstream body(std::stringstream::in | std::stringstream::out | std::stringstream::binary); for (int i = 0; i < loop; i++) { body << "<b>Hello World</b><br/>"; body << "<a href=\"/wiki/General-purpose_programming_language\" title=\"General-purpose programming language\">general-purpose programming language</a>"; body << "\r\n"; } std::stringstream compressed(std::stringstream::in | std::stringstream::out | std::stringstream::binary); compress_gzip(body, compressed); std::stringstream().swap(body); std::cout << compressed.str(); std::stringstream().swap(compressed); }; void write_header(const char* ct) { std::cout << "Content-Type:" << ct << "\n"; std::cout << "Accept-Ranges:bytes\n"; }; int main(int argc, char *argv[], char*envp[]) { //100 problem ==> ERR_CONTENT_DECODING_FAILED //1000 problem ==> ERR_CONTENT_DECODING_FAILED //10000 Ok write_header("text/plain"); std::cout << "Content-Encoding:gzip\n"; std::cout << "\r\n"; gzip_test(10000); return EXIT_SUCCESS; }; #杂注警告(禁用:4231) #杂注警告(禁用:4996) //2018年11月24日下午3:45 #如果!(已定义(WIN32)|已定义(WIN64))和&(已定义(uuUnix)|已定义(uUnix)| |(已定义(uuApple)&&defined(uuu MACH)) #错误必须检查!待办事项 #否则 #如果!已定义(_IOSTREAM) #包括 #endif/_流_ #ifndef\u窗口_ #包括 #endif/_窗户_ #endif/_WIN32 | | | u WIN64/uu unix__ #如果!已定义(_INC_STDIO) #include/*定义文件名\u MAX、printf、sprintf*/ #endif/_公司 #ifndefxstring_ #包括/_XSTRING//memcpy,memset #endif/_XSTRING_ #如果!已定义(ZLIB_H) #包括 #endif/!兹利布什 #如果!已定义(\u SSTREAM\ux) #include//std::stringstream #endif/\u SSTREAM_ #如果!已定义(块) #定义块16384 #endif/!大块 #ifndef操作系统代码 #定义操作系统代码0x03/*假定为Unix*/ #endif/!操作系统代码 #如果最大内存级别>=8 #定义定义成员级别8 #否则 #定义定义内存级别最大内存级别 #endif/!最大记忆水平 #如果!已定义(断言) #定义断言(表达式)((无效)0) #endif/!断言 静态int-gz_-magic[2]={0x1f,0x8b};/*gzip魔术头*/ void\uuuu write\u magic\u头(std::stringstream&output){ char*dest=(char*)malloc(10); sprintf(目标,“%c%c%c%c%c%c%c%c%c%c”,gz_magic[0],gz_magic[1],Z_压缩,0/*标志*/,0,0,0/*时间*/,0/*xflags*/,操作系统代码); 输出写入(常量转换(dest),10); 免费(目的地); }; 整数定义标准(标准::stringstream&source,标准::stringstream&dest,整数级别=Z_最佳速度){ //2019年1月18日上午6:00 整流罩,齐平; 未签字的有; z_溪strm; /*分配放气状态*/ strm.zalloc=Z_NULL; strm.zfree=Z_NULL; strm.opaque=Z_NULL; ret=放气装置2(&strm,液位,Z)放气, -马克斯·比茨, 定义成员级别,默认策略, ZLIB_版本(int)sizeof(z_流); 如果(ret!=Z_OK) 返回ret; /*压缩到流结束*/ std::流大小n; source.seekg(0,std::ios::end);//转到流的末尾 std::streamoff size=source.tellg(); source.seekg(0,std::ios::beg);//返回流的起始 int write_len=0; 做{ [块]中的字符; n=source.rdbuf()->sgetn(in,CHUNK); strm.avail_in=(uInt)n; 尺寸-=n; flush=size

在web浏览器(c+;+;)中定义的zlib gzip无效响应 我有一个C++的FASTCGI应用程序。我想用gzip压缩将我的回复发送给客户端。 (ZLIB版本“1.2.11”) 以下是我的源代码示例: #pragma warning (disable : 4231) #pragma warning(disable : 4996) //3:45 PM 11/24/2018 #if !(defined(_WIN32)||defined(_WIN64)) && (defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))) #error Have to check !TODO #else #if !defined(_IOSTREAM_) #include <iostream> #endif//!_IOSTREAM_ #ifndef _WINDOWS_ #include <windows.h> #endif//!_WINDOWS_ #endif//_WIN32||_WIN64/__unix__ #if !defined(_INC_STDIO) #include <stdio.h> /* defines FILENAME_MAX, printf, sprintf */ #endif//!_INC_STDIO #ifndef _XSTRING_ #include <string>// !_XSTRING_// memcpy, memset #endif //!_XSTRING_ #if !defined(ZLIB_H) #include <zlib.h> #endif//!ZLIB_H #if !defined(_SSTREAM_) #include <sstream> // std::stringstream #endif//_SSTREAM_ #if !defined(CHUNK) #define CHUNK 16384 #endif//!CHUNK #ifndef OS_CODE # define OS_CODE 0x03 /* assume Unix */ #endif//!OS_CODE #if MAX_MEM_LEVEL >= 8 # define DEF_MEM_LEVEL 8 #else # define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif//!MAX_MEM_LEVEL #if !defined(assert) #define assert(expression) ((void)0) #endif//!assert static int gz_magic[2] = { 0x1f, 0x8b }; /* gzip magic header */ void __write_magic_header(std::stringstream&output) { char*dest = (char*)malloc(10); sprintf(dest, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1], Z_DEFLATED, 0 /*flags*/, 0, 0, 0, 0 /*time*/, 0 /*xflags*/, OS_CODE); output.write(const_cast<const char*>(dest), 10); free(dest); }; int ____def_strm(std::stringstream&source, std::stringstream&dest, int level = Z_BEST_SPEED) { //6:00 AM 1/18/2019 int ret, flush; unsigned have; z_stream strm; /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit2_(&strm, level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, ZLIB_VERSION, (int)sizeof(z_stream)); if (ret != Z_OK) return ret; /* compress until end of stream */ std::streamsize n; source.seekg(0, std::ios::end);//Go to end of stream std::streamoff size = source.tellg(); source.seekg(0, std::ios::beg);//Back to begain of stream int write_len = 0; do { char in[CHUNK]; n = source.rdbuf()->sgetn(in, CHUNK); strm.avail_in = (uInt)n; size -= n; flush = size <= 0 ? Z_FINISH : Z_NO_FLUSH; strm.next_in = (Bytef*)in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { char out[CHUNK]; strm.avail_out = CHUNK; strm.next_out = (Bytef*)out; ret = deflate(&strm, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ have = CHUNK - strm.avail_out; dest.write(out, have); write_len += have; } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input will be used */ /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)deflateEnd(&strm); return write_len; }; void compress_gzip (std::stringstream&source, std::stringstream&output) { __write_magic_header(output); ____def_strm(source, output); return; }; void gzip_test(int loop) { std::stringstream body(std::stringstream::in | std::stringstream::out | std::stringstream::binary); for (int i = 0; i < loop; i++) { body << "<b>Hello World</b><br/>"; body << "<a href=\"/wiki/General-purpose_programming_language\" title=\"General-purpose programming language\">general-purpose programming language</a>"; body << "\r\n"; } std::stringstream compressed(std::stringstream::in | std::stringstream::out | std::stringstream::binary); compress_gzip(body, compressed); std::stringstream().swap(body); std::cout << compressed.str(); std::stringstream().swap(compressed); }; void write_header(const char* ct) { std::cout << "Content-Type:" << ct << "\n"; std::cout << "Accept-Ranges:bytes\n"; }; int main(int argc, char *argv[], char*envp[]) { //100 problem ==> ERR_CONTENT_DECODING_FAILED //1000 problem ==> ERR_CONTENT_DECODING_FAILED //10000 Ok write_header("text/plain"); std::cout << "Content-Encoding:gzip\n"; std::cout << "\r\n"; gzip_test(10000); return EXIT_SUCCESS; }; #杂注警告(禁用:4231) #杂注警告(禁用:4996) //2018年11月24日下午3:45 #如果!(已定义(WIN32)|已定义(WIN64))和&(已定义(uuUnix)|已定义(uUnix)| |(已定义(uuApple)&&defined(uuu MACH)) #错误必须检查!待办事项 #否则 #如果!已定义(_IOSTREAM) #包括 #endif/_流_ #ifndef\u窗口_ #包括 #endif/_窗户_ #endif/_WIN32 | | | u WIN64/uu unix__ #如果!已定义(_INC_STDIO) #include/*定义文件名\u MAX、printf、sprintf*/ #endif/_公司 #ifndefxstring_ #包括/_XSTRING//memcpy,memset #endif/_XSTRING_ #如果!已定义(ZLIB_H) #包括 #endif/!兹利布什 #如果!已定义(\u SSTREAM\ux) #include//std::stringstream #endif/\u SSTREAM_ #如果!已定义(块) #定义块16384 #endif/!大块 #ifndef操作系统代码 #定义操作系统代码0x03/*假定为Unix*/ #endif/!操作系统代码 #如果最大内存级别>=8 #定义定义成员级别8 #否则 #定义定义内存级别最大内存级别 #endif/!最大记忆水平 #如果!已定义(断言) #定义断言(表达式)((无效)0) #endif/!断言 静态int-gz_-magic[2]={0x1f,0x8b};/*gzip魔术头*/ void\uuuu write\u magic\u头(std::stringstream&output){ char*dest=(char*)malloc(10); sprintf(目标,“%c%c%c%c%c%c%c%c%c%c”,gz_magic[0],gz_magic[1],Z_压缩,0/*标志*/,0,0,0/*时间*/,0/*xflags*/,操作系统代码); 输出写入(常量转换(dest),10); 免费(目的地); }; 整数定义标准(标准::stringstream&source,标准::stringstream&dest,整数级别=Z_最佳速度){ //2019年1月18日上午6:00 整流罩,齐平; 未签字的有; z_溪strm; /*分配放气状态*/ strm.zalloc=Z_NULL; strm.zfree=Z_NULL; strm.opaque=Z_NULL; ret=放气装置2(&strm,液位,Z)放气, -马克斯·比茨, 定义成员级别,默认策略, ZLIB_版本(int)sizeof(z_流); 如果(ret!=Z_OK) 返回ret; /*压缩到流结束*/ std::流大小n; source.seekg(0,std::ios::end);//转到流的末尾 std::streamoff size=source.tellg(); source.seekg(0,std::ios::beg);//返回流的起始 int write_len=0; 做{ [块]中的字符; n=source.rdbuf()->sgetn(in,CHUNK); strm.avail_in=(uInt)n; 尺寸-=n; flush=size,c++,web,gzip,zlib,C++,Web,Gzip,Zlib,您没有写入包含CRC和数据长度的gzip页脚: std::streamoff size = source.tellg(); int totalSize = size; int tcrc = 0; ... n = source.rdbuf()->sgetn( in, CHUNK ); strm.avail_in = (uInt)n; tcrc = crc32( tcrc, (uint8_t*)in, n ); ... (void)deflateEnd( &strm );

您没有写入包含CRC和数据长度的gzip页脚:

std::streamoff size = source.tellg();
int totalSize = size;
int tcrc = 0;
...
  n = source.rdbuf()->sgetn( in, CHUNK );
  strm.avail_in = (uInt)n;
  tcrc = crc32( tcrc, (uint8_t*)in, n );
...
(void)deflateEnd( &strm );
dest.write( (char*)&tcrc, sizeof( tcrc ) );
dest.write( (char*)&totalSize, sizeof( totalSize ) );
return write_len;
您的
\u write\u magic\u header
方法也不正确,因为它只分配10个字节,然后使用
sprintf
写入10个字符,这实际上会写入11个溢出缓冲区的字节

在windows上,无法通过
std::cout
发送二进制数据,这与在未指定
binary
的情况下使用流的
打开文件时遇到的问题相同。要修复此调用,请在使用
std::cout
之前执行以下操作:

_setmode( _fileno( stdout ), _O_BINARY );
与您的问题无关的其他一些要点:

  • 不要用
    #ifdef
    包装您的include,您使用的宏是实现细节,在现代编译器上应该不会提供任何/可忽略的性能差异
  • 不要在方法名或其他标识符的开头使用“_u”,这些名称(以及“u”后跟大写字母)保留供编译器使用

  • 我使用的是Microsoft Visual Studio Community 2017 15.8.6版。我已经解释了我的问题,并尝试了所有可用的资源。我已经花了更多的时间来解决这个问题。请查看我的更新并帮助我…您是否使用了调试器?是@ThomasSablik。此程序可以生成,并且没有定义任何问题。但在发送请求f时rom浏览器(如chrome或Firefox)显示错误错误#错误#内容(u解码)失败您是否尝试获取消息(如使用netcat)并对其进行解压缩?压缩消息并将其与程序的输出进行比较。您的程序似乎生成了无效数据尝试添加
    (文件号(stdout),(二进制);
    到程序的开头: