今天在Server发现一个错误日志:
写道
ParseException#Not a valid protocol version: ""HTTP/1.1 201 Created#org.apache.http.ParseException: Not a valid protocol version: ""HTTP/1.1 201 Created
org.apache.http.message.BasicLineParser.parseProtocolVersion(BasicLineParser.java:147)
org.apache.http.message.BasicLineParser.parseStatusLine(BasicLineParser.java:365)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:114)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:51)
org.apache.http.message.BasicLineParser.parseProtocolVersion(BasicLineParser.java:147)
org.apache.http.message.BasicLineParser.parseStatusLine(BasicLineParser.java:365)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:114)
org.apache.http.impl.nio.codecs.DefaultHttpResponseParser.createMessage(DefaultHttpResponseParser.java:51)
找到对应的代码:
public ProtocolVersion parseProtocolVersion(final CharArrayBuffer buffer, final ParserCursor cursor) throws ParseException { Args.notNull(buffer, "Char array buffer"); Args.notNull(cursor, "Parser cursor"); final String protoname = this.protocol.getProtocol(); final int protolength = protoname.length(); final int indexFrom = cursor.getPos(); final int indexTo = cursor.getUpperBound(); skipWhitespace(buffer, cursor); int i = cursor.getPos(); // long enough for "HTTP/1.1"? if (i + protolength + 4 > indexTo) { throw new ParseException ("Not a valid protocol version: " + buffer.substring(indexFrom, indexTo)); } // check the protocol name and slash boolean ok = true; for (int j=0; ok && (j<protolength); j++) { ok = (buffer.charAt(i+j) == protoname.charAt(j)); } if (ok) { ok = (buffer.charAt(i+protolength) == '/'); } if (!ok) { throw new ParseException ("Not a valid protocol version: " + buffer.substring(indexFrom, indexTo)); }
说明协议栈在读取buffer.substring(indexFrom, indexTo)的时候读到的是""HTTP/1.1 201 Created,前面有两个双引号。抓包发现,在同一个长连接上出现这种情况:
写道
GET /check HTTP/1.1
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 204 OK
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
""Get /creat HTTP/1.1
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 201 Created
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
...
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 204 OK
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
""Get /creat HTTP/1.1
Host: abc.com
Connection: keep-alive
Cache-Control: max-age=0
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8,en;q=0.6
HTTP/1.1 201 Created
Date: Sat, 12 Nov 2016 04:41:29 GMT
Content-Length: 2
...
大家注意我标红的这个应答,返回的是204,却标明了Content-Length: 2,这个应答是不符合HTTP协议定义的:
https://tools.ietf.org/html/rfc7230#section-3.3.1
3.3.3. Message Body Length
The length of a message body is determined by one of the following (in order of precedence): 1. Any response to a HEAD request and any response with a 1xx (Informational), 204 (No Content), or 304 (Not Modified) status code is always terminated by the first empty line after the header fields, regardless of the header fields present in the message, and thus cannot contain a message body.
问题定位:
在一条长连接上返回的两个应答中,第一个应答返回的应答码是204,却在body中带了两个引号,违反了HTTP1.1的规范,导致遵守了该规范的Apache的读取第一个应答的线程没有从流中读出最后两个引号,而读取第二个应答的时候发现前两个字节是两个双引号,不是HTTP/1.1,直接抛出异常。
结论,204的应答一定要遵守规范,不能再body中写数据,否则会污染流中的数据,影响长连接上对下个数据包的读取。
相关推荐
### SOCK-HTTP代理协议解析 #### 一、引言 随着互联网技术的不断发展与网络环境的日益复杂化,为了确保网络安全、控制访问权限以及优化网络性能,越来越多的企业和个人选择使用代理服务。代理服务通过中间服务器...
Java版的DLT645-2007电能表协议解析源码是用于处理电能表通信的一种软件开发资源,尤其适用于那些需要通过串行接口与电能表进行数据交互的应用。这个协议是中国电力行业的一个标准,规定了电能表与数据采集系统之间...
2. 错误处理:当接收到的帧格式不正确或者校验失败时,需要有适当的错误处理机制。 3. 命令与应答:解析出命令代码并执行相应的操作,同时能够生成正确的应答帧。 4. 多线程或异步处理:在多设备通信环境下,可能...
SIP 协议应答码是其通信过程中用来指示请求处理状态的关键部分,它沿袭并扩展了 HTTP/1.1 的应答码体系,同时也新增了一些特有的应答码。 1. **临时应答 (1xx)** - 1xx 应答码表示服务器正在处理请求,但尚未做出...
为了保证通信的安全性,协议还包含了错误检测和重传机制,如CRC校验用于检查数据传输错误,而应答机制则确保命令的正确执行。此外,通过加密技术,可以防止数据被非法窃取和篡改。 总结,DL/T645-2007电表通信协议...
"HART协议解析" HART(Highway Addressable Remote Transducer)协议是一种工业自动化领域中的通讯协议,主要应用于过程控制和工业自动化系统中。HART协议规定了传输的物理形式、消息结构、数据格式和一系列操作...
HTTP协议作为互联网上应用最为广泛的一种网络协议,其核心功能在于规范客户端与服务器间的数据交互过程。在这一过程中,HTTP应答码扮演着至关重要的角色,它不仅告知客户端请求的状态,还帮助开发者快速定位问题所在...
在实际操作中,"国南网报文解析工具-698.exe"是实现698协议解析的关键软件,它能有效地解析出698协议中的各种数据包,包括命令、应答、事件记录等,使得工作人员无需深入理解底层通信细节,也能快速定位问题和分析...
本资源内,包含原创代码如下: 1、Command_0x02.java 运行主类mian()方法类 ...以上通过JAVA实现报文协议解析的原创代码,即十六进制报文解析的示例代码。【注:可关注本作者关于报文解析,该系列的示例源码和文章】
1.介绍 2.现有的协议 3.基于TCP协议的客户 4.请求 5.地址 6.应答 7.基于UDP协议的客户 8. 安全性考虑 9. 参考书目
HTTP(Hypertext Transfer Protocol)协议是互联网上应用最广泛的一种网络协议,它定义了客户端(通常是Web浏览器)和服务器之间交互数据的格式和规则。HTTP协议基于客户/服务器模式,设计简洁快速,允许传输各种...
**BACnet_IP协议解析** BACnet(楼宇自动化控制网络)是一种标准的通信协议,专为楼宇自动化系统设计,用于设备之间的数据交换。BACnet_IP是BACnet协议的一种实现,它允许BACnet设备通过IP网络进行通信。本篇文章将...
技术规范书及应答是用于数字化监控系统设备与管理平台项目的技术应答规,投标单位应逐条的、点对点的答复〔满足/局部满足/不能满足〕,可对不满足或局部满足项和进展详细补充说明,对应答汇总成《技术应答偏离表》。...
智能卡复位应答(ATR)是智能卡与读卡器进行通信时的第一步,它是卡片在初始化过程中的响应信号。ATR全称为Answer To Reset,它包含了卡片的重要信息,如卡片类型、通信参数、卡片状态等。理解ATR对于进行有效的智能...
DHCP 协议解析、每个流程的报文解析 DHCP(Dynamic Host Configuration Protocol)是一种应用层协议,用于让主机自动获取 IP 地址和相关的网络参数。DHCP 协议采用 UDP 作为传输协议,主机发送请求消息到 DHCP ...
**OBDII ISO 15765-4 CAN协议解析与输出** OBD(On-Board Diagnostics)是汽车自诊断系统,用于检测车辆的排放控制和发动机性能。OBDII是其第二代,提供了统一的数据接口和通信协议,方便第三方设备进行车辆状态...
在本项目中,“DNS协议解析源码程序”旨在实现DNS查询和响应的解析功能,这涉及到对DNS报文结构的理解以及C#编程语言的应用。 首先,我们来看DNS协议的基本概念。DNS协议基于UDP(User Datagram Protocol)或TCP...
它于 1990 年提出,经过多年的发展和完善,目前在 WWW 中使用的是 HTTP/1.0 的第六版,HTTP/1.1 的规范化工作正在进行中。 HTTP 协议的主要特点包括: 1. 支持客户 / 服务器模式 2. 简单快速:客户向服务器请求...
总结来说,"jt808netty版解析部分源码"主要展示了如何使用Java和Netty框架来实现JT808协议的解析,涵盖了协议解析、字节操作、消息处理、异常控制等多个方面,是理解网络通信协议解析和Java并发编程的宝贵资源。