返回1xx状态代码时,Spring引导请求挂起

时间:2017-09-18 15:29:30

标签: java spring-boot kotlin http-status-codes

我有一个小型演示可以使用自定义状态代码。

有趣的是,如果状态低于200,请求将始终挂起,如105,199等。但适用于任何大于200的状态,如209,789等。

Http状态代码注册表,请参阅https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

  

Spring boot:1.5.4.RELEASE with embedded tomcat

     

Java:8

控制器:

@RestController
public class DemoController {

    @GetMapping("/hello")
    public ResponseEntity get() {
        return ResponseEntity.status(105).build();
    }
}

有人能给我一个明确的解释吗?

我在这里创建了一个要点:https://gist.github.com/pengisgood/dbea1fcdc45c2bb5809871c7f020b800

更新

我还创建了一个小型演示来重现它: https://github.com/pengisgood/springboot-customize-status-code

更新:

运行curl -v localhost:8080/hello后,我可以看到状态,但响应无法完成。请参阅下面的gif:

curl result

2 个答案:

答案 0 :(得分:0)

据我所知,Spring DispacherServlet以完全相同的方式处理不同的返回码。我认为正在发生的事情就是打开连接,因为响应处于1xx范围内。

This article提供了有关状态代码的良好入门读物。这句话特别相关:

  

100-199 100s中的代码是信息性的,表明客户应该采取其他一些行动。

如果您使用curl运行--trace,您会看到105响应确实到达了:

curl -v -trace http://localhost:8080/hello                                                                                                                                                                                                                                                                                                 
Trying ::1...
TCP_NODELAY set
Connected to localhost (::1) port 8080 (#0)
> GET /hello HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
> 
< HTTP/1.1 105 
< Date: Tue, 19 Sep 2017 18:07:04 GMT
^C

所以我认为正在发生的是返回响应,客户端应该采取其他一些行动(但不会),所以看起来事情已经挂起了。

这里真正的问题可能是你为什么试图返回105状态,你期望发生什么?

答案 1 :(得分:0)

我也遇到了这个问题,发现不是Spring造成这种现象。是Tomcat。

curl -v --header "Expect: 100-continue" http://localhost:8080

像这样调用任何已配置的端点将返回一个额外的响应代码,该代码不会终止请求。

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                             Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   
Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.56.1
> Accept: */*
> Expect: 100-continue
>
< HTTP/1.1 100
< HTTP/1.1 200
< Set-Cookie: JSESSIONID=9355141A10CF546E9A9A43F5A5C0B1A4; Path=/; HttpOnly
< Content-Type: text/html;charset=ISO-8859-1
< Content-Length: 58
< Date: Tue, 31 Jul 2018 17:27:52 GMT
<
{ [58 bytes data]
100    58  100    58    0     0     58      0  0:00:01 --:--:--  0:00:01    82<html>
<body>
<h2>Hello Heroku!</h2>
</body>
</html>

* Connection #0 to host localhost left intact

请注意HTTP/1.1 100

此响应来自该项目https://devcenter.heroku.com/articles/create-a-java-web-application-using-embedded-tomcat,该项目没有Spring。如果我将HelloServlet修改为包含100的响应代码,它将挂起。

深入探讨: https://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3

该规范明确指出应该在同一请求中发生100响应。之所以挂起,是因为它希望客户端以请求的内容作为响应。

在Wiki上查找其他1XX响应代码,似乎确实是在不关闭请求的情况下返回了某些信息。我的猜测是,Tomcat希望所有1xx响应代码都以这种方式起作用。