Firefox的HTTP内容解压代码阅读
2007-07-09 11:29
337 查看
Firefox的HTTP内容解压代码阅读
(转载请注明来源于金庆的专栏)
参考firefox-2.0.0.4-source
RFC2612 3.5节Content codings, 内容编码定义了三种内容压缩方式:
gzip, compress, deflate, 但也可以注册新的压缩方式。
找到FireFox中的Http解压代码:
Find 'deflate' in 'D:/mozilla/netwerk/streamconv/converters/nsHTTPCompressConv.h' :
D:/mozilla/netwerk/streamconv/converters/nsHTTPCompressConv.h(58):
#define HTTP_DEFLATE_TYPE "deflate"
nsHttpCompressConv.h
#define HTTP_DEFLATE_TYPE "deflate"
#define HTTP_GZIP_TYPE "gzip"
#define HTTP_X_GZIP_TYPE "x-gzip"
#define HTTP_COMPRESS_TYPE "compress"
#define HTTP_X_COMPRESS_TYPE "x-compress"
#define HTTP_IDENTITY_TYPE "identity"
#define HTTP_UNCOMPRESSED_TYPE "uncompressed"
typedef enum ...{
HTTP_COMPRESS_GZIP,
HTTP_COMPRESS_DEFLATE,
HTTP_COMPRESS_COMPRESS,
HTTP_COMPRESS_IDENTITY
} CompressMode;
定位到类与方法:
class nsHTTPCompressConv : public nsIStreamConverter
nsHTTPCompressConv::AsyncConvertData(const char *aFromType, ...)
比较类型串,设置解压模式。例
else if (!PL_strncasecmp(aFromType, HTTP_DEFLATE_TYPE, sizeof(HTTP_DEFLATE_TYPE)-1))
mMode = HTTP_COMPRESS_DEFLATE;
nsHTTPCompressConv::OnDataAvailable(...)
针对不同解压模式进行解压。
代码阅读:
switch (mMode)
...{
case HTTP_COMPRESS_GZIP:
streamLen = check_header(iStr, streamLen, &rv);
case HTTP_COMPRESS_DEFLATE:
...
break;
default:
...
}
HTTP_COMPRESS_COMPRESS没有进行特别处理?
应该是无法解的,可能LZW解压算法有专利问题。
Gzip进行头部处理后就与deflate进行相似的解压。
case HTTP_COMPRESS_DEFLATE:
...
if (mMode == HTTP_COMPRESS_DEFLATE)
... /**//* deflate */
else
... /**//* gzip */
break;
deflate与gzip解压的代码几乎相同,应该可以合成一块代码。
区别仅有:
deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比inflateInit()多一个参数: -MAX_WBITS,表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节。使用inflateInit2时要求zlib库忽略zlib header。在zlib手册中要求windowBits为8..15,但是实际上其它范围的数据有特殊作用,见zlib.h中的注释,如负数表示raw deflate。
Apache的deflate变种可能也没有zlib header,需要添加假头后处理。即MS的错误deflate (raw deflate). zlib头第1字节一般是0x78, 第2字节与第一字节合起来的双字节应能被31整除,详见rfc1950。例如Firefox的zlib假头为0x7801,python zlib.compress()结果头部为0x789c。
deflate添假头,与gzip忽略头部效果应该是一样的,是否可以合并处理?
能否判断头部两个字节是zlib头部还是数据?是否有可能raw deflate数据按正常zlib块处理了而不报错?
check_header()
参考:GZIP文件格式简介
1. gz头:0x1f8b
2. Z_DEFLATED标志:0x08
...
其中FLG.FEXTRA的处理有个错误,额外可选项的长度应该是两个字节的合成:
mLen = ((uInt) c & 0377) << 8;
应改为
mLen |= ((uInt) c & 0377) << 8;
因为该额外字段一般在HTTP的应用中不会出现,所以没有显现出来。
我已提交:Bugzilla@Mozilla – Bug 383984
注意:GZIP文件格式简介中的额外字段的格式与rfc1952不一致,多了两个“选项ID”字节。
还有,
case GZIP_COMMENT:
if (mFlags & GZIP_COMMENT)
应改为:
case GZIP_COMMENT:
if (mFlags & COMMENT)
该错误已提交,Bugzilla@Mozilla – Bug 382849
zlib可以处理gzip头部,但所有gz函数都是针对gz文件进行的,没有直接在内存中处理gzip的,这好象是zlib功能上的一个不足吧?
相关rfc:
rfc1950: ZLIB Compressed Data Format Specification version 3.3
rfc1951: DEFLATE Compressed Data Format Specification version 1.3
(转载请注明来源于金庆的专栏)
TAGS: http,firefox,mozilla,netwerk,nshttpcompressconv,gzip,compress,deflate,zlib,代码阅读,解压
(转载请注明来源于金庆的专栏)
参考firefox-2.0.0.4-source
RFC2612 3.5节Content codings, 内容编码定义了三种内容压缩方式:
gzip, compress, deflate, 但也可以注册新的压缩方式。
找到FireFox中的Http解压代码:
Find 'deflate' in 'D:/mozilla/netwerk/streamconv/converters/nsHTTPCompressConv.h' :
D:/mozilla/netwerk/streamconv/converters/nsHTTPCompressConv.h(58):
#define HTTP_DEFLATE_TYPE "deflate"
nsHttpCompressConv.h
#define HTTP_DEFLATE_TYPE "deflate"
#define HTTP_GZIP_TYPE "gzip"
#define HTTP_X_GZIP_TYPE "x-gzip"
#define HTTP_COMPRESS_TYPE "compress"
#define HTTP_X_COMPRESS_TYPE "x-compress"
#define HTTP_IDENTITY_TYPE "identity"
#define HTTP_UNCOMPRESSED_TYPE "uncompressed"
typedef enum ...{
HTTP_COMPRESS_GZIP,
HTTP_COMPRESS_DEFLATE,
HTTP_COMPRESS_COMPRESS,
HTTP_COMPRESS_IDENTITY
} CompressMode;
定位到类与方法:
class nsHTTPCompressConv : public nsIStreamConverter
nsHTTPCompressConv::AsyncConvertData(const char *aFromType, ...)
比较类型串,设置解压模式。例
else if (!PL_strncasecmp(aFromType, HTTP_DEFLATE_TYPE, sizeof(HTTP_DEFLATE_TYPE)-1))
mMode = HTTP_COMPRESS_DEFLATE;
nsHTTPCompressConv::OnDataAvailable(...)
针对不同解压模式进行解压。
代码阅读:
switch (mMode)
...{
case HTTP_COMPRESS_GZIP:
streamLen = check_header(iStr, streamLen, &rv);
case HTTP_COMPRESS_DEFLATE:
...
break;
default:
...
}
HTTP_COMPRESS_COMPRESS没有进行特别处理?
应该是无法解的,可能LZW解压算法有专利问题。
Gzip进行头部处理后就与deflate进行相似的解压。
case HTTP_COMPRESS_DEFLATE:
...
if (mMode == HTTP_COMPRESS_DEFLATE)
... /**//* deflate */
else
... /**//* gzip */
break;
deflate与gzip解压的代码几乎相同,应该可以合成一块代码。
区别仅有:
deflate使用inflateInit(),而gzip使用inflateInit2()进行初始化,比inflateInit()多一个参数: -MAX_WBITS,表示处理raw deflate数据。因为gzip数据中的zlib压缩数据块没有zlib header的两个字节。使用inflateInit2时要求zlib库忽略zlib header。在zlib手册中要求windowBits为8..15,但是实际上其它范围的数据有特殊作用,见zlib.h中的注释,如负数表示raw deflate。
Apache的deflate变种可能也没有zlib header,需要添加假头后处理。即MS的错误deflate (raw deflate). zlib头第1字节一般是0x78, 第2字节与第一字节合起来的双字节应能被31整除,详见rfc1950。例如Firefox的zlib假头为0x7801,python zlib.compress()结果头部为0x789c。
deflate添假头,与gzip忽略头部效果应该是一样的,是否可以合并处理?
能否判断头部两个字节是zlib头部还是数据?是否有可能raw deflate数据按正常zlib块处理了而不报错?
check_header()
参考:GZIP文件格式简介
1. gz头:0x1f8b
2. Z_DEFLATED标志:0x08
...
其中FLG.FEXTRA的处理有个错误,额外可选项的长度应该是两个字节的合成:
mLen = ((uInt) c & 0377) << 8;
应改为
mLen |= ((uInt) c & 0377) << 8;
因为该额外字段一般在HTTP的应用中不会出现,所以没有显现出来。
我已提交:Bugzilla@Mozilla – Bug 383984
注意:GZIP文件格式简介中的额外字段的格式与rfc1952不一致,多了两个“选项ID”字节。
还有,
case GZIP_COMMENT:
if (mFlags & GZIP_COMMENT)
应改为:
case GZIP_COMMENT:
if (mFlags & COMMENT)
该错误已提交,Bugzilla@Mozilla – Bug 382849
zlib可以处理gzip头部,但所有gz函数都是针对gz文件进行的,没有直接在内存中处理gzip的,这好象是zlib功能上的一个不足吧?
相关rfc:
rfc1950: ZLIB Compressed Data Format Specification version 3.3
rfc1951: DEFLATE Compressed Data Format Specification version 1.3
(转载请注明来源于金庆的专栏)
TAGS: http,firefox,mozilla,netwerk,nshttpcompressconv,gzip,compress,deflate,zlib,代码阅读,解压
相关文章推荐
- Firefox的HTTP内容解压代码阅读
- Discuz!NT代码阅读笔记(1)--从HttpModule开始
- 获取http的gzip内容并解压相关问题(续)
- 开源:我的Android新闻客户端,速度快、体积小、支持离线阅读、操作简便、内容展现形式丰富多样、信息量大、功能全面 等(要代码的留下邮箱)
- Discuz!NT代码阅读笔记(1)--从HttpModule开始
- Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码(用socket解释http,不错)
- JAVA发送HTTP请求,返回HTTP响应内容,应用及实例代码
- http client对post内容gzip压缩和server端解压接收
- 获取http的gzip内容并解压相关问题
- 开源:我的Android新闻客户端,速度快、体积小、支持离线阅读、操作简便、内容展现形式丰富多样、信息量大、功能全面 等(要代码的留下邮箱)
- 阅读干货—HTTP记录与内容摘要
- 获取http的gzip内容并解压
- Discuz!NT代码阅读笔记(1)--从HttpModule开始
- 获取http的gzip内容并解压相关问题
- tinyhttp 安装和使用 (代码阅读前期准备)
- Discuz!NT代码阅读笔记(1)--从HttpModule开始 (转)
- python中BaseHTTPServer.py代码阅读分析
- android通过okhttpClient下载网页内容的实例代码
- Discuz!NT代码阅读笔记(1)--从HttpModule开始 (转)
- ffmpeg中的http协议相关代码阅读笔记