001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2011 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.messaging.webapp; 022 023import java.io.ByteArrayInputStream; 024import java.io.ByteArrayOutputStream; 025import java.io.IOException; 026import java.io.InputStream; 027import java.io.OutputStream; 028import java.io.PrintStream; 029 030import javax.servlet.Filter; 031import javax.servlet.FilterChain; 032import javax.servlet.FilterConfig; 033import javax.servlet.ServletException; 034import javax.servlet.ServletInputStream; 035import javax.servlet.ServletOutputStream; 036import javax.servlet.ServletRequest; 037import javax.servlet.ServletResponse; 038import javax.servlet.http.HttpServletRequest; 039import javax.servlet.http.HttpServletRequestWrapper; 040import javax.servlet.http.HttpServletResponse; 041import javax.servlet.http.HttpServletResponseWrapper; 042 043import org.granite.logging.Logger; 044import org.granite.messaging.jmf.JMFDumper; 045import org.granite.messaging.jmf.JMFServletContextListener; 046import org.granite.messaging.jmf.SharedContext; 047import org.granite.util.ContentType; 048 049/** 050 * @author Franck WOLFF 051 */ 052public class JMFDumpFilter implements Filter { 053 054 private static final Logger log = Logger.getLogger(JMFDumpFilter.class); 055 056 private SharedContext jmfSharedContext = null; 057 058 public void init(FilterConfig config) throws ServletException { 059 jmfSharedContext = JMFServletContextListener.getDumpSharedContext(config.getServletContext()); 060 if (jmfSharedContext == null) 061 throw JMFServletContextListener.newSharedContextNotInitializedException(); 062 } 063 064 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 065 throws IOException, ServletException { 066 067 if (!ContentType.JMF_AMF.mimeType().equals(request.getContentType())) { 068 log.info("Ignoring request with content-type: " + request.getContentType()); 069 chain.doFilter(request, response); 070 } 071 else { 072 DumpRequestWrapper requestWrapper = new DumpRequestWrapper((HttpServletRequest)request); 073 DumpResponseWrapper responseWrapper= new DumpResponseWrapper((HttpServletResponse)response); 074 075 chain.doFilter(requestWrapper, responseWrapper); 076 } 077 } 078 079 public void destroy() { 080 jmfSharedContext = null; 081 } 082 083 private void dumpBytes(String label, byte[] bytes) throws IOException { 084 final String encoding = "UTF-8"; 085 086 ByteArrayOutputStream baos = new ByteArrayOutputStream(512); 087 PrintStream ps = new PrintStream(baos, true, encoding); 088 089 JMFDumper dumper = new JMFDumper(new ByteArrayInputStream(bytes), jmfSharedContext, ps); 090 dumper.dump(); 091 dumper.close(); 092 093 log.info("[JMF %s (%d bytes)]\n%s", label.toUpperCase(), bytes.length, new String(baos.toByteArray(), encoding)); 094 } 095 096 class DumpRequestWrapper extends HttpServletRequestWrapper { 097 098 private final ByteArrayOutputStream baos = new ByteArrayOutputStream(); 099 100 public DumpRequestWrapper(HttpServletRequest request) { 101 super(request); 102 } 103 104 @Override 105 public ServletInputStream getInputStream() throws IOException { 106 107 final InputStream is = getRequest().getInputStream(); 108 109 return new ServletInputStream() { 110 111 @Override 112 public int read() throws IOException { 113 int b = is.read(); 114 if (b != -1) 115 baos.write(b); 116 return b; 117 } 118 119 @Override 120 public int available() throws IOException { 121 return is.available(); 122 } 123 124 @Override 125 public void close() throws IOException { 126 is.close(); 127 128 dumpBytes("request", baos.toByteArray()); 129 } 130 }; 131 } 132 } 133 134 class DumpResponseWrapper extends HttpServletResponseWrapper { 135 136 private final ByteArrayOutputStream baos = new ByteArrayOutputStream(256); 137 138 public DumpResponseWrapper(HttpServletResponse response) { 139 super(response); 140 } 141 142 @Override 143 public ServletOutputStream getOutputStream() throws IOException { 144 145 final OutputStream os = getResponse().getOutputStream(); 146 147 return new ServletOutputStream() { 148 @Override 149 public void write(int b) throws IOException { 150 baos.write(b); 151 os.write(b); 152 } 153 154 @Override 155 public void close() throws IOException { 156 os.close(); 157 158 dumpBytes("response", baos.toByteArray()); 159 } 160 }; 161 } 162 } 163}