SockJsHttpRequestHandler.java 4.9 KB
Newer Older
1
/*
S
Sebastien Deleuze 已提交
2
 * Copyright 2002-2015 the original author or authors.
3 4 5 6 7
 *
 * 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
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9 10 11 12 13 14 15 16
 *
 * 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.
 */

17
package org.springframework.web.socket.sockjs.support;
18 19

import java.io.IOException;
20
import javax.servlet.ServletContext;
21 22 23 24
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

25
import org.springframework.context.Lifecycle;
26 27
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
28
import org.springframework.http.server.ServletServerHttpRequest;
29 30 31
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.util.Assert;
import org.springframework.web.HttpRequestHandler;
32
import org.springframework.web.context.ServletContextAware;
S
Sebastien Deleuze 已提交
33 34
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
35
import org.springframework.web.servlet.HandlerMapping;
R
Rossen Stoyanchev 已提交
36
import org.springframework.web.socket.WebSocketHandler;
37 38
import org.springframework.web.socket.handler.ExceptionWebSocketHandlerDecorator;
import org.springframework.web.socket.handler.LoggingWebSocketHandlerDecorator;
39 40
import org.springframework.web.socket.sockjs.SockJsException;
import org.springframework.web.socket.sockjs.SockJsService;
41 42

/**
43 44
 * An {@link HttpRequestHandler} that allows mapping a {@link SockJsService} to requests
 * in a Servlet container.
R
Rossen Stoyanchev 已提交
45
 *
46
 * @author Rossen Stoyanchev
S
Sebastien Deleuze 已提交
47
 * @author Sebastien Deleuze
48 49
 * @since 4.0
 */
50
public class SockJsHttpRequestHandler
51
		implements HttpRequestHandler, CorsConfigurationSource, Lifecycle, ServletContextAware {
52

53 54
	// No logging: HTTP transports too verbose and we don't know enough to log anything of value

55 56
	private final SockJsService sockJsService;

57
	private final WebSocketHandler webSocketHandler;
58

59 60
	private volatile boolean running = false;

61

62
	/**
63
	 * Create a new SockJsHttpRequestHandler.
P
Phillip Webb 已提交
64
	 * @param sockJsService the SockJS service
65
	 * @param webSocketHandler the websocket handler
66
	 */
67
	public SockJsHttpRequestHandler(SockJsService sockJsService, WebSocketHandler webSocketHandler) {
68 69
		Assert.notNull(sockJsService, "SockJsService must not be null");
		Assert.notNull(webSocketHandler, "WebSocketHandler must not be null");
70
		this.sockJsService = sockJsService;
71 72
		this.webSocketHandler =
				new ExceptionWebSocketHandlerDecorator(new LoggingWebSocketHandlerDecorator(webSocketHandler));
73 74
	}

P
Phillip Webb 已提交
75

76 77 78 79 80 81 82 83 84 85 86
	/**
	 * Return the {@link SockJsService}.
	 */
	public SockJsService getSockJsService() {
		return this.sockJsService;
	}

	/**
	 * Return the {@link WebSocketHandler}.
	 */
	public WebSocketHandler getWebSocketHandler() {
87
		return this.webSocketHandler;
88 89
	}

90 91 92 93 94 95 96
	@Override
	public void setServletContext(ServletContext servletContext) {
		if (this.sockJsService instanceof ServletContextAware) {
			((ServletContextAware) this.sockJsService).setServletContext(servletContext);
		}
	}

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117

	@Override
	public void start() {
		if (!isRunning()) {
			this.running = true;
			if (this.sockJsService instanceof Lifecycle) {
				((Lifecycle) this.sockJsService).start();
			}
		}
	}

	@Override
	public void stop() {
		if (isRunning()) {
			this.running = false;
			if (this.sockJsService instanceof Lifecycle) {
				((Lifecycle) this.sockJsService).stop();
			}
		}
	}

118 119 120 121 122
	@Override
	public boolean isRunning() {
		return this.running;
	}

123

124
	@Override
125
	public void handleRequest(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
126 127
			throws ServletException, IOException {

128 129
		ServerHttpRequest request = new ServletServerHttpRequest(servletRequest);
		ServerHttpResponse response = new ServletServerHttpResponse(servletResponse);
130

131
		try {
132
			this.sockJsService.handleRequest(request, response, getSockJsPath(servletRequest), this.webSocketHandler);
133
		}
134 135
		catch (Throwable ex) {
			throw new SockJsException("Uncaught failure in SockJS request, uri=" + request.getURI(), ex);
136
		}
137 138
	}

139 140 141
	private String getSockJsPath(HttpServletRequest servletRequest) {
		String attribute = HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE;
		String path = (String) servletRequest.getAttribute(attribute);
142
		return (path.length() > 0 && path.charAt(0) != '/' ? "/" + path : path);
143 144
	}

S
Sebastien Deleuze 已提交
145 146
	@Override
	public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
147 148
		if (this.sockJsService instanceof CorsConfigurationSource) {
			return ((CorsConfigurationSource) this.sockJsService).getCorsConfiguration(request);
S
Sebastien Deleuze 已提交
149 150 151 152
		}
		return null;
	}

153
}