From: Laramie Crocker Date: Wed, 1 Dec 2010 22:39:22 +0000 (+0000) Subject: CSPACE-338 classes to support sniffing all request/response traffic X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=bd76eaf02c5f6e1bb271bce2f714bdb1d526ee48;p=tmp%2Fjakarta-migration.git CSPACE-338 classes to support sniffing all request/response traffic --- diff --git a/services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/PayloadLogger.java b/services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/PayloadLogger.java index b1259ee61..ec11df9cf 100755 --- a/services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/PayloadLogger.java +++ b/services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/PayloadLogger.java @@ -213,6 +213,11 @@ public class PayloadLogger{ String[] boundaryTokens = headerLine.split("boundary="); if (boundaryTokens.length == 2) { boundary = killTrailingWS(boundaryTokens[1]); + //Header might be: + // Content-Type: multipart/mixed; boundary=a97c20ab-3ef6-4adc-82b0-6cf28c450faf;charset=ISO-8859-1 + + String[] boundaryTerm = boundary.split(";"); + boundary = boundaryTerm[0]; } else if (boundaryTokens.length > 2) { System.err.println("WARNING: too many tokens after boundary= on Content-Type: header line: " + headerLine); diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/dev-master.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/dev-master.xml index 0e938788f..4a6d61dae 100644 --- a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/dev-master.xml +++ b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/dev-master.xml @@ -1,7 +1,7 @@ - http://localhost:8180 + http://localhost:8280 @@ -11,7 +11,7 @@ - + diff --git a/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletInputStream.java b/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletInputStream.java new file mode 100755 index 000000000..513a94b07 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletInputStream.java @@ -0,0 +1,28 @@ +package org.collectionspace.services.common.profile; + +import javax.servlet.ServletInputStream; +import java.io.ByteArrayInputStream; + +/* Subclass of ServletInputStream needed by the servlet engine. +All inputStream methods are wrapped and are delegated to +the ByteArrayInputStream (obtained as constructor parameter)!*/ + +public class BufferedServletInputStream extends ServletInputStream { + ByteArrayInputStream bais; + public BufferedServletInputStream(ByteArrayInputStream bais) { + this.bais = bais; + } + + public int available() { + return bais.available(); + } + + public int read() { + return bais.read(); + } + + public int read(byte[] buf, int off, int len) { + return bais.read(buf, off, len); + } +} + diff --git a/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletOutputStream.java b/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletOutputStream.java new file mode 100755 index 000000000..35993b9fb --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletOutputStream.java @@ -0,0 +1,39 @@ +package org.collectionspace.services.common.profile; + +import java.io.*; +import javax.servlet.*; + +public class BufferedServletOutputStream extends ServletOutputStream { + // the actual buffer + private ByteArrayOutputStream bos = new ByteArrayOutputStream( ); + + public String getAsString(){ + byte[] buf = bos.toByteArray(); + return new String(buf); + } + + /** + * @return the contents of the buffer. + */ + public byte[] getBuffer( ) { + return this.bos.toByteArray( ); + } + + /** + * This method must be defined for custom servlet output streams. + */ + public void write(int data) { + this.bos.write(data); + } + + // BufferedHttpResponseWrapper calls this method + public void reset( ) { + this.bos.reset( ); + } + + // BufferedHttpResponseWrapper calls this method + public void setBufferSize(int size) { + // no way to resize an existing ByteArrayOutputStream + this.bos = new ByteArrayOutputStream(size); + } +} \ No newline at end of file diff --git a/services/common/src/main/java/org/collectionspace/services/common/profile/PayloadFilter.java b/services/common/src/main/java/org/collectionspace/services/common/profile/PayloadFilter.java new file mode 100755 index 000000000..1a8501c4b --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/profile/PayloadFilter.java @@ -0,0 +1,115 @@ +/** + * This document is a part of the source code and related artifacts + * for CollectionSpace, an open source collections management system + * for museums and related institutions: + * + * http://www.collectionspace.org + * http://wiki.collectionspace.org + * + * Copyright 2009 {Contributing Institution} + * + * Licensed under the Educational Community License (ECL), Version 2.0. + * You may not use this file except in compliance with this License. + * + * You may obtain a copy of the ECL 2.0 License at + * https://source.collectionspace.org/collection-space/LICENSE.txt + */ +package org.collectionspace.services.common.profile; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Enumeration; +import java.util.Map; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +//import javax.servlet.ServletContext; + +import org.collectionspace.services.common.ServletTools; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Install like this: + C:\src\trunk\services\JaxRsServiceProvider\src\main\webapp\WEB-INF\web.xml + + PayloadFilter + org.collectionspace.services.common.profile.PayloadFilter + + + PayloadFilter + /* + + */ +public class PayloadFilter implements Filter { + FilterConfig filterConfig = null; + + public String CRLF = "\r\n"; + + @Override + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + if (request != null) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + //String uri = httpRequest.getRequestURI(); + //String method = httpRequest.getMethod(); + RequestWrapper requestWrapper = new RequestWrapper(httpRequest); + //ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response); + + java.io.PrintWriter out = response.getWriter(); + ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response); + + + + // pass the wrappers on to the next entry + chain.doFilter(requestWrapper, responseWrapper); + + + + //StringReader sr = new StringReader(new String(responseWrapper.getData())); + String rsp = responseWrapper.toString(); + response.setContentLength(rsp.length()); + out.write(rsp); + + StringBuffer rqd = new StringBuffer(); + StringBuffer rsd = new StringBuffer(); + + rqd.append(httpRequest.getMethod()+' '+ServletTools.getURL(httpRequest)+' '+httpRequest.getProtocol()+CRLF); + rqd.append(requestWrapper.getHeaderBlock()); + rqd.append(CRLF); + rqd.append(requestWrapper.getRequestAsString()); + System.out.println("request: =========="+CRLF+rqd.toString()); + + rsd.append(responseWrapper.getResponseLine()+CRLF); + rsd.append(responseWrapper.getHeaderBlock()); + rsd.append("Content-Length: "+rsp.length()); + rsd.append(CRLF); + rsd.append(rsp); + //responseWrapper.getContentType() + responseWrapper.getLocale() + responseWrapper.getResponse().) + System.out.println("response: =========="+CRLF+rsd.toString()); + } + } + + @Override + public void init(FilterConfig theFilterConfig) throws ServletException { + filterConfig = theFilterConfig; + if (filterConfig != null) { + // We can initialize using the init-params here which we defined in + // web.xml) + } + } + @Override + + public void destroy() { + // Empty method. + } + + + +} diff --git a/services/common/src/main/java/org/collectionspace/services/common/profile/RequestWrapper.java b/services/common/src/main/java/org/collectionspace/services/common/profile/RequestWrapper.java new file mode 100755 index 000000000..0b0f4a9e0 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/profile/RequestWrapper.java @@ -0,0 +1,98 @@ +package org.collectionspace.services.common.profile; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequestWrapper; +import javax.servlet.http.HttpServletRequest; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Enumeration; + +public class RequestWrapper extends HttpServletRequestWrapper { + + ByteArrayInputStream bais; + ByteArrayOutputStream baos; + BufferedServletInputStream bufInputStream; + byte[] buffer; + HttpServletRequest originalRequest; + + public RequestWrapper(HttpServletRequest req) throws IOException { + super(req); + this.originalRequest = req; + // Read InputStream and store its content in a buffer. + java.io.InputStream is = req.getInputStream(); + baos = new ByteArrayOutputStream(); + byte buf[] = new byte[1024]; + int bytesRead; + while ((bytesRead = is.read(buf)) > 0) baos.write(buf, 0, bytesRead); + buffer = baos.toByteArray(); + } + + public ServletInputStream getInputStream() { + try { + // Generate a new InputStream by stored buffer + bais = new ByteArrayInputStream(buffer); + bufInputStream = new BufferedServletInputStream(bais); //BufferedServletInputStream is our custom class. + } + catch (Exception ex) { + ex.printStackTrace(); + } + finally { + return bufInputStream; + } + } + public String getRequestAsString(){ + return new String(buffer); + } + + public String getHeaderBlock() { + StringBuffer b = new StringBuffer(); + for (Enumeration headernames = originalRequest.getHeaderNames(); headernames.hasMoreElements();) { + String headername = (String) headernames.nextElement(); + b.append(headername + ": " + originalRequest.getHeader(headername) + "\r\n"); + } + return b.toString(); + } + +} + + + /* +public class POSTFilter { +public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + try { + HttpServletRequest httpRequest = (HttpServletRequest) request; + RequestWrapper bufferedRequest = new RequestWrapper(httpRequest); + +//Here obtain InputStream to process POST data! + + InputStream is = bufferedRequest.getInputStream(); + +//... some kind of processing on "is"...... + +//chain.doFilter using wrapped request!!!! + + chain.doFilter(bufferedRequest, response); + +//When a chained servlet call request.getInputStream() + +//then the getInputStream() method of RequestWrapper will be invoked + +//and a new readable copy of the original inputStream will be returned!!! + + } + + catch (Exception ex) { + + ex.printStackTrace(); + + } + + } + +} */ + + + + + diff --git a/services/common/src/main/java/org/collectionspace/services/common/profile/ResponseWrapper.java b/services/common/src/main/java/org/collectionspace/services/common/profile/ResponseWrapper.java new file mode 100755 index 000000000..53580f272 --- /dev/null +++ b/services/common/src/main/java/org/collectionspace/services/common/profile/ResponseWrapper.java @@ -0,0 +1,176 @@ +package org.collectionspace.services.common.profile; + +import java.io.*; +import java.util.HashMap; +import java.util.Map; +import javax.servlet.*; +import javax.servlet.http.*; + +public class ResponseWrapper extends HttpServletResponseWrapper { + private CharArrayWriter output; + private BufferedServletOutputStream os; + private boolean gotWriter = false; + private boolean gotStream = false; + private Map headers = new HashMap(); + private int statusCode = 0; + private String statusMessage = ""; + + public String toString() { + if (gotWriter) return output.toString(); + else { + String str = os.getAsString(); + return str; + } + } + + public ResponseWrapper(HttpServletResponse response) { + super(response); + output = new CharArrayWriter(); + os = new BufferedServletOutputStream(); + } + + public PrintWriter getWriter() { + gotWriter = true; + return new PrintWriter(output); + } + + public ServletOutputStream getOutputStream() { + gotStream = true; + return os; + } + + public void setHeader(String header, String value){ + System.out.println("###### setHeader ######################## header set: "+header+": "+value); + headers.put(header, value); + super.setHeader(header, value); + } + public void addHeader(java.lang.String name, java.lang.String value){ + super.addHeader(name, value); + System.out.println("### addHeader ########################### header set: "+name+": "+value); + + } + public void setIntHeader(java.lang.String name, int value){ + super.setIntHeader(name, value); + System.out.println("### setIntHeader ########################### header set: "+name+": "+value); + } + public void addIntHeader(java.lang.String name, int value){ + super.addIntHeader(name, value); + System.out.println("### addIntHeader ########################### header set: "+name+": "+value); + } + + + public void setStatus(int sc, String sm){ + super.setStatus(sc,sm); + this.statusCode = sc; + this.statusMessage = sm; + } + public void setStatus(int sc){ + super.setStatus(sc); + this.statusCode = sc; + } + public void sendError(int sc) throws java.io.IOException { + super.sendError(sc); + this.statusCode = sc; + } + public void sendError(int sc, String msg) throws java.io.IOException{ + super.sendError(sc, msg); + this.statusCode = sc; + this.statusMessage = msg; + } + + public String getStatusMessage(){ + return statusMessage; + } + public int getStatusCode(){ + return statusCode; + } + public Map getHeaders(){ + return headers; + } + public String getHeaderBlock(){ + StringBuffer b = new StringBuffer(); + for(Map.Entry e : headers.entrySet()){ + b.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n"); + } + return b.toString(); + } + public String getResponseLine(){ + return "HTTP/1.1 "+statusCode+' '+statusMessage; + } + +} + +/** + * A custom response wrapper that captures all output in a buffer. + */ +/* +public class ResponseWrapper extends HttpServletResponseWrapper { + private BufferedServletOutputStream bufferedServletOut = new BufferedServletOutputStream( ); + private PrintWriter printWriter = null; + private ServletOutputStream outputStream = null; + + public ResponseWrapper(HttpServletResponse origResponse) { + super(origResponse); + } + + public String getResponseAsString(){ + return bufferedServletOut.getAsString(); + } + + public byte[] getBuffer( ) { + return this.bufferedServletOut.getBuffer( ); + } + + public PrintWriter getWriter( ) throws IOException { + if (this.outputStream != null) { + throw new IllegalStateException( + "The Servlet API forbids calling getWriter( ) after" + + " getOutputStream( ) has been called"); + } + + if (this.printWriter == null) { + this.printWriter = new PrintWriter(this.bufferedServletOut); + } + return this.printWriter; + } + + public ServletOutputStream getOutputStream( ) throws IOException { + if (this.printWriter != null) { + throw new IllegalStateException( + "The Servlet API forbids calling getOutputStream( ) after" + + " getWriter( ) has been called"); + } + + if (this.outputStream == null) { + this.outputStream = this.bufferedServletOut; + } + return this.outputStream; + } + + // override methods that deal with the response buffer + + public void flushBuffer( ) throws IOException { + if (this.outputStream != null) { + this.outputStream.flush( ); + } else if (this.printWriter != null) { + this.printWriter.flush( ); + } + } + + public int getBufferSize( ) { + return this.bufferedServletOut.getBuffer( ).length; + } + + public void reset( ) { + this.bufferedServletOut.reset( ); + } + + public void resetBuffer( ) { + this.bufferedServletOut.reset( ); + } + + public void setBufferSize(int size) { + this.bufferedServletOut.setBufferSize(size); + } +} +*/ \ No newline at end of file