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