JRE HttpServer 是否违反了“期望继续”规则? HTTP 的语义?
这是我在使用 com.sun.net.httpserver 中内置的 Java 时遇到的一些问题的后续帖子。 HttpServer
和多步身份验证方案。
有人暗示,发送较大的数据量会使 Java 客户端无法提前接收“需要授权”消息(由于 Java 阻塞 I/O)。
这就是 HTTP 定义涉及 100 个状态代码的“期望继续握手”的原因 ( RFC 2616):
100(继续)状态的目的是允许客户端 发送带有请求正文的请求消息以确定是否 源服务器愿意接受请求(基于请求 headers)在客户端发送请求正文之前。在某些情况下,它 对于客户来说可能不合适或效率极低 如果服务器不查看就拒绝消息,则发送正文 身体。
所以在这种情况下不适合发送数据。服务器...
必须响应 100(继续)状态并继续阅读 来自输入流,或使用最终状态代码进行响应。
不幸的是,Sun HttpServer
总是以 100 状态代码响应,而不涉及应用程序。查看源:
/* check if client sent an Expect 100 Continue.
* In that case, need to send an interim response.
* In future API may be modified to allow app to
* be involved in this process.
*/
String exp = headers.getFirst("Expect");
if (exp != null && exp.equalsIgnoreCase ("100-continue")) {
logReply (100, requestLine, null);
sendReply (
Code.HTTP_CONTINUE, false, null
);
}
当应用程序不涉及,似乎无法向客户端传达不适合发送消息的信息,因此违反了协议(这确实导致了早期关闭连接和损坏管道等问题)。以防万一我遗漏了什么,我最好询问社区这种解释是否正确:)
This is a follow up post to some problems I've had using Java built in com.sun.net.httpserver.HttpServer
and an multistep authentication scheme.
I was hinted at, that sending larger data amounts make it impossible for Java clients to receive early "Authorization required"-messages (due to Java blocking I/O).
Thats the reason why HTTP defines the "expect-continue handshake" involving 100 status code (RFC 2616):
The purpose of the 100 (Continue) status is to allow a client that is
sending a request message with a request body to determine if the
origin server is willing to accept the request (based on the request
headers) before the client sends the request body. In some cases, it
might either be inappropriate or highly inefficient for the client to
send the body if the server will reject the message without looking at
the body.
So in this case it is not appropriate to send the data. The server...
MUST either respond with 100 (Continue) status and continue to read
from the input stream, or respond with a final status code.
Unfortunately the Sun HttpServer
always responds with a 100 status code without involving the application. Looking at the source:
/* check if client sent an Expect 100 Continue.
* In that case, need to send an interim response.
* In future API may be modified to allow app to
* be involved in this process.
*/
String exp = headers.getFirst("Expect");
if (exp != null && exp.equalsIgnoreCase ("100-continue")) {
logReply (100, requestLine, null);
sendReply (
Code.HTTP_CONTINUE, false, null
);
}
When the application is not involved, its seems to be not possible to communicate the client that it is inappropriate to send its message thus the protocol is violated (which really leads to problems like early closed connections and broken pipes). Just in case I'm missing something, I better ask the community if this interpretation is right :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不会说它违反了协议,因为服务器和应用程序之间的通信不是协议的一部分,只是服务器和客户端之间的通信。只要服务器在发送 100-Continue 后接受整个客户端请求,就会遵守该协议。
当然,自动返回 100-Continue 意味着您失去了 Expect-Continue 旨在提供的潜在效率增益,但效率并不是协议所保证的。
I wouldn't say it is violating the protocol, because communicating between the server and the application is not part of the protocol, only communicating between the server and the client. As long as the server accepts the entire client request after sending a 100-Continue, the protocol is respected.
Of course, automatically returning the 100-Continue means you lose the potential efficiency gain that Expect-Continue is intended to provide, but efficiency is not what the protocol guarantees.