首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Jetty JSR356在checkOrigin和modifyHandshake方面表现不同

为什么Jetty JSR356在checkOrigin和modifyHandshake方面表现不同
EN

Stack Overflow用户
提问于 2015-05-18 11:47:23
回答 1查看 273关注 0票数 1

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

代码语言:javascript
复制
Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp){
 ...
 // modify handshake
 configurator.modifyHandshake(config,hsreq,hsresp);
 ...
}

我阅读了modifyHandshake of ServerEndpointConfig (javax.webSocket-API1.0)的javadoc,其中声明:

容器在制定了由格式良好的握手请求产生的握手响应后调用。容器已经检查了,该配置是否具有匹配的URI,使用checkOrigin方法确定了原点的有效性,并基于该配置填充了协商过的子协议和扩展。自定义配置可以覆盖此方法,以便检查请求参数,并修改服务器已制定的握手响应。以及URI检查。如果开发人员不覆盖此方法,则实现不对请求和响应进行进一步修改。

以下是Jetty所做的工作:

代码语言:javascript
复制
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 of WebSocketServerFactory调用WebSocketCreator:

代码语言:javascript
复制
Object websocketPojo = creator.createWebSocket(sockreq, sockresp);

在那之后:

代码语言:javascript
复制
private boolean upgrade(HttpConnection http, ServletUpgradeRequest request, ServletUpgradeResponse response, EventDriver driver)

它还通过HandshakeRFC6455修改响应。

代码语言:javascript
复制
 // build response
 response.setHeader("Upgrade","WebSocket");
 response.addHeader("Connection","Upgrade");
 response.addHeader("Sec-WebSocket-Accept",AcceptHash.hashKey(key));

因此,我无法仅用配置器修改响应,因为Jetty无论如何都会更改它。

在我看来,Jetty不符合JSR 356,,对吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-18 12:53:22

啊,JSR-356规范的许多模棱两可和定义不清的部分之一。

您可能需要阅读在规范中打开错误

如果最初的1.x规范完全遵循,那么有许多真实的场景是不可能实现的。

现在,为了解决你问题的具体细节:

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

这是因为有一些有效的场景(尤其是CDI和Spring),其中最终用户所需的checkOrigin实现所需的信息在调用modifyHandshake调用之前是无效的,或者是存在的。

基本上,端点Configurator被创建,modifyHandshake被调用,在这一点上,所有的库集成(CDI,Spring等等)。启动时,端点进入WebSocket (RFC6455)连接状态。(一旦调用了端点的onOpen,则WebSocket RFC6455状态将进入开放状态)

正如您可能已经注意到的,在涉及CDI (或Spring)时,对象的作用域和生存期的规范中没有任何定义。

1.x JSR356规范实际上将自己与servlet容器特定的行为隔离开来,这样做是为了使规范尽可能通用,同时也具有非servlet websocket服务器容器的能力。不幸的是,这也意味着servlet容器中有许多不与1.x JSR356规范相匹配的用例。

一旦JSR356规范被更新以正确定义WebSocket上的CDI作用域,那么checkOriginmodifyHandshake之后的怪癖就可以修复了。

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

实现必须修改响应,否则对于HTTP/1.1升级来说,响应是无效的,对于子协议来说,实现需要与端点及其配置合作,而扩展使这成为现实。(请注意,JSR356规范对扩展进行了投机?)

这也是承诺在下一次JSR356修订版中纠正的一个领域。

当前关于HTTP/2规范的工作使得这一点更加有趣,因为(目前)它没有使用WebSocket /1.1升级语义。它只是通过握手(没有升级,没有起源,等等)就出现了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30302409

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档