use of org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection in project jetty.project by eclipse.
the class WebSocketServerFactory method upgrade.
/**
* Upgrade the request/response to a WebSocket Connection.
* <p/>
* This method will not normally return, but will instead throw a UpgradeConnectionException, to exit HTTP handling and initiate WebSocket handling of the
* connection.
*
* @param http the raw http connection
* @param request The request to upgrade
* @param response The response to upgrade
* @param driver The websocket handler implementation to use
*/
private boolean upgrade(HttpConnection http, ServletUpgradeRequest request, ServletUpgradeResponse response, EventDriver driver) throws IOException {
if (!"websocket".equalsIgnoreCase(request.getHeader("Upgrade"))) {
throw new IllegalStateException("Not a 'WebSocket: Upgrade' request");
}
if (!"HTTP/1.1".equals(request.getHttpVersion())) {
throw new IllegalStateException("Not a 'HTTP/1.1' request");
}
int version = request.getHeaderInt("Sec-WebSocket-Version");
if (version < 0) {
// Old pre-RFC version specifications (header not present in RFC-6455)
version = request.getHeaderInt("Sec-WebSocket-Draft");
}
WebSocketHandshake handshaker = handshakes.get(version);
if (handshaker == null) {
StringBuilder warn = new StringBuilder();
warn.append("Client ").append(request.getRemoteAddress());
warn.append(" (:").append(request.getRemotePort());
warn.append(") User Agent: ");
String ua = request.getHeader("User-Agent");
if (ua == null) {
warn.append("[unset] ");
} else {
warn.append('"').append(StringUtil.sanitizeXmlString(ua)).append("\" ");
}
warn.append("requested WebSocket version [").append(version);
warn.append("], Jetty supports version");
if (handshakes.size() > 1) {
warn.append('s');
}
warn.append(": [").append(supportedVersions).append("]");
LOG.warn(warn.toString());
// Per RFC 6455 - 4.4 - Supporting Multiple Versions of WebSocket Protocol
// Using the examples as outlined
response.setHeader("Sec-WebSocket-Version", supportedVersions);
response.sendError(HttpStatus.BAD_REQUEST_400, "Unsupported websocket version specification");
return false;
}
// Initialize / Negotiate Extensions
ExtensionStack extensionStack = new ExtensionStack(getExtensionFactory());
// Usually from a Configurator.
if (response.isExtensionsNegotiated()) {
// Use pre-negotiated extension list from response
extensionStack.negotiate(response.getExtensions());
} else {
// Use raw extension list from request
extensionStack.negotiate(request.getExtensions());
}
// Get original HTTP connection
EndPoint endp = http.getEndPoint();
Connector connector = http.getConnector();
Executor executor = connector.getExecutor();
ByteBufferPool bufferPool = connector.getByteBufferPool();
// Setup websocket connection
AbstractWebSocketConnection wsConnection = new WebSocketServerConnection(endp, executor, scheduler, driver.getPolicy(), bufferPool);
extensionStack.setPolicy(driver.getPolicy());
extensionStack.configure(wsConnection.getParser());
extensionStack.configure(wsConnection.getGenerator());
if (LOG.isDebugEnabled()) {
LOG.debug("HttpConnection: {}", http);
LOG.debug("WebSocketConnection: {}", wsConnection);
}
// Setup Session
WebSocketSession session = createSession(request.getRequestURI(), driver, wsConnection);
session.setUpgradeRequest(request);
// set true negotiated extension list back to response
response.setExtensions(extensionStack.getNegotiatedExtensions());
session.setUpgradeResponse(response);
wsConnection.addListener(session);
// Setup Incoming Routing
wsConnection.setNextIncomingFrames(extensionStack);
extensionStack.setNextIncoming(session);
// Setup Outgoing Routing
session.setOutgoingHandler(extensionStack);
extensionStack.setNextOutgoing(wsConnection);
// Start Components
session.addManaged(extensionStack);
this.addManaged(session);
if (session.isFailed()) {
throw new IOException("Session failed to start");
}
// Tell jetty about the new upgraded connection
request.setServletAttribute(HttpConnection.UPGRADE_CONNECTION_ATTRIBUTE, wsConnection);
if (LOG.isDebugEnabled())
LOG.debug("Handshake Response: {}", handshaker);
if (getSendServerVersion(connector))
response.setHeader("Server", HttpConfiguration.SERVER_VERSION);
// Process (version specific) handshake response
handshaker.doHandshakeResponse(request, response);
if (LOG.isDebugEnabled())
LOG.debug("Websocket upgrade {} {} {} {}", request.getRequestURI(), version, response.getAcceptedSubProtocol(), wsConnection);
return true;
}
Aggregations