001/* 002 * Copyright 2002-2018 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.io.IOException; 020import java.lang.reflect.Constructor; 021 022import javax.servlet.ServletException; 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletResponse; 025 026import org.glassfish.tyrus.core.TyrusUpgradeResponse; 027import org.glassfish.tyrus.core.Utils; 028import org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler; 029import org.glassfish.tyrus.spi.WebSocketEngine.UpgradeInfo; 030import org.glassfish.tyrus.spi.Writer; 031 032import org.springframework.util.ReflectionUtils; 033import org.springframework.web.socket.server.HandshakeFailureException; 034 035/** 036 * A WebSocket {@code RequestUpgradeStrategy} for Oracle's GlassFish 4.1 and higher. 037 * 038 * @author Rossen Stoyanchev 039 * @author Juergen Hoeller 040 * @author Michael Irwin 041 * @since 4.0 042 */ 043public class GlassFishRequestUpgradeStrategy extends AbstractTyrusRequestUpgradeStrategy { 044 045 private static final Constructor<?> constructor; 046 047 static { 048 try { 049 ClassLoader classLoader = GlassFishRequestUpgradeStrategy.class.getClassLoader(); 050 Class<?> type = classLoader.loadClass("org.glassfish.tyrus.servlet.TyrusServletWriter"); 051 constructor = type.getDeclaredConstructor(TyrusHttpUpgradeHandler.class); 052 ReflectionUtils.makeAccessible(constructor); 053 } 054 catch (Exception ex) { 055 throw new IllegalStateException("No compatible Tyrus version found", ex); 056 } 057 } 058 059 060 @Override 061 protected void handleSuccess(HttpServletRequest request, HttpServletResponse response, 062 UpgradeInfo upgradeInfo, TyrusUpgradeResponse upgradeResponse) throws IOException, ServletException { 063 064 TyrusHttpUpgradeHandler handler = request.upgrade(TyrusHttpUpgradeHandler.class); 065 Writer servletWriter = newServletWriter(handler); 066 handler.preInit(upgradeInfo, servletWriter, request.getUserPrincipal() != null); 067 068 response.setStatus(upgradeResponse.getStatus()); 069 upgradeResponse.getHeaders().forEach((key, value) -> response.addHeader(key, Utils.getHeaderFromList(value))); 070 response.flushBuffer(); 071 } 072 073 private Writer newServletWriter(TyrusHttpUpgradeHandler handler) { 074 try { 075 return (Writer) constructor.newInstance(handler); 076 } 077 catch (Exception ex) { 078 throw new HandshakeFailureException("Failed to instantiate TyrusServletWriter", ex); 079 } 080 } 081 082}