001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.socket.server.standard; 018 019import java.lang.reflect.Method; 020import java.util.Collections; 021import java.util.List; 022import java.util.Map; 023 024import javax.servlet.http.HttpServletRequest; 025import javax.servlet.http.HttpServletResponse; 026import javax.websocket.Endpoint; 027import javax.websocket.Extension; 028import javax.websocket.server.ServerContainer; 029import javax.websocket.server.ServerEndpointConfig; 030 031import org.springframework.http.server.ServerHttpRequest; 032import org.springframework.http.server.ServerHttpResponse; 033import org.springframework.lang.Nullable; 034import org.springframework.web.socket.server.HandshakeFailureException; 035 036/** 037 * WebSphere support for upgrading an {@link HttpServletRequest} during a 038 * WebSocket handshake. To modify properties of the underlying 039 * {@link javax.websocket.server.ServerContainer} you can use 040 * {@link ServletServerContainerFactoryBean} in XML configuration or, when using 041 * Java configuration, access the container instance through the 042 * "javax.websocket.server.ServerContainer" ServletContext attribute. 043 * 044 * <p>Tested with WAS Liberty beta (August 2015) for the upcoming 8.5.5.7 release. 045 * 046 * @author Rossen Stoyanchev 047 * @since 4.2.1 048 */ 049public class WebSphereRequestUpgradeStrategy extends AbstractStandardUpgradeStrategy { 050 051 private static final Method upgradeMethod; 052 053 static { 054 ClassLoader loader = WebSphereRequestUpgradeStrategy.class.getClassLoader(); 055 try { 056 Class<?> type = loader.loadClass("com.ibm.websphere.wsoc.WsWsocServerContainer"); 057 upgradeMethod = type.getMethod("doUpgrade", HttpServletRequest.class, 058 HttpServletResponse.class, ServerEndpointConfig.class, Map.class); 059 } 060 catch (Exception ex) { 061 throw new IllegalStateException("No compatible WebSphere version found", ex); 062 } 063 } 064 065 066 @Override 067 public String[] getSupportedVersions() { 068 return new String[] {"13"}; 069 } 070 071 @Override 072 public void upgradeInternal(ServerHttpRequest httpRequest, ServerHttpResponse httpResponse, 073 @Nullable String selectedProtocol, List<Extension> selectedExtensions, Endpoint endpoint) 074 throws HandshakeFailureException { 075 076 HttpServletRequest request = getHttpServletRequest(httpRequest); 077 HttpServletResponse response = getHttpServletResponse(httpResponse); 078 079 StringBuffer requestUrl = request.getRequestURL(); 080 String path = request.getRequestURI(); // shouldn't matter 081 Map<String, String> pathParams = Collections.<String, String> emptyMap(); 082 083 ServerEndpointRegistration endpointConfig = new ServerEndpointRegistration(path, endpoint); 084 endpointConfig.setSubprotocols(Collections.singletonList(selectedProtocol)); 085 endpointConfig.setExtensions(selectedExtensions); 086 087 try { 088 ServerContainer container = getContainer(request); 089 upgradeMethod.invoke(container, request, response, endpointConfig, pathParams); 090 } 091 catch (Exception ex) { 092 throw new HandshakeFailureException( 093 "Servlet request failed to upgrade to WebSocket for " + requestUrl, ex); 094 } 095 } 096 097}