apisix作为中间代理层,通过ext-plugin-post-resp扩展使用Java插件,代理转发客户端请求到上游服务。其中客户端发起HTTP请求头中包含Expect属性,后端服务在接收到Expect属性时,分别响应HTTP/1.1 100 Continue回应支持,或者HTTP/1.1 417 Expectation Failed。当Response包含了响应头信息(例如Server属性)后apisix会出现failed to request: couldn't parse HTTP version from response status line:的错误,客户端收到502的请求响应。
就如上业务场景,参考RFC2616规范内容:
在RFC2616规范中
4.4 Message Length内容如下:
1.Any response message which "MUST NOT" include a message-body (such
as the 1xx, 204, and 304 responses and any response to a HEAD
request) is always terminated by the first empty line after the
header fields, regardless of the entity-header fields present in
the message.
6 Response内容如下:
After receiving and interpreting a request message, a server responds
with an HTTP response message.
Response = Status-Line ; Section 6.1
*(( general-header ; Section 4.5
| response-header ; Section 6.2
| entity-header ) CRLF) ; Section 7.1
CRLF
[ message-body ] ; Section 7.2
local function _handle_continue(sock, body)
-- _receive_status 方法中会读取1行数据。即:HTTP/1.1 100 Continue
local status, version, reason, err = _receive_status(sock) --luacheck: no unused
if not status then
return nil, nil, err
end
-- Only send body if we receive a 100 Continue
if status == 100 then
-- 当响应包含Header信息时会被读取到,后续的解析就会因此出错
local ok, err = sock:receive("*l") -- Read carriage return
if not ok then
return nil, nil, err
end
_send_body(sock, body)
end
return status, version, err
end
建议代码如下:
local function _handle_continue(sock, body)
local status, version, reason, err = _receive_status(sock) --luacheck: no unused
if not status then
return nil, nil, err
end
-- Only send body if we receive a 100 Continue
if status == 100 then
-- 读取到空行后再做后续处理
repeat
local ok, err = sock:receive("*l") -- Read carriage return
if not ok then
return nil, nil, err
end
until (ok and #ok == 0)
_send_body(sock, body)
end
return status, version, err
end
Issue description
apisix作为中间代理层,通过ext-plugin-post-resp扩展使用Java插件,代理转发客户端请求到上游服务。其中客户端发起HTTP请求头中包含Expect属性,后端服务在接收到Expect属性时,分别响应
HTTP/1.1 100 Continue
回应支持,或者HTTP/1.1 417 Expectation Failed
。当Response包含了响应头信息(例如Server属性)后apisix会出现failed to request: couldn't parse HTTP version from response status line:
的错误,客户端收到502的请求响应。就如上业务场景,参考RFC2616规范内容:
在RFC2616规范中
4.4 Message Length
内容如下:6 Response
内容如下:结论:在请求头包含
Expect
时,响应码100允许返回general-header
和response-header
信息。ext-plugin-post-resp 插件实现依赖http.lua代码如下:
建议代码如下:
Environment
Minimal test code / Steps to reproduce the issue
HTTP/1.1 100 Continue
What's the actual result? (including assertion message & call stack if applicable)
当出现类似Undertow带有Content-Length的属性响应时,apisix解析报头时会报错
What's the expected result?
正常处理并返回客户端200