diff options
Diffstat (limited to 'simple/simple-http/src/main/java/org/simpleframework/http/socket/service/RequestValidator.java')
-rw-r--r-- | simple/simple-http/src/main/java/org/simpleframework/http/socket/service/RequestValidator.java | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/RequestValidator.java b/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/RequestValidator.java new file mode 100644 index 0000000..7e47dc3 --- /dev/null +++ b/simple/simple-http/src/main/java/org/simpleframework/http/socket/service/RequestValidator.java @@ -0,0 +1,137 @@ +/* + * RequestValidator.java February 2014 + * + * Copyright (C) 2014, Niall Gallagher <niallg@users.sf.net> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package org.simpleframework.http.socket.service; + +import static org.simpleframework.http.Protocol.CONNECTION; +import static org.simpleframework.http.Protocol.SEC_WEBSOCKET_KEY; +import static org.simpleframework.http.Protocol.SEC_WEBSOCKET_VERSION; +import static org.simpleframework.http.Protocol.UPGRADE; +import static org.simpleframework.http.Protocol.WEBSOCKET; + +import java.util.List; + +import org.simpleframework.http.Request; + +/** + * The <code>RequestValidator</code> object is used to ensure requests + * for confirm to RFC 6455 section 4.2.1. The client opening handshake + * must consist of several parts, including a version of 13 referring + * to RFC 6455, a WebSocket key, and the required HTTP connection + * details. If any of these are missing the server is obliged to + * respond with a HTTP 400 response indicating a bad request. + * + * @author Niall Gallagher + */ +class RequestValidator { + + /** + * This is the request forming the client part of the handshake. + */ + private final Request request; + + /** + * This is the version referring to the required client version. + */ + private final String version; + + /** + * Constructor for the <code>RequestValidator</code> object. This + * is used to create a plain vanilla validator that uses version + * 13 as dictated by RFC 6455 section 4.2.1. + * + * @param request this is the handshake request from the client + */ + public RequestValidator(Request request) { + this(request, "13"); + } + + /** + * Constructor for the <code>RequestValidator</code> object. This + * is used to create a plain vanilla validator that uses version + * 13 as dictated by RFC 6455 section 4.2.1. + * + * @param request this is the handshake request from the client + * @param version a version other than 13 if desired + */ + public RequestValidator(Request request, String version) { + this.request = request; + this.version = version; + } + + /** + * This is used to determine if the client handshake request had + * all the required headers as dictated by RFC 6455 section 4.2.1. + * If the request does not contain any of these parts then this + * will return false, indicating a HTTP 400 response should be + * sent to the client. + * + * @return true if the request was a valid handshake + */ + public boolean isValid() { + if(!isProtocol()) { + return false; + } + if(!isUpgrade()) { + return false; + } + return true; + } + + /** + * This is used to determine if the request is a valid WebSocket + * handshake of the correct version. This also checks to see if + * the request contained the required handshake token. + * + * @return this returns true if the request is a valid handshake + */ + private boolean isProtocol() { + String protocol = request.getValue(SEC_WEBSOCKET_VERSION); + String token = request.getValue(SEC_WEBSOCKET_KEY); + + if(token != null) { + return version.equals(protocol); + } + return false; + } + + /** + * Here we check to ensure that there is a HTTP connection header + * with the required upgrade token. The upgrade token may be + * one of many, so all must be checked. Finally to ensure that + * the upgrade is for a WebSocket the upgrade header is checked. + * + * @return this returns true if the request is an upgrade + */ + private boolean isUpgrade() { + List<String> tokens = request.getValues(CONNECTION); + + for(String token : tokens) { + if(token.equalsIgnoreCase(UPGRADE)) { + String upgrade = request.getValue(UPGRADE); + + if(upgrade != null) { + return upgrade.equalsIgnoreCase(WEBSOCKET); + } + return false; + } + } + return false; + } + +} |