LiuYawei2019 opened a new issue, #306:
URL: https://github.com/apache/apisix-java-plugin-runner/issues/306

   ### 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```内容如下:
   ```
   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
   ```
   
结论:在请求头包含```Expect```时,响应码100允许返回```general-header```和```response-header```信息。
   
   ext-plugin-post-resp 插件实现依赖http.lua代码如下:
   ```
   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
   ```
   
   ### Environment
   * apisix V3.2
   * apisix-java-plugin-runner  
   
   ### Minimal test code / Steps to reproduce the issue
   
   1. Postman 通过POST请求接口,Header头中增加Expect: 100-continue属性
   2. Tomcat 容器下返回```HTTP/1.1 100 Continue ```
   3. Undertow 容器下返回(Undertow官方在2.2.21.Final版本修改并去掉了Content-Length的属性)
   ```
   HTTP/1.1 100 Continue
   Content-Length: 0
   ```
   
   ### What's the actual result? (including assertion message & call stack if 
applicable)
   当出现类似Undertow带有Content-Length的属性响应时,apisix解析报头时会报错
   
   ### What's the expected result?
   正常处理并返回客户端200


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to