【问题标题】:How can I get Jetty to return an error response instead of assuming an HTTP/0.9 request?如何让 Jetty 返回错误响应而不是假设 HTTP/0.9 请求?
【发布时间】:2015-02-13 17:10:33
【问题描述】:

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

根据spec,我相信这基本上是正确的,尽管 Jetty 不需要 CRLF,并且很乐意为 GET 以外的请求执行此操作。但newer specs 请注意,HTTP/0.9 请求主要表示客户端混淆。在我们的案例中,如果发送了错误消息,客户(和我们)本可以避免一些令人困惑的故障排除。

如何让 Jetty 对 URL 中带有换行符的请求返回错误响应?我很乐意使用 Jetty 级别的配置或 webapp 级别的代码。

【问题讨论】:

    标签: java servlets jetty embedded-jetty


    【解决方案1】:

    首先,support for HTTP/0.9 has been completely removed in Jetty 9.3+

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

    Jetty Distribution 9.2.7.v20150116,运行演示库:

    普通 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\">
    

    那里有标头,看起来也像 HTTP/1.0 响应标头。

    普通 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 特定的标头。

    现在让我们试试嵌入 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\">
    

    没有响应头。

    为什么会这样?

    嗯,Jetty 没有可以确定的 HTTP 版本,因此没有可以响应的有效标头集。所以它响应没有标题。令人惊讶的是 1.0 之前的 HTTP 规范的行为方式。

    现在让我们试试 Jetty Distribution 9.3.x,以及具有相同 CRLF 问题的演示基础配置。

    $ 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 指日可待的现代时代,这更有意义。

    【讨论】:

    • 我们在 Jetty 8 上停留的时间更长了。有什么方法可以在那里获得类似的行为?
    • Jetty 8 现在是 EOL(生命终结)。修复方法是让解析器不执行任何 HTTP/0.9 工作,返回响应标头中不受支持的内容。不幸的是,因为这个过程太早了,所以没有可能的解决方法(除了可能的自定义 HTTP 解析器)
    • HttpServletRequest 是否有任何我可以查看的功能可能表明 Jetty 在 HTTP/0.9 上已对其进行了解释?
    • Jetty 9 中的原始 Jetty org.eclipse.jetty.server.Request 可以访问.getHttpVersion(),但不能访问 Jetty 8。抱歉。
    【解决方案2】:

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

    正如the other answer 所指出的,最新版本的 Jetty 9 不再支持 HTTP/0.9 请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-18
      • 1970-01-01
      • 2021-05-21
      • 2014-06-03
      • 2016-09-09
      • 1970-01-01
      • 2017-02-17
      相关资源
      最近更新 更多