/** * Checks protocol specific information can and should be upgraded. * * <p>The default implementation will check for the presence of the <code>Upgrade</code> header * with a value of <code>WebSocket</code>. If present, {@link * #isApplicationRequest(org.glassfish.tyrus.spi.UpgradeRequest)} will be invoked to determine if * the request is a valid websocket request. * * @param request TODO * @return <code>true</code> if the request should be upgraded to a WebSocket connection */ public final boolean upgrade(UpgradeRequest request) { final String upgradeHeader = request.getHeader(UpgradeRequest.UPGRADE); return request.getHeaders().get(UpgradeRequest.UPGRADE) != null && // RFC 6455, paragraph 4.2.1.3 UpgradeRequest.WEBSOCKET.equalsIgnoreCase(upgradeHeader) && isApplicationRequest(request); }
/** * Checks application specific criteria to determine if this application can process the request * as a WebSocket connection. * * @param request the incoming HTTP request. * @return <code>true</code> if this application can service this request */ protected boolean isApplicationRequest(UpgradeRequest request) { final List<String> protocols = request.getHeaders().get(UpgradeRequest.SEC_WEBSOCKET_PROTOCOL); temporaryNegotiatedProtocol = endpoint.getNegotiatedProtocol(protocols); final List<Extension> extensions = TyrusExtension.fromString( request.getHeaders().get(UpgradeRequest.SEC_WEBSOCKET_EXTENSIONS)); temporaryNegotiatedExtensions = endpoint.getNegotiatedExtensions(extensions); return endpoint.checkHandshake(request); }
/** * Client side only - Generate host and origin header and put them to the upgrade request headers. * * @param upgradeRequest upgrade request to be updated. */ public static void updateHostAndOrigin(final UpgradeRequest upgradeRequest) { URI requestUri = upgradeRequest.getRequestURI(); String host = requestUri.getHost(); int port = requestUri.getPort(); if (upgradeRequest.isSecure()) { if (port != 443 && port != -1) { host += ":" + port; } } else { if (port != 80 && port != -1) { host += ":" + port; } } Map<String, List<String>> requestHeaders = upgradeRequest.getHeaders(); requestHeaders.put(UpgradeRequest.HOST, Collections.singletonList(host)); requestHeaders.put(UpgradeRequest.ORIGIN_HEADER, Collections.singletonList(host)); }
TyrusEndpoint getEndpoint(UpgradeRequest request) { if (endpoints.isEmpty()) { return null; } final String requestPath = request.getRequestUri(); for (Match m : Match.getAllMatches(requestPath, endpoints)) { final TyrusEndpoint endpoint = m.getTyrusEndpoit(); for (String name : m.getParameterNames()) { request.getParameterMap().put(name, Arrays.asList(m.getParameterValue(name))); } if (endpoint.upgrade(request)) { return endpoint; } } return null; }
/** * Server-side handshake. * * @param request received handshake request. * @param extensionContext extension context. * @return created handshake. * @throws HandshakeException when there is problem with received {@link UpgradeRequest}. */ static Handshake createServerHandshake( UpgradeRequest request, ExtendedExtension.ExtensionContext extensionContext) throws HandshakeException { final Handshake handshake = new Handshake(); handshake.incomingRequest = request; handshake.extensionContext = extensionContext; checkForHeader(request.getHeader(UpgradeRequest.UPGRADE), UpgradeRequest.UPGRADE, "WebSocket"); checkForHeader( request.getHeader(UpgradeRequest.CONNECTION), UpgradeRequest.CONNECTION, UpgradeRequest.UPGRADE); // TODO - trim? final String protocolHeader = request.getHeader(HandshakeRequest.SEC_WEBSOCKET_PROTOCOL); handshake.subProtocols = (protocolHeader == null ? Collections.<String>emptyList() : Arrays.asList(protocolHeader.split(","))); if (request.getHeader(UpgradeRequest.HOST) == null) { throw new HandshakeException(LocalizationMessages.HEADERS_MISSING()); } // final String queryString = request.getQueryString(); // if (queryString != null) { // if (!queryString.isEmpty()) { // } //// Parameters queryParameters = new Parameters(); //// queryParameters.processParameters(queryString); //// final Set<String> names = queryParameters.getParameterNames(); //// for (String name : names) { //// queryParams.put(name, queryParameters.getParameterValues(name)); //// } // } List<String> value = request.getHeaders().get(HandshakeRequest.SEC_WEBSOCKET_EXTENSIONS); if (value != null) { handshake.extensions = TyrusExtension.fromHeaders(value); } handshake.secKey = SecKey.generateServerKey(new SecKey(request.getHeader(HandshakeRequest.SEC_WEBSOCKET_KEY))); return handshake; }
// server side List<Extension> respond( UpgradeRequest request, UpgradeResponse response, TyrusEndpointWrapper endpointWrapper /*,TyrusUpgradeResponse response*/ ) { response.setStatus(101); response.getHeaders().put(UpgradeRequest.UPGRADE, Arrays.asList(UpgradeRequest.WEBSOCKET)); response.getHeaders().put(UpgradeRequest.CONNECTION, Arrays.asList(UpgradeRequest.UPGRADE)); response.setReasonPhrase(UpgradeRequest.RESPONSE_CODE_MESSAGE); response .getHeaders() .put(HandshakeResponse.SEC_WEBSOCKET_ACCEPT, Arrays.asList(secKey.getSecKey())); final List<String> protocols = request.getHeaders().get(HandshakeRequest.SEC_WEBSOCKET_PROTOCOL); final List<Extension> extensions = TyrusExtension.fromString( request.getHeaders().get(HandshakeRequest.SEC_WEBSOCKET_EXTENSIONS)); if (subProtocols != null && !subProtocols.isEmpty()) { String protocol = endpointWrapper.getNegotiatedProtocol(protocols); if (protocol != null && !protocol.isEmpty()) { response.getHeaders().put(HandshakeRequest.SEC_WEBSOCKET_PROTOCOL, Arrays.asList(protocol)); } } final List<Extension> negotiatedExtensions = endpointWrapper.getNegotiatedExtensions(extensions); if (!negotiatedExtensions.isEmpty()) { response .getHeaders() .put( HandshakeRequest.SEC_WEBSOCKET_EXTENSIONS, Utils.getStringList( negotiatedExtensions, new Utils.Stringifier<Extension>() { @Override String toString(final Extension extension) { if (extension instanceof ExtendedExtension) { return TyrusExtension.toString( new Extension() { @Override public String getName() { return extension.getName(); } @Override public List<Parameter> getParameters() { // TODO! XXX FIXME // null is there because extension is wrapped and the // original parameters are stored // in the wrapped instance. return ((ExtendedExtension) extension) .onExtensionNegotiation(extensionContext, null); } }); } else { return TyrusExtension.toString(extension); } } })); } endpointWrapper.onHandShakeResponse(incomingRequest, response); return negotiatedExtensions; }