`
desert3
  • 浏览: 2156103 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

HTTP Chunk分块&java.io.IOException: CRLF&missing CR

 
阅读更多
总结:
HTTP 1.1时,Response要嘛通过Content-Length来指定要传输的内容大小,要嘛通过Transfer-Encoding: chunked来传输动态大小的内容,此时要求Response传输的内容要符合chunk encoding的规定。
从抓包的角度来说,两个请求如果HTTP 参数(Head和Body)都相同的话,是等价的,不管请求是从浏览器还是Java代码发出来的。

CRLF -- Carriage-Return Line-Feed回车换行 回车(CR, ASCII 13, \r) 换行(LF, ASCII 10, \n)。
carriage ['kæridʒ] n. 运输;运费;四轮马车;举止;客车厢

HTTP1.1默认支持长连接(持久连接),长连接避免为每个请求都创建各自的连接,而是多个请求使用一个已经建立好的连接。如果每个HTTP请求都进行set up和tear down,这对于性能损失是非常严重的。
在长连接中,每次传输的长度必须都被计算的非常精确。如果在http头中以Content-Length来标记请求request或者响应response的大小,客户端或者服务器就只会从流中读取Content-Length指定大小的字节,然后表明本次传输结束。使得下一次客户端请求以及服务器端响应继续使用这个相同的socket连接成为可能。

在交互式应用程序中有1个问题,就是它并不知道将要传输的数据有多大。
在HTTP1.0中,服务器就会省略response头中的Content-Length而持续写数据出去,当服务器挂了的话,它简单地断开连接。而经典的HTTP客户端会一直读数据直到碰到-1(传输结束的标识符)。
为了处理这个问题,HTTP1.1中增加了一个特殊的header:Transfer-Encoding:chunked,允许响应response被分块chunked。每次向连接写数据的时候会先计算大小,最后在response的尾部以一个0长度的chunk块标志着此次传输的结束。即HTTP1.1支持chunked编码,它允许HTTP消息被分成多块后再进行传输。Chunking一般用在服务器响应response的时候,但是客户端也可以chunk大的请求request。即Chunk编码允许服务器在发送完Header后,发送更多的Body内容。

Chunked编码使用若干个Chunk块串连而成,每个Chunk块都以一个表明chunk快大小的16进制数字和一个额外的CRLF(回车换行)开始,后面跟着指定大小的内容。即每个Chunk块分为头部和正文两部分,头部内容指定下一段正文的字符总数(十六进制的数字)和数量单位(一般不写),正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。最后以一个长度为0的Chunk表明本次传输结束 。
1个典型的Chunk传输例子:
C\r\n
Some data...
11\r\n
Some more data...
0\r\n

上述消息内容包含2个chunk块,第一个块是12字节长度(hex C),第二个块是17字节长度(hex 11)。

Java中减少Chunk数量的一种方法是不要适应flush(),只使用1个write()方法来输出所有内容。如果被输出的内容大小大于output的buffer大小,那么输出还是会被chunk,但是不使用flush()方法还是可以有效地减少不必要的chunking。

在有些情况下,有些客户端或者服务器只能处理老的HTTP1.0的行为。此时,应该使用Connection: close的header来通知接收部分不要使用长连接。
Connection: keep-alive表明可以使用长连接。

参考:HTTP Chunking





相关解决的问题:
Axis2 RPC客户端默认根据Content-Length的大小来读取Response,而相应的Web Service使用chunked encoding的方式来传输,因此报错。通过设置参数来通知服务器不使用Chunk编码来解决。
Axis2 客户端调用时报【Transport error: 411 Error: Length Required】


CRLF、missing CR这2个错误都表明返回的Response内容不正确。
即返回的Response Header头中指定了Transfer-Encoding:chunked,但是传输的Response内容却不符合HTTP 1.1 RFC中对于chunked的规定。
因此在apache http client包通过以下2种不同的方法调用Request后,做解码操作时,在某个读取某个chunk时,读取根据CRLF标识符前面指定的字节数后,紧跟着应该是下一个Chunk,而读下一个Chunk时,发现CRLF前面的字符并不是16进制的数,即返回的Response不符合Chunking中对于分块的规定,所以报错。
java.io.IOException: CRLF expected at end of chunk: 47/109
	at org.apache.commons.httpclient.ChunkedInputStream.readCRLF(ChunkedInputStream.java:207)
	at org.apache.commons.httpclient.ChunkedInputStream.nextChunk(ChunkedInputStream.java:219)
	at org.apache.commons.httpclient.ChunkedInputStream.read(ChunkedInputStream.java:176)
	at java.io.FilterInputStream.read(Unknown Source)
	at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:108)
	at java.io.FilterInputStream.read(Unknown Source)
	at org.apache.commons.httpclient.AutoCloseInputStream.read(AutoCloseInputStream.java:127)
	at org.apache.jmeter.protocol.http.sampler.HTTPSampler2.sample(HTTPSampler2.java:853)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1038)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1022)
	at org.apache.jmeter.threads.JMeterThread.doNormalSample(JMeterThread.java:292)
	at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:351)
	at java.lang.Thread.run(Unknown Source)


java.io.IOException: missing CR
	at sun.net.www.http.ChunkedInputStream.processRaw(Unknown Source)
	at sun.net.www.http.ChunkedInputStream.readAheadNonBlocking(Unknown Source)
	at sun.net.www.http.ChunkedInputStream.readAhead(Unknown Source)
	at sun.net.www.http.ChunkedInputStream.available(Unknown Source)
	at java.io.FilterInputStream.available(Unknown Source)
	at java.io.BufferedInputStream.read(Unknown Source)
	at java.io.FilterInputStream.read(Unknown Source)
	at org.apache.jmeter.protocol.http.sampler.HTTPSampler.readResponse(HTTPSampler.java:260)
	at org.apache.jmeter.protocol.http.sampler.HTTPSampler.sample(HTTPSampler.java:480)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1038)
	at org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase.sample(HTTPSamplerBase.java:1022)
	at org.apache.jmeter.threads.JMeterThread.doNormalSample(JMeterThread.java:292)
	at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:351)
	at java.lang.Thread.run(Unknown Source)
分享到:
评论
1 楼 jss 2012-11-05  
                   

相关推荐

    修正版AXMLPrinter2

    android 二进制xml 解析。AXMLPrinter2反编译的时候报错解决

    AXMLPrinter2错误修正版本

    java.lang.ArrayIndexOutOfBoundsException: 128 at android.content.res.StringBlock.getShort(StringBlock.java:231) at android.content.res.StringBlock.getString(StringBlock.java:91) at android.content....

    chunk.js:在您的网页中下载大量网络资源

    块.js Chunk.js 是一个 javascript 库,它允许您为您的网页分部分下载任何资源。用法并行下载图像数据通过并行打开 3 个连接下载路径 /data/4.jpg 中的图像。 image = new Chunk("/data/4.jpg", 3, each_chunk_...

    javaweb service大文件上传下载 DataHandler.docx

    Java Web Service 大文件上传下载通常涉及到处理大量数据,尤其是对于超过10MB的大文件,直接使用`byte[]`数组存储并不合适,因为这可能导致内存溢出。在这种情况下,可以利用`DataHandler`类和MTOM(Message ...

    六级核心词汇,让你轻松过六级

    14. chunk(堆):大块或一堆,常用于描述物质的堆积。 15. oncoming(接近的):即将到来的,常用于描述车辆或事件。 16. deform(变形):形状或结构的改变,可能是由于外力或自然过程。 17. distract(分散注意力...

    http.client.IncompleteRead: IncompleteRead(0 bytes read)

    1. `requests` 库中的 `urllib3` 模块的 `response.py` 文件中,`_update_chunk_length` 函数尝试将接收到的行解析为十六进制的块大小,但遇到了一个空字符串(`b''`),这意味着无法转换为整数,于是抛出了 `...

    chunk 有关代码

    import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Iterator; import org.apache.commons.httpclient.ChunkedInputStream; import org....

    jQuery.extend和jQuery.fn.extend的区别

    在JavaScript的世界里,jQuery是一个非常流行的库,它简化了DOM操作、事件处理、动画效果以及Ajax交互等任务。在jQuery的API中,`jQuery.extend`和`jQuery.fn.extend`是两个重要的方法,它们用于合并对象属性,但...

    本科毕业设计:众筹系统的设计与实现 Vue.js+SpringBoot框架 前后端分离 可以用于毕业设计,可运行

    开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven包:Maven3.3.9 浏览器:谷歌浏览器 Java...

    PHP 仿陌陌直播

    red5 java java用的较多,性能还是不错的! crtmpserver c++ 支持多种rtmp协议,移动设备以及IPTV相关网络协议 http://www.rtmpd.com/ Erlyvideo erlong 有开源和商业版本 https//github.com/erlyvideo/erlyvideo h...

    requests-0.8.4.tar.gz

    8. **分块下载**:大文件下载时,requests库支持流式响应,可实现分块下载: ```python with open('filename', 'wb') as f: for chunk in response.iter_content(1024): f.write(chunk) ``` 9. **错误处理**:...

    python request库

    9. **分块读取大文件**:对于大文件下载,可以使用迭代器分块读取响应内容,避免一次性加载到内存中: ```python with open('file', 'wb') as f: for chunk in response.iter_content(1024): f.write(chunk) ``...

    java 使用socked接收chunck分块数据

    import java.io.*; import java.net.Socket; public class ChunkedReader { private Socket socket; private BufferedReader reader; private ByteArrayOutputStream outputStream; public ChunkedReader...

    把文本文件转化为pdf文件,需要iText.jar和iTextAsian.jar这两个包JAVA.zip

    在Java编程环境中,将文本文件转换为PDF文件是一项常见的任务,尤其在生成报告、文档或电子书籍时。这里的关键依赖是iText库,一个强大的开源Java库,专门用于处理PDF文档。iText.jar是核心库,支持基本的PDF操作,...

    Netty实现大文件分块传输详解.pdf

    ### Netty实现大文件分块传输详解 #### 前言 在现代互联网应用中,高效、稳定地传输大量数据是十分重要的。特别是在文件传输场景下,如何有效地处理大文件的传输成为了一个技术挑战。传统的文件传输方式往往一次性...

    python requests 包

    for chunk in response.iter_content(1024): f.write(chunk) ``` ### 6. 自定义请求头 可以通过 `headers` 参数设置自定义请求头: ```python headers = {'User-Agent': 'My User Agent'} response = requests....

    通过NodeJS中的http.get() 和 http.request()模块两种方法,调用中国天气api

    在NodeJS中,HTTP模块是核心模块之一,用于创建服务器以及发起HTTP请求。在这个场景下,我们将探讨如何使用`http.get()`和`http.request()`来调用中国天气API,获取实时天气信息。这两个方法都是NodeJS HTTP模块的一...

    apktool documentation

    apks are nothing more than a zip file containing resources and compiled java. If you were to simply unzip an apk like so, you would be left with files such as classes.dex and resources.arsc. $ unzip...

    大文件上传的java例子(webuploader包括前台和后台代码)

    import java.io.*; public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Part ...

    requests-2.28.2.tar.gz

    1. 分块读取大文件:`response.iter_content(chunk_size)`可分块下载大文件,避免内存溢出。 2. 代理设置:`proxies`参数可以配置HTTP或HTTPS代理。 3. 超时设置:`timeout`参数控制请求超时时间。 4. 自定义认证:`...

Global site tag (gtag.js) - Google Analytics