/** * Constructor. * * @param base64 sec key to be represented as {@link SecKey} instance. * @throws HandshakeException when the provided key is {@code null}. */ public SecKey(String base64) throws HandshakeException { if (base64 == null) { throw new HandshakeException(LocalizationMessages.SEC_KEY_NULL_NOT_ALLOWED()); } secKey = base64; }
private UpgradeInfo handleHandshakeException(HandshakeException handshakeException, UpgradeResponse response) { LOGGER.log(Level.CONFIG, handshakeException.getMessage(), handshakeException); response.setStatus(handshakeException.getHttpStatusCode()); return HANDSHAKE_FAILED_UPGRADE_INFO; }
private RemoteEndpoint.Async getEndpoint() { try { Session session = sessionFuture.get(CONNECTION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS); if (session == null) throw new CucumberException("Couldn't connect to " + uri); return session.getAsyncRemote(); } catch (ExecutionException e) { if (e.getCause() instanceof DeploymentException) { DeploymentException de = (DeploymentException) e.getCause(); if (de.getCause() instanceof HandshakeException) { HandshakeException he = (HandshakeException) de.getCause(); switch (he.getHttpStatusCode()) { case 401: throw new CucumberException("Couldn't authenticate user: " + uri.getQuery()); case 403: throw new CucumberException("Access denied: " + uri.getQuery()); default: throw he; } } else { throw new CucumberException(e); } } else { throw new CucumberException(e); } } catch (TimeoutException e) { throw new CucumberException("Timed out connecting to " + uri, e); } catch (Exception e) { throw new CucumberException(e); } }
/** * Constructor. * * @param base64 sec key to be represented as {@link SecKey} instance. * @throws HandshakeException when the provided key is {@code null}. */ public SecKey(String base64) throws HandshakeException { if (base64 == null) { throw new HandshakeException(LocalizationMessages.SEC_KEY_NULL_NOT_ALLOWED()); } secKey = base64; }
private UpgradeInfo handleHandshakeException(HandshakeException handshakeException, UpgradeResponse response) { LOGGER.log(Level.CONFIG, handshakeException.getMessage(), handshakeException); response.setStatus(handshakeException.getHttpStatusCode()); return HANDSHAKE_FAILED_UPGRADE_INFO; }
private static void validate(String header, String validValue, String value) throws HandshakeException { // http://java.net/jira/browse/TYRUS-55 // Firefox workaround (it sends "Connections: keep-alive, upgrade"). if (header.equalsIgnoreCase(UpgradeRequest.CONNECTION)) { if (value == null || !value.toLowerCase().contains(validValue.toLowerCase())) { throw new HandshakeException(LocalizationMessages.INVALID_HEADER(header, value)); } } else { if (!validValue.equalsIgnoreCase(value)) { throw new HandshakeException(LocalizationMessages.INVALID_HEADER(header, value)); } } }
private static void validate(String header, String validValue, String value) throws HandshakeException { // http://java.net/jira/browse/TYRUS-55 // Firefox workaround (it sends "Connections: keep-alive, upgrade"). if (header.equalsIgnoreCase(UpgradeRequest.CONNECTION)) { if (value == null || !value.toLowerCase().contains(validValue.toLowerCase())) { throw new HandshakeException(LocalizationMessages.INVALID_HEADER(header, value)); } } else { if (!validValue.equalsIgnoreCase(value)) { throw new HandshakeException(LocalizationMessages.INVALID_HEADER(header, value)); } } }
/** * Generate server-side security key, which gets passed to the client during * the handshake phase as part of message payload. * * @param clientKey client's Sec-WebSocket-Key * @return server key. */ public static SecKey generateServerKey(SecKey clientKey) throws HandshakeException { String key = clientKey.getSecKey() + UpgradeRequest.SERVER_KEY_HASH; final MessageDigest instance; try { instance = MessageDigest.getInstance("SHA-1"); instance.update(key.getBytes("UTF-8")); final byte[] digest = instance.digest(); if (digest.length != 20) { throw new HandshakeException(LocalizationMessages.SEC_KEY_INVALID_LENGTH(digest.length)); } return new SecKey(Base64.getEncoder().encodeToString(digest)); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { throw new HandshakeException(e.getMessage()); } }
/** * Generate server-side security key, which gets passed to the client during * the handshake phase as part of message payload. * * @param clientKey client's Sec-WebSocket-Key * @return server key. */ public static SecKey generateServerKey(SecKey clientKey) throws HandshakeException { String key = clientKey.getSecKey() + UpgradeRequest.SERVER_KEY_HASH; final MessageDigest instance; try { instance = MessageDigest.getInstance("SHA-1"); instance.update(key.getBytes("UTF-8")); final byte[] digest = instance.digest(); if (digest.length != 20) { throw new HandshakeException(LocalizationMessages.SEC_KEY_INVALID_LENGTH(digest.length)); } return new SecKey(Base64.getEncoder().encodeToString(digest)); } catch (NoSuchAlgorithmException | UnsupportedEncodingException e) { throw new HandshakeException(e.getMessage()); } }
/** * Validate provided server key. * * @param serverKey server key to be validated. * @throws HandshakeException when the server key is invalid. */ public void validateServerKey(String serverKey) throws HandshakeException { final SecKey key = generateServerKey(this); if (!key.getSecKey().equals(serverKey)) { throw new HandshakeException(LocalizationMessages.SEC_KEY_INVALID_SERVER()); } } }
/** * Validate provided server key. * * @param serverKey server key to be validated. * @throws HandshakeException when the server key is invalid. */ public void validateServerKey(String serverKey) throws HandshakeException { final SecKey key = generateServerKey(this); if (!key.getSecKey().equals(serverKey)) { throw new HandshakeException(LocalizationMessages.SEC_KEY_INVALID_SERVER()); } } }
/** * Server side check for protocol specific information to determine whether the request can be upgraded. * <p> * The default implementation will check for the presence of the * {@code Upgrade} header with a value of {@code WebSocket}. * * @param request received {@link UpgradeRequest}. * @return {@code true} if the request should be upgraded to a WebSocket connection. * @throws HandshakeException when origin verification check returns {@code false}. */ final boolean upgrade(UpgradeRequest request) throws HandshakeException { final String upgradeHeader = request.getHeader(UpgradeRequest.UPGRADE); if (request.getHeaders().get(UpgradeRequest.UPGRADE) != null // RFC 6455, paragraph 4.2.1.3 && UpgradeRequest.WEBSOCKET.equalsIgnoreCase(upgradeHeader)) { if (!(configuration instanceof ServerEndpointConfig)) { return false; } if (configurator.checkOrigin(request.getHeader("Origin"))) { return true; } else { throw new HandshakeException(403, LocalizationMessages.ORIGIN_NOT_VERIFIED()); } } return false; }
/** * Server side check for protocol specific information to determine whether the request can be upgraded. * <p> * The default implementation will check for the presence of the * {@code Upgrade} header with a value of {@code WebSocket}. * * @param request received {@link UpgradeRequest}. * @return {@code true} if the request should be upgraded to a WebSocket connection. * @throws HandshakeException when origin verification check returns {@code false}. */ final boolean upgrade(UpgradeRequest request) throws HandshakeException { final String upgradeHeader = request.getHeader(UpgradeRequest.UPGRADE); if (request.getHeaders().get(UpgradeRequest.UPGRADE) != null // RFC 6455, paragraph 4.2.1.3 && UpgradeRequest.WEBSOCKET.equalsIgnoreCase(upgradeHeader)) { if (!(configuration instanceof ServerEndpointConfig)) { return false; } if (configurator.checkOrigin(request.getHeader("Origin"))) { return true; } else { throw new HandshakeException(403, LocalizationMessages.ORIGIN_NOT_VERIFIED()); } } return false; }
throw new HandshakeException(LocalizationMessages.HEADERS_MISSING());
default: clientEngineState = TyrusClientEngineState.FAILED; HandshakeException e = new HandshakeException( upgradeResponse.getStatus(), LocalizationMessages.INVALID_RESPONSE_CODE(101, upgradeResponse.getStatus()));
throw new HandshakeException(LocalizationMessages.HEADERS_MISSING());
default: clientEngineState = TyrusClientEngineState.FAILED; HandshakeException e = new HandshakeException( upgradeResponse.getStatus(), LocalizationMessages.INVALID_RESPONSE_CODE(101, upgradeResponse.getStatus()));
/** * Client side only - validate server response. * * @param response response to be validated. * @throws HandshakeException when HTTP Status of received response is not 101 - Switching protocols. */ public void validateServerResponse(UpgradeResponse response) throws HandshakeException { if (RESPONSE_CODE_VALUE != response.getStatus()) { throw new HandshakeException(response.getStatus(), LocalizationMessages .INVALID_RESPONSE_CODE(RESPONSE_CODE_VALUE, response.getStatus())); } checkForHeader(response.getFirstHeaderValue(UpgradeRequest.UPGRADE), UpgradeRequest.UPGRADE, UpgradeRequest.WEBSOCKET); checkForHeader(response.getFirstHeaderValue(UpgradeRequest.CONNECTION), UpgradeRequest.CONNECTION, UpgradeRequest.UPGRADE); // if (!getSubProtocols().isEmpty()) { // checkForHeader(response.getHeaders(), WebSocketEngine.SEC_WS_PROTOCOL_HEADER, // WebSocketEngine.SEC_WS_PROTOCOL_HEADER); // } secKey.validateServerKey(response.getFirstHeaderValue(HandshakeResponse.SEC_WEBSOCKET_ACCEPT)); }
/** * Client side only - validate server response. * * @param response response to be validated. * @throws HandshakeException when HTTP Status of received response is not 101 - Switching protocols. */ public void validateServerResponse(UpgradeResponse response) throws HandshakeException { if (RESPONSE_CODE_VALUE != response.getStatus()) { throw new HandshakeException(response.getStatus(), LocalizationMessages .INVALID_RESPONSE_CODE(RESPONSE_CODE_VALUE, response.getStatus())); } checkForHeader(response.getFirstHeaderValue(UpgradeRequest.UPGRADE), UpgradeRequest.UPGRADE, UpgradeRequest.WEBSOCKET); checkForHeader(response.getFirstHeaderValue(UpgradeRequest.CONNECTION), UpgradeRequest.CONNECTION, UpgradeRequest.UPGRADE); // if (!getSubProtocols().isEmpty()) { // checkForHeader(response.getHeaders(), WebSocketEngine.SEC_WS_PROTOCOL_HEADER, // WebSocketEngine.SEC_WS_PROTOCOL_HEADER); // } secKey.validateServerKey(response.getFirstHeaderValue(HandshakeResponse.SEC_WEBSOCKET_ACCEPT)); }