http中chunked编码的特殊编码头

在进行Http传输中,可以通过设置Transfer-Encoding以进行传输编码。其中chunked编码表示分块进行数据传输,其通过一个0长度的chunk块表示数据传输完毕。对于在传输过程中的chunked块,则通过以下的一个数据格式进行描述:

chunk-size 
[ chunk-extension ] 
CRLF 
chunk-data 
CRLF

不考虑chunked-extension属性,则可以理解为先描述块长度,然后接回车换行,接下来再描述相应长度的数据信息,最后接回车换行符,即完成一个chunk编码信息。

这里的chunk-size,与其它的传输不同,这里需要设置为 16 进制数字字符串。即不是传输认为的设置一个长度值即可。对于一个长度值为255的chunk块,其16进制为ff(小写表示),直接编码即为 ff。但这里要求为数字字符串,即以字符串的方式来描述编码值,编码为'f''f',针对f字符的编码值为 66(16进制),那么255长度的实际编码值即为 66 66。

一个255长度的编码片断,类似如下所示:

如上所示的标记处,前面为头结束的2个CRLF值。

在Http编码中,只有这里的chunked编码有点特别。其它的长度信息如content-length值等,都是使用正常的长度值(16进制),确实有点奇怪。在编码时,如果对这里的编码头没写正确,那么输出到客户端的数据永远都是错的…

transfer-encoding和content-length的不同实现

前段时间在项目中看到如下的代码:

		HttpServletResponse response = (HttpServletResponse)servletResponse;
		response.setHeader("Transfer-Encoding", "utf8");
		filterChain.doFilter(servletRequest, servletResponse);

原意是想对输出的内容进行编码,却用错了响应头,结果这个错误的响应头对后面的客户端程序带来了许多麻烦。这里有必要对这个这块的内容进行详细地了解。

传输数据编码:Transfer-Encoding
数据编码,即表示数据在网络传输当中,使用怎么样的保证方式来保证数据是安全成功地传输处理。可以是分段传输,也可以是不分段,直接使用原数据进行传输。
有效的值为:Trunked和Identity.
传输内容编码:Content-Encoding
内容编码,即整个数据信息是在数据器端经过怎样的编码处理,然后客户端会以怎么的编码来反向处理,以得到原始的内容。这里的内容编码主要是指压缩编码,即服务器端压缩,客户端解压缩。
可以参考的值为:gzip,compress,deflate和identity。
传输内容格式:Content-Type
内容格式,即接收的数据最终是以何种的形式显示在浏览器中。可以是一个图片,还是一段文本,或者是一段html。内容格式额外支持可选参数,charset,即实际内容的字符集。通过字符集,客户端可以对数据进行解编码,以最终显示可以看得懂的文字(而不是一段byte[]或者是乱码)。

3种描述信息,可以由下图来表示(来源于《Http权威指南》):

从上文中,可以看出,实际上原filter中的内容可能是想表达以下的意思:

response.setContentType("text/html;charset=UTF8");
//或者
response.setContentType("application/json;charset=UTF8");

继续阅读“transfer-encoding和content-length的不同实现”