xref: /unit/src/java/nginx/unit/websocket/server/WsFilter.java (revision 1157:7ae152bda303)
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 package nginx.unit.websocket.server;
18 
19 import java.io.IOException;
20 
21 import javax.servlet.FilterChain;
22 import javax.servlet.GenericFilter;
23 import javax.servlet.ServletException;
24 import javax.servlet.ServletRequest;
25 import javax.servlet.ServletResponse;
26 import javax.servlet.http.HttpServletRequest;
27 import javax.servlet.http.HttpServletResponse;
28 
29 /**
30  * Handles the initial HTTP connection for WebSocket connections.
31  */
32 public class WsFilter extends GenericFilter {
33 
34     private static final long serialVersionUID = 1L;
35 
36     private transient WsServerContainer sc;
37 
38 
39     @Override
init()40     public void init() throws ServletException {
41         sc = (WsServerContainer) getServletContext().getAttribute(
42                 Constants.SERVER_CONTAINER_SERVLET_CONTEXT_ATTRIBUTE);
43     }
44 
45 
46     @Override
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)47     public void doFilter(ServletRequest request, ServletResponse response,
48             FilterChain chain) throws IOException, ServletException {
49 
50         // This filter only needs to handle WebSocket upgrade requests
51         if (!sc.areEndpointsRegistered() ||
52                 !UpgradeUtil.isWebSocketUpgradeRequest(request, response)) {
53             chain.doFilter(request, response);
54             return;
55         }
56 
57         // HTTP request with an upgrade header for WebSocket present
58         HttpServletRequest req = (HttpServletRequest) request;
59         HttpServletResponse resp = (HttpServletResponse) response;
60 
61         // Check to see if this WebSocket implementation has a matching mapping
62         String path;
63         String pathInfo = req.getPathInfo();
64         if (pathInfo == null) {
65             path = req.getServletPath();
66         } else {
67             path = req.getServletPath() + pathInfo;
68         }
69         WsMappingResult mappingResult = sc.findMapping(path);
70 
71         if (mappingResult == null) {
72             // No endpoint registered for the requested path. Let the
73             // application handle it (it might redirect or forward for example)
74             chain.doFilter(request, response);
75             return;
76         }
77 
78         UpgradeUtil.doUpgrade(sc, req, resp, mappingResult.getConfig(),
79                 mappingResult.getPathParams());
80     }
81 }
82