/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see <http://www.gnu.org/licenses/>.
*/
package org.granite.messaging.webapp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.granite.logging.Logger;
import org.granite.util.ServletParams;
/**
* @author Franck WOLFF
*/
public class DumpFilter implements Filter {
private static final Logger log = Logger.getLogger(DumpFilter.class);
private static final String HEXS = "0123456789ABCDEF";
private static final String DUMP_DIR = "dumpDir";
File dumpDir = null;
public void init(FilterConfig config) throws ServletException {
String dumpDirString = ServletParams.get(config, DUMP_DIR, String.class, null);
if (dumpDirString != null) {
File dumpDir = new File(dumpDirString);
if (!dumpDir.exists() || !dumpDir.isDirectory() || !dumpDir.canWrite())
log.warn("Ignoring dump directory (is it a writable directory?): %s", dumpDir);
else
this.dumpDir = dumpDir;
}
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
DumpRequestWrapper requestWrapper = new DumpRequestWrapper((HttpServletRequest)request);
DumpResponseWrapper responseWrapper= new DumpResponseWrapper((HttpServletResponse)response);
dumpBytes("request", requestWrapper.getBytes());
chain.doFilter(requestWrapper, responseWrapper);
dumpBytes("response", responseWrapper.getBytes());
}
public void destroy() {
dumpDir = null;
}
private void dumpBytes(String label, byte[] bytes) {
StringBuilder hexSb = new StringBuilder();
StringBuilder charSb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
int b = bytes[i] & 0xFF;
if (hexSb.length() > 0) {
hexSb.append(' ');
charSb.append(' ');
}
hexSb.append(HEXS.charAt(b >> 4)).append(HEXS.charAt(b & 0x0F));
if (b >= 0x20 && b <= 0x7e)
charSb.append(' ').append((char)b);
else
charSb.append("##");
}
log.info("[RAW %s] {\n%s\n%s\n}", label.toUpperCase(), hexSb.toString(), charSb.toString());
if (dumpDir != null) {
File file = new File(dumpDir.getPath() + File.separator + label + "_" + System.currentTimeMillis() + ".amf");
for (int i = 1; i < 100 && file.exists(); i++)
file = new File(file.getAbsolutePath() + "." + i);
OutputStream os = null;
try {
os = new FileOutputStream(file);
os.write(bytes);
} catch (Exception e) {
log.error(e, "Could not write dump file: %s", file);
} finally {
if (os != null) try {
os.close();
} catch (Exception e) {
}
}
}
}
class DumpRequestWrapper extends HttpServletRequestWrapper {
private byte[] bytes = null;
public DumpRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
setCharacterEncoding("UTF-8");
InputStream is = null;
try {
is = request.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream(128);
for (int b = is.read(); b != -1; b = is.read())
out.write(b);
this.bytes = out.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
return new ServletInputStream() {
@Override
public int read() throws IOException {
return bais.read();
}
};
}
public byte[] getBytes() {
return bytes;
}
}
class DumpResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream baos = new ByteArrayOutputStream(256);
private ServletOutputStream out = null;
public DumpResponseWrapper(HttpServletResponse response) throws IOException {
super(response);
this.out = response.getOutputStream();
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
@Override
public void write(int b) throws IOException {
baos.write(b);
out.write(b);
}
};
}
public byte[] getBytes() {
return baos.toByteArray();
}
}
}