isReady() returns 在关闭状态下为真 - 为什么?
isReady() returns true in closed state - why?
ServletOutputStream.isReady()
javadoc says the following:
Returns:
true if a write to this ServletOutputStream will succeed, otherwise returns false.
尽管 Jetty 的 ServletOutputStream
实现,HttpOutput
在流处于 CLOSED
状态的情况下似乎表现得相当混乱。它returns true
:
case CLOSED:
return true;
此外,HttpOutput
中的所有三个 write
方法在 CLOSED
:
时抛出 EofException
case CLOSED:
throw new EofException("Closed");
这么看来write永远不可能成功。这种行为背后的原因是什么?
关键事实:关闭调用意味着写入操作。
CLOSED 内部状态表示 stream/output 的 usage 已关闭到该调度(不是流本身实际上已关闭)。
我们是如何进入这种状态的?某些东西触发了 ServletOutputStream.close()
(进而 HttpOutput.close()
),现在从当前分派开始不再允许对该流进行写入。
在CLOSED状态下,发生flush。
- 刷新将提交响应
- 刷新将完成对交换/连接/输出各个层上存在的各种缓冲区的写入。
- 如果有一个聚合缓冲区(对于许多小的写入)它会写出来。
- 如果有压缩层 (gzip),它也会强制从那里进行刷新。
- 然后所有这些缓冲区也通过
Transfer-Encoding
层(例如:分块)。
- 然后发生网络写入。
HttpOutput
也是所有嵌套请求的一个输出点,比如using include()
from RequestDispatcher
会重新打开HttpOutput
以供在include()
然后再次关闭它。
一旦 HttpOutput
完全 flushed/finished(不再发送,不再写入等),最后的缓冲区刷新完成,传输编码完成,HttpOutput 是重置、回收并返回到 HttpConnection 以供下一次交换使用。
我们可以在代码库中更好地编写 javadoc,或者至少使用更有意义的常量和变量名。
已打开https://github.com/eclipse/jetty.project/issues/2687
关于写 Jetty EofException
(不是 JVM EOFException
)。
一旦 ServletOutputStream
关闭以用于特定调度,进一步调用 write()
将导致 Jetty EofException
.
还有一种情况是 EofException
违反了您提交的响应详细信息。
例如:您声明了一个响应 Content-Length
,比如 40MB,但写入了 41MB,您超出了该已提交响应的能力,这是一个 IOException。在这种情况下,Servlet 规范告诉我们抛出一个 IOException
。
Jetty 将抛出 Jetty 内部 EofException
(它扩展了 IOException)以指示这种特定情况并中止连接,从而破坏您可能想要的任何连接持久性。
ServletOutputStream.isReady()
javadoc says the following:
Returns: true if a write to this ServletOutputStream will succeed, otherwise returns false.
尽管 Jetty 的 ServletOutputStream
实现,HttpOutput
在流处于 CLOSED
状态的情况下似乎表现得相当混乱。它returns true
:
case CLOSED:
return true;
此外,HttpOutput
中的所有三个 write
方法在 CLOSED
:
EofException
case CLOSED:
throw new EofException("Closed");
这么看来write永远不可能成功。这种行为背后的原因是什么?
关键事实:关闭调用意味着写入操作。
CLOSED 内部状态表示 stream/output 的 usage 已关闭到该调度(不是流本身实际上已关闭)。
我们是如何进入这种状态的?某些东西触发了 ServletOutputStream.close()
(进而 HttpOutput.close()
),现在从当前分派开始不再允许对该流进行写入。
在CLOSED状态下,发生flush。
- 刷新将提交响应
- 刷新将完成对交换/连接/输出各个层上存在的各种缓冲区的写入。
- 如果有一个聚合缓冲区(对于许多小的写入)它会写出来。
- 如果有压缩层 (gzip),它也会强制从那里进行刷新。
- 然后所有这些缓冲区也通过
Transfer-Encoding
层(例如:分块)。 - 然后发生网络写入。
HttpOutput
也是所有嵌套请求的一个输出点,比如using include()
from RequestDispatcher
会重新打开HttpOutput
以供在include()
然后再次关闭它。
一旦 HttpOutput
完全 flushed/finished(不再发送,不再写入等),最后的缓冲区刷新完成,传输编码完成,HttpOutput 是重置、回收并返回到 HttpConnection 以供下一次交换使用。
我们可以在代码库中更好地编写 javadoc,或者至少使用更有意义的常量和变量名。
已打开https://github.com/eclipse/jetty.project/issues/2687
关于写 Jetty EofException
(不是 JVM EOFException
)。
一旦 ServletOutputStream
关闭以用于特定调度,进一步调用 write()
将导致 Jetty EofException
.
还有一种情况是 EofException
违反了您提交的响应详细信息。
例如:您声明了一个响应 Content-Length
,比如 40MB,但写入了 41MB,您超出了该已提交响应的能力,这是一个 IOException。在这种情况下,Servlet 规范告诉我们抛出一个 IOException
。
Jetty 将抛出 Jetty 内部 EofException
(它扩展了 IOException)以指示这种特定情况并中止连接,从而破坏您可能想要的任何连接持久性。