]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-338 classes to support sniffing all request/response traffic
authorLaramie Crocker <laramie@berkeley.edu>
Wed, 1 Dec 2010 22:39:22 +0000 (22:39 +0000)
committerLaramie Crocker <laramie@berkeley.edu>
Wed, 1 Dec 2010 22:39:22 +0000 (22:39 +0000)
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/PayloadLogger.java
services/IntegrationTests/src/test/resources/test-data/xmlreplay/dev-master.xml
services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletInputStream.java [new file with mode: 0755]
services/common/src/main/java/org/collectionspace/services/common/profile/BufferedServletOutputStream.java [new file with mode: 0755]
services/common/src/main/java/org/collectionspace/services/common/profile/PayloadFilter.java [new file with mode: 0755]
services/common/src/main/java/org/collectionspace/services/common/profile/RequestWrapper.java [new file with mode: 0755]
services/common/src/main/java/org/collectionspace/services/common/profile/ResponseWrapper.java [new file with mode: 0755]

index b1259ee61e560a12cca38e8c262b2391ab976971..ec11df9cf2e94a5a0a244e1db0dd94a09d37c09f 100755 (executable)
@@ -213,6 +213,11 @@ public class PayloadLogger{
             String[] boundaryTokens = headerLine.split("boundary=");\r
             if (boundaryTokens.length == 2) {\r
                 boundary = killTrailingWS(boundaryTokens[1]);\r
+                //Header might be:\r
+                // Content-Type: multipart/mixed; boundary=a97c20ab-3ef6-4adc-82b0-6cf28c450faf;charset=ISO-8859-1\r
+\r
+                String[] boundaryTerm = boundary.split(";");\r
+                boundary = boundaryTerm[0];\r
 \r
             } else if (boundaryTokens.length > 2) {\r
                 System.err.println("WARNING: too many tokens after boundary= on Content-Type: header line: " + headerLine);\r
index 0e938788f014b9cac5c551c6e94d1984511461f6..4a6d61dae4330a38c403546b0a58db5ecc7a382f 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <xmlReplayMaster>\r
 <!-- Use this file to drive local testing.  Check it in or don't ... no automated tests should reference this file. -->\r
-    <protoHostPort>http://localhost:8180</protoHostPort>\r
+    <protoHostPort>http://localhost:8280</protoHostPort>\r
     \r
     <!-- legal values for dumpServiceResult=[minimal,detailed,full] -->\r
     <dump payloads="false" dumpServiceResult="minimal" />\r
@@ -11,7 +11,7 @@
     </auths>\r
 \r
 \r
-    <run controlFile="objectexit/object-exit.xml" testGroup="CRUDL" />\r
+   <!-- <run controlFile="objectexit/object-exit.xml" testGroup="CRUDL" />-->   \r
     <run controlFile="objectexit/object-exit.xml" testGroup="domwalk" />\r
     \r
 \r
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 (executable)
index 0000000..513a94b
--- /dev/null
@@ -0,0 +1,28 @@
+package org.collectionspace.services.common.profile;\r
+\r
+import javax.servlet.ServletInputStream;\r
+import java.io.ByteArrayInputStream;\r
+\r
+/* Subclass of ServletInputStream needed by the servlet engine.\r
+All inputStream methods are wrapped and are delegated to\r
+the ByteArrayInputStream (obtained as constructor parameter)!*/\r
+\r
+public class BufferedServletInputStream extends ServletInputStream {\r
+    ByteArrayInputStream bais;\r
+    public BufferedServletInputStream(ByteArrayInputStream bais) {\r
+        this.bais = bais;\r
+    }\r
+\r
+    public int available() {\r
+        return bais.available();\r
+    }\r
+\r
+    public int read() {\r
+        return bais.read();\r
+    }\r
+\r
+    public int read(byte[] buf, int off, int len) {\r
+        return bais.read(buf, off, len);\r
+    }\r
+}\r
+\r
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 (executable)
index 0000000..35993b9
--- /dev/null
@@ -0,0 +1,39 @@
+package org.collectionspace.services.common.profile;\r
+\r
+import java.io.*;\r
+import javax.servlet.*;\r
+\r
+public class BufferedServletOutputStream extends ServletOutputStream {\r
+    // the actual buffer\r
+    private ByteArrayOutputStream bos = new ByteArrayOutputStream( );\r
+\r
+    public String getAsString(){\r
+        byte[] buf = bos.toByteArray();\r
+        return new String(buf);\r
+    }\r
+\r
+    /**\r
+     * @return the contents of the buffer.\r
+     */\r
+    public byte[] getBuffer( ) {\r
+        return this.bos.toByteArray( );\r
+    }\r
+\r
+    /**\r
+     * This method must be defined for custom servlet output streams.\r
+     */\r
+    public void write(int data) {\r
+        this.bos.write(data);\r
+    }\r
+\r
+    // BufferedHttpResponseWrapper calls this method\r
+    public void reset( ) {\r
+        this.bos.reset( );\r
+    }\r
+\r
+    // BufferedHttpResponseWrapper calls this method\r
+    public void setBufferSize(int size) {\r
+        // no way to resize an existing ByteArrayOutputStream\r
+        this.bos = new ByteArrayOutputStream(size);\r
+    }\r
+}
\ 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 (executable)
index 0000000..1a8501c
--- /dev/null
@@ -0,0 +1,115 @@
+/**\r
+ * This document is a part of the source code and related artifacts\r
+ * for CollectionSpace, an open source collections management system\r
+ * for museums and related institutions:\r
+ *\r
+ * http://www.collectionspace.org\r
+ * http://wiki.collectionspace.org\r
+ *\r
+ * Copyright 2009 {Contributing Institution}\r
+ *\r
+ * Licensed under the Educational Community License (ECL), Version 2.0.\r
+ * You may not use this file except in compliance with this License.\r
+ *\r
+ * You may obtain a copy of the ECL 2.0 License at\r
+ * https://source.collectionspace.org/collection-space/LICENSE.txt\r
+ */\r
+package org.collectionspace.services.common.profile;\r
+\r
+import java.io.IOException;\r
+import java.io.StringReader;\r
+import java.util.Enumeration;\r
+import java.util.Map;\r
+import javax.servlet.Filter;\r
+import javax.servlet.FilterChain;\r
+import javax.servlet.FilterConfig;\r
+import javax.servlet.ServletException;\r
+import javax.servlet.ServletRequest;\r
+import javax.servlet.ServletResponse;\r
+import javax.servlet.http.HttpServletRequest;\r
+import javax.servlet.http.HttpServletResponse;\r
+//import javax.servlet.ServletContext;\r
+\r
+import org.collectionspace.services.common.ServletTools;\r
+\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+/**\r
+ *  Install like this:\r
+    C:\src\trunk\services\JaxRsServiceProvider\src\main\webapp\WEB-INF\web.xml\r
+ <filter>\r
+     <filter-name>PayloadFilter</filter-name>\r
+     <filter-class>org.collectionspace.services.common.profile.PayloadFilter</filter-class>\r
+ </filter>\r
+ <filter-mapping>\r
+     <filter-name>PayloadFilter</filter-name>\r
+     <url-pattern>/*</url-pattern>\r
+ </filter-mapping>\r
+ */\r
+public class PayloadFilter implements Filter {\r
+    FilterConfig filterConfig = null;\r
+\r
+    public String CRLF = "\r\n";\r
+\r
+    @Override\r
+    public void doFilter(ServletRequest request, ServletResponse response,\r
+            FilterChain chain) throws IOException, ServletException {\r
+        if (request != null) {\r
+            HttpServletRequest httpRequest = (HttpServletRequest) request;\r
+            //String uri = httpRequest.getRequestURI();\r
+            //String method = httpRequest.getMethod();\r
+            RequestWrapper requestWrapper = new RequestWrapper(httpRequest);\r
+            //ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);\r
+\r
+            java.io.PrintWriter out = response.getWriter();\r
+            ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response);\r
+\r
+\r
+\r
+            // pass the wrappers on to the next entry\r
+            chain.doFilter(requestWrapper, responseWrapper);\r
+\r
+\r
+\r
+            //StringReader sr = new StringReader(new String(responseWrapper.getData()));\r
+            String rsp = responseWrapper.toString();\r
+            response.setContentLength(rsp.length());\r
+            out.write(rsp);\r
+\r
+            StringBuffer rqd = new StringBuffer();\r
+            StringBuffer rsd = new StringBuffer();\r
+\r
+            rqd.append(httpRequest.getMethod()+' '+ServletTools.getURL(httpRequest)+' '+httpRequest.getProtocol()+CRLF);\r
+            rqd.append(requestWrapper.getHeaderBlock());\r
+            rqd.append(CRLF);\r
+            rqd.append(requestWrapper.getRequestAsString());\r
+            System.out.println("request: =========="+CRLF+rqd.toString());\r
+\r
+            rsd.append(responseWrapper.getResponseLine()+CRLF);\r
+            rsd.append(responseWrapper.getHeaderBlock());\r
+            rsd.append("Content-Length: "+rsp.length());\r
+            rsd.append(CRLF);\r
+            rsd.append(rsp);\r
+            //responseWrapper.getContentType() + responseWrapper.getLocale() + responseWrapper.getResponse().)\r
+            System.out.println("response: =========="+CRLF+rsd.toString());\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void init(FilterConfig theFilterConfig) throws ServletException {\r
+        filterConfig = theFilterConfig;\r
+        if (filterConfig != null) {\r
+            // We can initialize using the init-params here which we defined in\r
+            // web.xml)\r
+        }\r
+    }\r
+    @Override\r
+\r
+    public void destroy() {\r
+        // Empty method.\r
+    }\r
+\r
+\r
+\r
+}\r
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 (executable)
index 0000000..0b0f4a9
--- /dev/null
@@ -0,0 +1,98 @@
+package org.collectionspace.services.common.profile;\r
+\r
+import javax.servlet.*;\r
+import javax.servlet.http.HttpServletRequestWrapper;\r
+import javax.servlet.http.HttpServletRequest;\r
+import java.io.ByteArrayInputStream;\r
+import java.io.ByteArrayOutputStream;\r
+import java.io.IOException;\r
+import java.util.Enumeration;\r
+\r
+public class RequestWrapper extends HttpServletRequestWrapper {\r
+\r
+    ByteArrayInputStream bais;\r
+    ByteArrayOutputStream baos;\r
+    BufferedServletInputStream bufInputStream;\r
+    byte[] buffer;\r
+    HttpServletRequest originalRequest;\r
+\r
+    public RequestWrapper(HttpServletRequest req) throws IOException {\r
+        super(req);\r
+        this.originalRequest = req;\r
+        // Read InputStream and store its content in a buffer.\r
+        java.io.InputStream is = req.getInputStream();\r
+        baos = new ByteArrayOutputStream();\r
+        byte buf[] = new byte[1024];\r
+        int bytesRead;\r
+        while ((bytesRead = is.read(buf)) > 0) baos.write(buf, 0, bytesRead);\r
+        buffer = baos.toByteArray();\r
+    }\r
+\r
+    public ServletInputStream getInputStream() {\r
+        try {\r
+            // Generate a new InputStream by stored buffer\r
+            bais = new ByteArrayInputStream(buffer);\r
+            bufInputStream = new BufferedServletInputStream(bais); //BufferedServletInputStream is our custom class.\r
+        }\r
+        catch (Exception ex) {\r
+            ex.printStackTrace();\r
+        }\r
+        finally {\r
+            return bufInputStream;\r
+        }\r
+    }\r
+    public String getRequestAsString(){\r
+        return new String(buffer);\r
+    }\r
+\r
+    public String getHeaderBlock() {\r
+        StringBuffer b = new StringBuffer();\r
+        for (Enumeration headernames = originalRequest.getHeaderNames(); headernames.hasMoreElements();) {\r
+            String headername = (String) headernames.nextElement();\r
+            b.append(headername + ": " + originalRequest.getHeader(headername) + "\r\n");\r
+        }\r
+        return b.toString();\r
+    }\r
+\r
+}\r
+\r
+\r
+ /*\r
+public class POSTFilter {\r
+public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {\r
+        try {\r
+            HttpServletRequest httpRequest = (HttpServletRequest) request;\r
+            RequestWrapper bufferedRequest = new RequestWrapper(httpRequest);\r
+\r
+//Here obtain InputStream to process POST data!\r
+\r
+            InputStream is = bufferedRequest.getInputStream();\r
+\r
+//... some kind of processing on "is"......\r
+\r
+//chain.doFilter using wrapped request!!!!\r
+\r
+            chain.doFilter(bufferedRequest, response);\r
+\r
+//When a chained servlet call request.getInputStream()\r
+\r
+//then the getInputStream() method of RequestWrapper will be invoked\r
+\r
+//and a new readable copy of the original inputStream will be returned!!!\r
+\r
+        }\r
+\r
+        catch (Exception ex) {\r
+\r
+            ex.printStackTrace();\r
+\r
+        }\r
+\r
+    }\r
+\r
+}  */\r
+\r
+\r
+\r
+\r
+\r
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 (executable)
index 0000000..53580f2
--- /dev/null
@@ -0,0 +1,176 @@
+package org.collectionspace.services.common.profile;\r
+\r
+import java.io.*;\r
+import java.util.HashMap;\r
+import java.util.Map;\r
+import javax.servlet.*;\r
+import javax.servlet.http.*;\r
+\r
+public class ResponseWrapper extends HttpServletResponseWrapper {\r
+    private CharArrayWriter output;\r
+    private BufferedServletOutputStream os;\r
+    private boolean gotWriter = false;\r
+    private boolean gotStream = false;\r
+    private Map<String, String> headers = new HashMap<String,String>();\r
+    private int statusCode = 0;\r
+    private String statusMessage = "";\r
+\r
+    public String toString() {\r
+        if (gotWriter) return output.toString();\r
+        else {\r
+            String str = os.getAsString();\r
+            return str;\r
+        }\r
+    }\r
+\r
+    public ResponseWrapper(HttpServletResponse response) {\r
+        super(response);\r
+        output = new CharArrayWriter();\r
+        os = new BufferedServletOutputStream();\r
+    }\r
+\r
+    public PrintWriter getWriter() {\r
+        gotWriter = true;\r
+        return new PrintWriter(output);\r
+    }\r
+\r
+    public ServletOutputStream getOutputStream() {\r
+        gotStream = true;\r
+        return os;\r
+    }\r
+\r
+    public void setHeader(String header, String value){\r
+        System.out.println("###### setHeader ######################## header set: "+header+": "+value);\r
+        headers.put(header, value);\r
+        super.setHeader(header, value);\r
+    }\r
+    public void addHeader(java.lang.String name, java.lang.String value){\r
+        super.addHeader(name, value);\r
+        System.out.println("### addHeader  ########################### header set: "+name+": "+value);\r
+\r
+    }\r
+    public void setIntHeader(java.lang.String name, int value){\r
+        super.setIntHeader(name, value);\r
+        System.out.println("### setIntHeader  ########################### header set: "+name+": "+value);\r
+    }\r
+    public void addIntHeader(java.lang.String name, int value){\r
+        super.addIntHeader(name, value);\r
+        System.out.println("### addIntHeader  ########################### header set: "+name+": "+value);\r
+    }\r
+\r
+\r
+    public void setStatus(int sc, String sm){\r
+        super.setStatus(sc,sm);\r
+        this.statusCode = sc;\r
+        this.statusMessage = sm;\r
+    }\r
+    public void setStatus(int sc){\r
+        super.setStatus(sc);\r
+        this.statusCode = sc;\r
+    }\r
+    public void sendError(int sc) throws java.io.IOException {\r
+        super.sendError(sc);\r
+        this.statusCode = sc;\r
+    }\r
+    public void sendError(int sc, String msg) throws java.io.IOException{\r
+        super.sendError(sc, msg);\r
+        this.statusCode = sc;\r
+        this.statusMessage = msg;\r
+    }\r
+\r
+    public String getStatusMessage(){\r
+        return statusMessage;\r
+    }\r
+    public int getStatusCode(){\r
+        return statusCode;\r
+    }\r
+    public Map getHeaders(){\r
+        return headers;\r
+    }\r
+    public String getHeaderBlock(){\r
+        StringBuffer b = new StringBuffer();\r
+        for(Map.Entry<String, String> e : headers.entrySet()){\r
+            b.append(e.getKey()).append(": ").append(e.getValue()).append("\r\n");\r
+        }\r
+        return b.toString();\r
+    }\r
+    public String getResponseLine(){\r
+        return "HTTP/1.1 "+statusCode+' '+statusMessage;\r
+    }\r
+\r
+}\r
+\r
+/**\r
+ * A custom response wrapper that captures all output in a buffer.\r
+ */\r
+/*\r
+public class ResponseWrapper extends HttpServletResponseWrapper {\r
+    private BufferedServletOutputStream bufferedServletOut = new BufferedServletOutputStream( );\r
+    private PrintWriter printWriter = null;\r
+    private ServletOutputStream outputStream = null;\r
+\r
+    public ResponseWrapper(HttpServletResponse origResponse) {\r
+        super(origResponse);\r
+    }\r
+\r
+    public String getResponseAsString(){\r
+        return bufferedServletOut.getAsString();\r
+    }\r
+\r
+    public byte[] getBuffer( ) {\r
+        return this.bufferedServletOut.getBuffer( );\r
+    }\r
+\r
+    public PrintWriter getWriter( ) throws IOException {\r
+        if (this.outputStream != null) {\r
+            throw new IllegalStateException(\r
+                    "The Servlet API forbids calling getWriter( ) after"\r
+                    + " getOutputStream( ) has been called");\r
+        }\r
+\r
+        if (this.printWriter == null) {\r
+            this.printWriter = new PrintWriter(this.bufferedServletOut);\r
+        }\r
+        return this.printWriter;\r
+    }\r
+\r
+    public ServletOutputStream getOutputStream( ) throws IOException {\r
+        if (this.printWriter != null) {\r
+            throw new IllegalStateException(\r
+                "The Servlet API forbids calling getOutputStream( ) after"\r
+                + " getWriter( ) has been called");\r
+        }\r
+\r
+        if (this.outputStream == null) {\r
+            this.outputStream = this.bufferedServletOut;\r
+        }\r
+        return this.outputStream;\r
+    }\r
+\r
+    // override methods that deal with the response buffer\r
+\r
+    public void flushBuffer( ) throws IOException {\r
+        if (this.outputStream != null) {\r
+            this.outputStream.flush( );\r
+        } else if (this.printWriter != null) {\r
+            this.printWriter.flush( );\r
+        }\r
+    }\r
+\r
+    public int getBufferSize( ) {\r
+        return this.bufferedServletOut.getBuffer( ).length;\r
+    }\r
+\r
+    public void reset( ) {\r
+        this.bufferedServletOut.reset( );\r
+    }\r
+\r
+    public void resetBuffer( ) {\r
+        this.bufferedServletOut.reset( );\r
+    }\r
+\r
+    public void setBufferSize(int size) {\r
+        this.bufferedServletOut.setBufferSize(size);\r
+    }\r
+}\r
+*/
\ No newline at end of file