2012-02-08 53 views
0

这是一个problems的后续文章我已经使用过内置com.sun.net.httpserver.HttpServer的Java和一个多步认证方案。JRE HttpServer是否违反HTTP的'expect-continue'语义?

我是hinted at,发送更大的数据量使Java客户端无法接收早期的“需要授权”消息(由于Java阻塞I/O)。

这就是为什么HTTP定义了“预计,继续握手”,涉及100状态码(RFC 2616)的原因:

的100(继续)状态的目的是为了让客户端是 发送请求消息与请求主体一起确定在客户端发送请求主体之前,原始服务器是否愿意接受请求(基于请求 标头)。在某些情况下, 可能是不合适的或者对于客户端来说效率非常低,如果服务器拒绝该消息而不注意 正文,则发送主体到 。

所以在这种情况下,发送数据是不合适的。服务器...

务必以100(继续)状态进行响应,并继续从输入流中读取 ,或以最终状态码进行响应。

不幸的是,太阳HttpServer总是以100个状态码响应,而不涉及应用。纵观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 
    ); 
} 

当未涉及的应用,它似乎是不可能的通信的客户端,这是不恰当的,从而发送其消息的协议违反了(这实际上导致的问题,像早期闭合连接和断开的管道)。以防万一我失去了一些东西,我最好问社区,如果这种解释是正确的:)

回答

1

我不会说这是违反协议,因为服务器和应用程序之间的通信不是协议的一部分,只能在服务器和客户端之间进行通信。只要服务器在发送100-Continue后接受整个客户端请求,协议就会受到尊重。

当然,自动返回100-继续意味着您失去了预期 - 继续打算提供的潜在效率增益,但效率不是协议所保证的。

+1

作为这个伟大的答案的附录,我会补充说,太阳HttpServer有一个_very_有限的使用范围。对于任何_real_ web服务器需求,您应该使用像jetty,apache或其他高质量java web服务器的主机。 – jtahlborn 2012-02-08 16:45:07

+0

@jtahlborn这个服务器嵌入的项目是一个学术背景,所以afaik还有其他的考虑使用这个服务器,比如它是Java的一部分。我不得不承认Jetty应该是一个更好的决定,因为几乎没有人会使用sun httpserver来处理任何严重问题。 – mtsz 2012-02-08 17:32:57

+0

@antlersoft感谢您的回答,但服务器在发送100之后不愿意接受请求,因为客户端尚未获得授权。根据http://www8.org/w8-papers/5c-protocols/key/key.html,这是一个满意的用例。在这种情况下,无法通知sun httpserver它应该避免发送continue消息。但是,它不是核心协议,它只是带宽优化的边缘。也许这是不恰当的,称之为违反或不......不管怎么说,这可能不是有趣的...这个问题似乎没有太多朋友:) – mtsz 2012-02-08 18:02:03