Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You 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.apache.catalina.websocket;
 
 import static org.jboss.web.CatalinaMessages.MESSAGES;
 
 import java.util.List;
 
 
Provides the base implementation of a Servlet for processing WebSocket connections as per RFC6455. It is expected that applications will extend this implementation and provide application specific functionality.
 
 public abstract class WebSocketServlet extends HttpServlet implements HttpEventServlet  {
 
     private static final long serialVersionUID = 1L;
     private static final byte[] WS_ACCEPT =
             "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".getBytes(
                     .);
 
     private final Queue<MessageDigestsha1Helpers =
             new ConcurrentLinkedQueue<MessageDigest>();
 
 
     public void event(HttpEvent eventthrows IOExceptionServletException {
 
         HttpServletRequest req = event.getHttpServletRequest();
         HttpServletResponse resp = event.getHttpServletResponse();
         switch (event.getType()) {
         case :
             // Information required to send the server handshake message
             String key;
             String subProtocol = null;
             List<Stringextensions = Collections.emptyList();
 
             if (!headerContainsToken(req"upgrade""websocket")) {
                 resp.sendError(.);
                 return;
             }
 
             if (!headerContainsToken(req"connection""upgrade")) {
                 resp.sendError(.);
                 return;
             }
 
             if (!headerContainsToken(req"sec-websocket-version""13")) {
                 resp.setStatus(426);
                 resp.setHeader("Sec-WebSocket-Version""13");
                 return;
             }
 
             key = req.getHeader("Sec-WebSocket-Key");
             if (key == null) {
                 resp.sendError(.);
                 return;
             }
 
             String origin = req.getHeader("Origin");
             if (!verifyOrigin(origin)) {
                 resp.sendError(.);
                 return;
             }
 
             List<StringsubProtocols = getTokensFromHeader(req,
                    "Sec-WebSocket-Protocol");
            if (!subProtocols.isEmpty()) {
                subProtocol = selectSubProtocol(subProtocols);
            }
            // Small hack until the Servlet API provides a way to do this.
            ServletResponse inner = resp;
            // Unwrap the request
            while (inner instanceof ServletResponseWrapper) {
                inner = ((ServletResponseWrapperinner).getResponse();
            }
            if (inner instanceof UpgradableHttpServletResponse) {
                ((UpgradableHttpServletResponseinner).startUpgrade();
            } else {
                resp.sendError(.,
                        .errorUpgrading());
            }
            // TODO Read client handshake - Sec-WebSocket-Extensions
            // TODO Extensions require the ability to specify something (API TBD)
            //      that can be passed to the Tomcat internals and process extension
            //      data present when the frame is fragmented.
            // If we got this far, all is good. Accept the connection.
            resp.setHeader("Upgrade""websocket");
            resp.setHeader("Connection""upgrade");
            resp.setHeader("Sec-WebSocket-Accept"getWebSocketAccept(key));
            if (subProtocol != null) {
                resp.setHeader("Sec-WebSocket-Protocol"subProtocol);
            }
            if (!extensions.isEmpty()) {
                // TODO
            }
            WsHttpServletRequestWrapper wrapper = new WsHttpServletRequestWrapper(req);
            StreamInbound inbound = createWebSocketInbound(subProtocolwrapper);
            inbound.setEvent(event);
            wrapper.invalidate();
            ((UpgradableHttpServletResponseinner).sendUpgrade();
            
            inbound.onUpgradeComplete();
            req.setAttribute(.inbound);
            break;
        case :
            event.close();
            break;
        case :
            break;
        case :
            event.close();
            break;
        case :
            break;
        case :
            inbound = (StreamInboundreq.getAttribute(.);
            do {
                inbound.onData();
            } while (event.isReadReady());
            break;
        case :
            // Ignore ?
            break;
        case :
            break;
        }
    }
    /*
     * This only works for tokens. Quoted strings need more sophisticated
     * parsing.
     */
    private boolean headerContainsToken(HttpServletRequest req,
            String headerNameString target) {
        Enumeration<Stringheaders = req.getHeaders(headerName);
        while (headers.hasMoreElements()) {
            String header = headers.nextElement();
            String[] tokens = header.split(",");
            for (String token : tokens) {
                if (target.equalsIgnoreCase(token.trim())) {
                    return true;
                }
            }
        }
        return false;
    }
    /*
     * This only works for tokens. Quoted strings need more sophisticated
     * parsing.
     */
            String headerName) {
        List<Stringresult = new ArrayList<String>();
        Enumeration<Stringheaders = req.getHeaders(headerName);
        while (headers.hasMoreElements()) {
            String header = headers.nextElement();
            String[] tokens = header.split(",");
            for (String token : tokens) {
                result.add(token.trim());
            }
        }
        return result;
    }
    private String getWebSocketAccept(String keythrows ServletException {
        MessageDigest sha1Helper = .poll();
        if (sha1Helper == null) {
            try {
                sha1Helper = MessageDigest.getInstance("SHA1");
            } catch (NoSuchAlgorithmException e) {
                throw new ServletException(e);
            }
        }
        sha1Helper.reset();
        sha1Helper.update(key.getBytes(.));
        String result = new String(Base64.encode(sha1Helper.digest()));
        .add(sha1Helper);
        return result;
    }


    
Intended to be overridden by sub-classes that wish to verify the origin of a WebSocket request before processing it.

Parameters:
origin The value of the origin header from the request which may be null
Returns:
true to accept the request. false to reject it. This default implementation always returns true.
    protected boolean verifyOrigin(String origin) {
        return true;
    }


    
Intended to be overridden by sub-classes that wish to select a sub-protocol if the client provides a list of supported protocols.

Parameters:
subProtocols The list of sub-protocols supported by the client in client preference order. The server is under no obligation to respect the declared preference
Returns:
null if no sub-protocol is selected or the name of the protocol which must be one of the protocols listed by the client. This default implementation always returns null.
    protected String selectSubProtocol(List<StringsubProtocols) {
        return null;
    }


    
Create the instance that will process this inbound connection. Applications must provide a new instance for each connection.

Parameters:
subProtocol The sub-protocol agreed between the client and server or null if none was agreed
request The HTTP request that initiated this WebSocket connection. Note that this object is only valid inside this method. You must not retain a reference to it outside the execution of this method. If Tomcat detects such access, it will throw an IllegalStateException
    protected abstract StreamInbound createWebSocketInbound(String subProtocol,
            HttpServletRequest request);
New to GrepCode? Check out our FAQ X