我怎样才能让 Jetty 得到 return 一个错误响应而不是假设一个 HTTP/0.9 请求?

How can I get Jetty to return an error response instead of assuming an HTTP/0.9 request?

一个损坏的 HTTP 客户端向我们的 Jetty-based HTTP 服务器发送了一些请求,在 URL 中有一个换行符。 Jetty 将此视为 HTTP/0.9 请求,在换行符处截断 URL,忽略请求 headers,并发回没有 headers 或状态行的响应。

根据 spec, although Jetty doesn't require CRLF and will happily do this for requests other than GET. But newer specs 我相信这大部分是正确的,请注意 HTTP/0.9 请求主要表示混淆的客户。在我们的例子中,如果发送错误消息,客户(和我们)本可以避免一些混乱的故障排除。

如何让 Jetty return 对 URL 中带有换行符的请求做出错误响应?我很乐意使用 Jetty-level 配置或 webapp-level 代码。

第一,support for HTTP/0.9 has been completely removed in Jetty 9.3+.

让我们看看行为是什么...

Jetty Distribution 9.2.7.v20150116,运行 demo-base:

正常HTTP/1.0 请求:

$ printf "GET / HTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Server: Jetty(9.2.7.v20150116)

<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">

在那里得到了 headers,看起来也像 HTTP/1.0 响应 headers。

正常HTTP/1.1 请求:

$ printf "GET / HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n" | nc localhost 8080
HTTP/1.1 200 OK
Set-Cookie: visited=yes
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Accept-Ranges: bytes
Content-Type: text/html
Last-Modified: Sat, 17 Jan 2015 00:25:03 GMT
Content-Length: 2773
Connection: close
Server: Jetty(9.2.7.v20150116)

<html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">

看起来也很正常。 甚至包括 HTTP/1.1 具体 headers.

现在让我们尝试使用嵌入式 CRLF HTTP/1.0:

 $ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
 <html xmlns=\ "http://www.w3.org/1999/xhtml\" xml:lang=\"en\">

无响应headers。

为什么会这样?

好吧,Jetty 无法确定 HTTP 版本,因此没有有效的 headers 集可以响应。所以它没有响应 headers。令人惊讶的是 1.0 之前的 HTTP 规范是如何表现的。

现在让我们试试 Jetty Distribution 9。3.x,以及具有相同 CRLF 问题的 demo-base 配置。

$ printf "GET /\r\nHTTP/1.0\r\n\r\n" | nc localhost 8080
HTTP/1.1 400 HTTP/0.9 not supported
Content-Length: 0
Connection: close
Server: Jetty(9.3.0-SNAPSHOT)

现在,在现代,HTTP/2 指日可待,这更有意义。

HttpServletRequest#getProtocol() 将为 Jetty 8 中的 HTTP/0.9 请求 return 空字符串。因此,一个简单的过滤器可以 return 对此类请求的 Bad Request 响应。

所示,HTTP/0.9 请求在最新版本的 Jetty 9 中不再受支持。