关键事实:close call 意味着写入操作。
CLOSED 内部状态表明流/输出的使用对于该调度是关闭的(而不是流本身实际上是关闭的)。
我们是如何进入这种状态的?某些事情触发了ServletOutputStream.close()
(反过来HttpOutput.close()
),现在不允许从当前调度对该流进行更多的写入。
在 CLOSED 状态下,会发生刷新。
- 刷新将提交响应
- 刷新将完成写入交换/连接/输出的各个层上存在的各种缓冲区。
- 如果有一个聚合缓冲区(对于许多小写入),它会将其写出。
- 如果有压缩层(gzip),它也会从那里强制刷新。
- 然后所有这些缓冲区也通过
Transfer-Encoding
层(例如:分块)。
- 然后发生网络写入。
HttpOutput
也是所有嵌套请求的一个输出点,比如 using from include()
whichRequestDispatcher
会HttpOutput
在 the 期间重新打开供使用include()
,然后再次关闭。
一旦HttpOutput
完全和完全刷新/完成(不再调度,不再写入等),则完成最终缓冲区刷新,完成传输编码,重置 HttpOutput,回收,并返回到 HttpConnection 以供使用下一次交流。
我们可以在代码库中更好地处理 javadoc,或者至少使用更有意义的常量和变量名。
打开https://github.com/eclipse/jetty.project/issues/2687
关于写的 Jetty EofException
(不是 JVM EOFException
)。
一旦ServletOutputStream
CLOSED 用于特定调度,进一步调用write()
将导致 Jetty EofException
。
还有一种EofException
你的承诺响应细节被违反的地方。
例如:您声明了一个Content-Length
40MB 的响应,但写入了 41MB,您超出了该提交响应的能力,这是一个 IOException。Servlet 规范告诉我们IOException
在这种情况下抛出一个。
Jetty 将抛出 Jetty 内部EofException
(扩展 IOException)以指示此特定场景并中止连接,从而破坏您可能想要的任何连接持久性。