/** * Copyright (c) 2009 Juwi MacMillan Group GmbH * * 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 * * 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 de.juwimm.cms.servlets; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.net.URL; import java.util.Properties; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.apache.log4j.Logger; /** * * @author <a href="sascha.kulawik@juwimm.com">Sascha-Matthias Kulawik</a> * @version $Id:ProxyJNLPDownloadServlet.java 18392 2007-04-02 15:32:06Z kulawik $ */ public class ProxyJNLPDownloadServlet extends HttpServlet implements javax.servlet.Filter { private static final long serialVersionUID = 5961639019230634706L; private static final String PROPERTIES_FILENAME = "tizzit.properties"; private static final String PLACEHOLDER_PROXY_HOST = "$$fake80codebase"; private static final String PLACEHOLDER_LOG4J_PROPERTIES = "$$fakeClientMailAppenderProperties"; //Mail appender key properties private static final String log4jPrefix = "log4j.appender.email."; private static final String tizzitPropetiesMailAppenderPrefix = "tizzitPropertiesBeanSpring.clientMailAppenderConfig."; private static final String SMTPHostKey = "tizzitPropertiesBeanSpring.clientMailAppenderConfig.SMTPHost"; private static final String fromKey = "tizzitPropertiesBeanSpring.clientMailAppenderConfig.from"; private static final String toKey = "tizzitPropertiesBeanSpring.clientMailAppenderConfig.to"; private static final String SMTP_USR = "tizzitPropertiesBeanSpring.clientMailAppenderConfig.SMTPUsername"; private static final String SMTP_PW = "tizzitPropertiesBeanSpring.clientMailAppenderConfig.SMTPPassword"; private static Logger log = Logger.getLogger(ProxyJNLPDownloadServlet.class); private static final String MAX_HEAP = "max-heap-size=\""; private static final String INITIAL_HEAP = "initial-heap-size=\""; private Properties props = null; //private String clientMailAppenderProperties = "clientMailAppenderProperties=\""; private String serverHost = null; private String serverPort = null; public void init(FilterConfig filterConfig) { if (log.isDebugEnabled()) log.debug("Init"); URL cp = this.getClass().getClassLoader().getResource(PROPERTIES_FILENAME); try { InputStream is = new FileInputStream(cp.getFile()); props = new Properties(); try { is = new FileInputStream(cp.getFile()); } catch (FileNotFoundException e) { log.error("Could not find " + PROPERTIES_FILENAME); } props.load(is); } catch (FileNotFoundException e) { log.error("Could not find " + PROPERTIES_FILENAME); } catch (IOException e) { log.warn("Unable to load jnlpHost / jnlpPort props from \"" + PROPERTIES_FILENAME + "\"!"); } } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { try { long startTime = System.currentTimeMillis(); HttpServletRequest req = (HttpServletRequest) request; if (log.isDebugEnabled()) log.debug("doFilter start for: " + req.getRequestURL().toString()); URL serverName = new URL(req.getRequestURL().toString()); if (serverName.getPath().endsWith(".jnlp")) { if (props == null) { log.error("Unable to load \"" + PROPERTIES_FILENAME + "\"! You MUST restart the server!"); } else { if (serverHost == null) { serverHost = props.getProperty("tizzitPropertiesBeanSpring.jnlpHost", ""); if (serverHost.equalsIgnoreCase("")) { serverHost = serverName.getHost(); } serverPort = props.getProperty("tizzitPropertiesBeanSpring.jnlpPort", ""); if (serverPort.equalsIgnoreCase("")) { if (serverName.getProtocol().equalsIgnoreCase("https")) { serverPort = "443"; } else { serverPort = "80"; } } } } String server80Name = serverName.getProtocol() + "://" + serverHost + ":" + serverPort + serverName.getPath().substring(0, serverName.getPath().lastIndexOf("/")); if (log.isDebugEnabled()) log.debug("$$fake80codebase will be replaced by: " + server80Name); final HttpServletResponse resp = (HttpServletResponse) response; final ByteArrayPrintWriter pw = new ByteArrayPrintWriter(); HttpServletResponse wrappedResp = new HttpServletResponseWrapper(resp) { @Override public PrintWriter getWriter() { return pw.getWriter(); } @Override public ServletOutputStream getOutputStream() { return pw.getStream(); } }; chain.doFilter(request, wrappedResp); byte[] bytes = pw.toByteArray(); String newJnlp = new String(bytes); //server argument newJnlp = newJnlp.replace(PLACEHOLDER_PROXY_HOST, server80Name); //mail appender argument //should be log4jProperties="k1=v1;k2=v2" StringBuilder clientMailAppenderProperties = new StringBuilder("clientMailAppenderProperties=\""); addLog4jPropertyArgument(clientMailAppenderProperties,SMTPHostKey); addLog4jPropertyArgument(clientMailAppenderProperties,fromKey); addLog4jPropertyArgument(clientMailAppenderProperties,toKey); addLog4jPropertyArgument(clientMailAppenderProperties,SMTP_USR); addLog4jPropertyArgument(clientMailAppenderProperties,SMTP_PW); clientMailAppenderProperties.append("\""); newJnlp = newJnlp.replace(PLACEHOLDER_LOG4J_PROPERTIES, clientMailAppenderProperties.toString()); if (isMacClient(req)) { newJnlp = this.cutMemorySettings(newJnlp); } if (log.isDebugEnabled()) log.debug("newJnlp new: " + newJnlp); resp.setContentLength(newJnlp.length()); resp.getOutputStream().print(newJnlp); resp.getOutputStream().close(); } else { chain.doFilter(request, response); } long stopTime = System.currentTimeMillis(); if (log.isDebugEnabled()) log.debug("Time to execute request: " + (stopTime - startTime) + " milliseconds"); } catch (ServletException sx) { log.error(sx.getMessage()); } catch (IOException iox) { log.error(iox.getMessage()); } } private void addLog4jPropertyArgument(StringBuilder clientMailAppenderProperties, String propertyKey) { String propertyValue = props.getProperty(propertyKey); if (propertyValue == null || "".equals(propertyValue)) { log.warn("Property " + propertyKey + "is missing from tizzit.properties"); return; } //properties of the email appender e.g. log4j.appender.email.BufferSize=1 propertyKey = propertyKey.replace(tizzitPropetiesMailAppenderPrefix, log4jPrefix); clientMailAppenderProperties.append(propertyKey + "=" + propertyValue + ";"); } @Override public void destroy() { if (log.isDebugEnabled()) log.debug("destroy"); } /** * */ private static class ByteArrayServletStream extends ServletOutputStream { private final ByteArrayOutputStream baos; ByteArrayServletStream(ByteArrayOutputStream baos) { this.baos = baos; } @Override public void write(int param) throws java.io.IOException { baos.write(param); } } /** * */ private static class ByteArrayPrintWriter { private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); private final PrintWriter pw = new PrintWriter(baos); private final ServletOutputStream sos = new ByteArrayServletStream(baos); public PrintWriter getWriter() { return pw; } public ServletOutputStream getStream() { return sos; } byte[] toByteArray() { return baos.toByteArray(); } } private boolean isMacClient(HttpServletRequest request) { String userAgent = request.getHeader("user-agent"); if (log.isDebugEnabled()) log.debug("User-Agent: " + userAgent); return ((userAgent != null) && (userAgent.indexOf("Mac") >= 0)); } private String cutMemorySettings(String oldJnlp) { StringBuilder sb = new StringBuilder(); // cut max-heap-size int maxHeapIndex = oldJnlp.indexOf(ProxyJNLPDownloadServlet.MAX_HEAP); if (maxHeapIndex > -1) { int endMaxHeapIndex = oldJnlp.indexOf("\"", maxHeapIndex + ProxyJNLPDownloadServlet.MAX_HEAP.length()); sb.append(oldJnlp.substring(0, maxHeapIndex)); sb.append(oldJnlp.substring(endMaxHeapIndex + 1, oldJnlp.length())); } // cut initial-heap-size String tmp = sb.toString(); int initialHeapIndex = tmp.indexOf(ProxyJNLPDownloadServlet.INITIAL_HEAP); if (initialHeapIndex > -1) { sb = new StringBuilder(); int endInitialHeapIndex = tmp.indexOf("\"", initialHeapIndex + ProxyJNLPDownloadServlet.INITIAL_HEAP.length()); sb.append(tmp.substring(0, initialHeapIndex)); sb.append(tmp.substring(endInitialHeapIndex + 1, tmp.length())); } return sb.toString(); } }