为什么Jetty JSR356在checkOrigin和modifyHandshake

时间:2015-05-18 11:47:23

标签: java websocket jetty jsr356

我正在玩Jetty( 9.2.3v20140905 ),当我遇到Jetty的代码时,我尝试使用自己的ServerEndpointConfig来连接网络套接字端点看看它是如何使用的。 我注意到在创建Web套接字对象时在JsrCreator中使用它:

Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp){
 ...
 // modify handshake
 configurator.modifyHandshake(config,hsreq,hsresp);
 ...
}

我读了modifyHandshake ServerEndpointConfig javax.websocket-api 1.0 )的javadoc,声明:

  

在容器响应之后由容器调用   一个结构良好的握手请求。容器已经存在   检查此配置有匹配的URI ,确定了   使用 checkOrigin方法进行原点的有效性,并填写   基于此配置的协商子协议和扩展。   自定义配置可能会覆盖此方法以进行检查   请求参数并修改服务器已制定的握手响应。   和URI检查也。   如果开发人员没有覆盖此方法,则不再进一步   请求和响应的修改由实现进行。

以下是Jetty所做的事情:

Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp){
 ...
 // modify handshake
 configurator.modifyHandshake(config,hsreq,hsresp);

 // check origin
 if (!configurator.checkOrigin(req.getOrigin())){...}
 ...
 resp.setAcceptedSubProtocol(subprotocol);
 ...
 resp.setExtensions(configs);
}

如您所见,在调用配置器之后检查原点。在调用配置器>后,响应被修改。 acceptWebSocket的{​​{1}}方法调用了WebSocketCreator:

WebSocketServerFactory

然后打电话:

Object websocketPojo = creator.createWebSocket(sockreq, sockresp);

也会通过private boolean upgrade(HttpConnection http, ServletUpgradeRequest request, ServletUpgradeResponse response, EventDriver driver) 修改回复:

HandshakeRFC6455

所以我无法仅使用我的配置器修改响应,因为Jetty无论如何都会改变它。

在我看来,Jetty不符合JSS 356,WebSocket的Java API,是吗?

1 个答案:

答案 0 :(得分:0)

啊,这是JSR-356规范中许多含糊不清和定义不明确的部分之一。

您可能需要阅读open bugs against the spec

如果原始的1.x规范完全遵循,有许多现实世界的场景示例无法实现。

现在,要解决问题的具体细节:

为什么在Jetty实现中的modifyHandshake之后调用checkOrigin?

这是因为有一些有效的场景(特别是CDI和Spring),最终用户checkOrigin实现所需的信息无效或存在,直到调用modifyHandshake调用

基本上,创建端点Configurator,调用modifyHandshake,此时,所有库集成(CDI,Spring等)都会启动,即端点进入时WebSocket(RFC6455)CONNECTING状态。 (一旦调用端点的onOpen,则WebSocket RFC6455状态进入OPEN状态)

正如您可能已经注意到的那样,当涉及CDI(或Spring)时,对象的范围和生命周期的规范中没有定义。

1.x JSR356规范实际上与servlet容器特定行为保持距离,这样做是为了使规范尽可能通用,并且能够拥有非servlet websocket服务器容器。不幸的是,这也意味着servlet容器中有许多用例没有与1.x JSR356规范相匹配。

更新JSR356规范以在WebSocket上正确定义CDI范围后,可以修复checkOrigin之后modifyHandshake的这个怪癖。

为什么在modifyHandshake后修改响应的实现?

实现必须修改响应,否则响应对于HTTP / 1.1升级无效,实现需要与端点及其配置合作,子协议和扩展使这成为现实。 (请注意,JSR356规范在Extensions上播放?)

这也是一个承诺在下一个JSR356版本中得到纠正的领域。

目前关于WebSocket over HTTP / 2规范的工作使得这更加有趣,因为它(当前)没有使用HTTP / 1.1升级语义。它只是在握手时出现(没有升级,没有原点等)。