
Author: ceki Date: Tue Mar 27 20:05:05 2007 New Revision: 1466 Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java Log: Significantly more robust TeeFilter. This version does not barf - on images, css files etc. - application/x-www-form-urlencoded requests If the request is application/x-www-form-urlencoded, TeeFilter attempts to recreate the input altough it might be able to do so only approximately Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/Constants.java Tue Mar 27 20:05:05 2007 @@ -3,4 +3,6 @@ public class Constants { public static final String LB_INPUT_BUFFER = "LB_INPUT_BUFFER"; public static final String LB_OUTPUT_BUFFER = "LB_OUTPUT_BUFFER"; + + public final static String X_WWW_FORM_URLECODED = "application/x-www-form-urlencoded"; } Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletRequest.java Tue Mar 27 20:05:05 2007 @@ -19,27 +19,51 @@ private TeeServletInputStream inStream; private BufferedReader reader; + boolean postedParametersMode = false; TeeHttpServletRequest(HttpServletRequest request) { super(request); - inStream = new TeeServletInputStream(request); - // add the contents of the input buffer as an attribute of the request in byte[] format - request.setAttribute(Constants.LB_INPUT_BUFFER, inStream.getInputBuffer()); - reader = new BufferedReader(new InputStreamReader(inStream)); + if (Util.isFormUrlEncoded(request)) { + postedParametersMode = true; + } else { + inStream = new TeeServletInputStream(request); + // add the contents of the input buffer as an attribute of the request + request + .setAttribute(Constants.LB_INPUT_BUFFER, inStream.getInputBuffer()); + reader = new BufferedReader(new InputStreamReader(inStream)); + } + } - + byte[] getInputBuffer() { + if (postedParametersMode) { + throw new IllegalStateException("Call disallowed in postedParametersMode"); + } return inStream.getInputBuffer(); } @Override public ServletInputStream getInputStream() throws IOException { - return inStream; + if (!postedParametersMode) { + return inStream; + } else { + return super.getInputStream(); + } } + // + @Override public BufferedReader getReader() throws IOException { - return reader; + if (!postedParametersMode) { + return reader; + } else { + return super.getReader(); + } } - + + public boolean isPostedParametersMode() { + return postedParametersMode; + } + } Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeHttpServletResponse.java Tue Mar 27 20:05:05 2007 @@ -15,7 +15,6 @@ public TeeHttpServletResponse(HttpServletResponse httpServletResponse) { super(httpServletResponse); - // System.out.println("TeeHttpServletResponse.constructor called"); } @Override @@ -28,7 +27,6 @@ @Override public PrintWriter getWriter() throws IOException { - // System.out.println("TeeHttpServletResponse.getWriter() called"); if (this.writer == null) { this.writer = new PrintWriter(new OutputStreamWriter(getOutputStream()), true); @@ -38,14 +36,14 @@ @Override public void flushBuffer() { - // System.out.println("TeeHttpServletResponse.flushBuffer() called"); - if(this.writer != null) { + if (this.writer != null) { this.writer.flush(); } } byte[] getOutputBuffer() { - // teeServletOutputStream can be null if the getOutputStream method is never called. + // teeServletOutputStream can be null if the getOutputStream method is never + // called. if (teeServletOutputStream != null) { return teeServletOutputStream.getOutputBuffer(); } else { Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletInputStream.java Tue Mar 27 20:05:05 2007 @@ -19,6 +19,7 @@ @Override public int read() throws IOException { + System.out.println("zzzzzzzzzz TeeServletInputStream.read called"); return in.read(); } @@ -35,7 +36,7 @@ while ((n = originalSIS.read(inputBuffer, 0, len)) != -1) { baos.write(inputBuffer, 0, n); } - this.in = new ByteArrayInputStream(inputBuffer); + this.in = new ByteArrayInputStream(inputBuffer); originalSIS.close(); } } catch (IOException e) { Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/TeeServletOutputStream.java Tue Mar 27 20:05:05 2007 @@ -15,11 +15,6 @@ throws IOException { // System.out.println("TeeServletOutputStream.constructor() called"); this.underlyingStream = httpServletResponse.getOutputStream(); - if (underlyingStream == null) { - System.out.println("XXXXX underlyingStream == null"); - } else { - System.out.println("XXXXX underlyingStream != null"); - } baos = new ByteArrayOutputStream(); } @@ -29,8 +24,6 @@ @Override public void write(int val) throws IOException { - // System.out.println("XXXXXXXXXXXWRITE TeeServletOutputStream.write(int) - // called"); if (underlyingStream != null) { underlyingStream.write(val); baos.write(val); @@ -69,7 +62,6 @@ } public void finish() throws IOException { - // System.out.println("FINISH TeeServletOutputStream.close() called"); flush(); underlyingStream.close(); baos.close(); Added: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java ============================================================================== --- (empty file) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/servlet/Util.java Tue Mar 27 20:05:05 2007 @@ -0,0 +1,17 @@ +package ch.qos.logback.access.servlet; + +import javax.servlet.http.HttpServletRequest; + +import ch.qos.logback.access.Constants; + +public class Util { + + public static boolean isFormUrlEncoded(HttpServletRequest request) { + if ("POST".equals(request.getMethod()) + && Constants.X_WWW_FORM_URLECODED.equals(request.getContentType())) { + return true; + } else { + return false; + } + } +} Modified: logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java ============================================================================== --- logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java (original) +++ logback/trunk/logback-access/src/main/java/ch/qos/logback/access/spi/AccessEvent.java Tue Mar 27 20:05:05 2007 @@ -12,6 +12,7 @@ import ch.qos.logback.access.Constants; import ch.qos.logback.access.pattern.AccessConverter; +import ch.qos.logback.access.servlet.Util; /** * The Access module's internal representation of logging events. When the @@ -43,7 +44,7 @@ String serverName; String requestContent; String responseContent; - + Map<String, String> requestHeaderMap; Map<String, Object> requestParameterMap; @@ -252,7 +253,7 @@ public List<String> getResponseHeaderNameList() { return serverAdapter.getResponseHeaderNameList(); } - + /** * Attributes are not serialized * @@ -321,19 +322,55 @@ return statusCode; } + @SuppressWarnings("unchecked") public String getRequestContent() { if (requestContent != null) { return requestContent; } - // retreive the byte array placed by TeeFilter - byte[] inputBuffer = (byte[]) httpRequest.getAttribute(Constants.LB_INPUT_BUFFER); - if (inputBuffer != null) { - requestContent = new String(inputBuffer); - } + if (Util.isFormUrlEncoded(httpRequest)) { + StringBuffer buf = new StringBuffer(); + + Enumeration pramEnumeration = httpRequest.getParameterNames(); + + // example: id=1234&user=cgu + // number=1233&x=1 + int count = 0; + try { + while(pramEnumeration.hasMoreElements()) { + + + String key = (String) pramEnumeration.nextElement(); + if (count++ != 0) { + buf.append("&"); + } + buf.append(key); + buf.append("="); + String val = httpRequest.getParameter(key); + if(val != null) { + buf.append(val); + } else { + buf.append(""); + } + } + } catch (Exception e) { + // FIXME Why is try/catch required? + e.printStackTrace(); + } + requestContent = buf.toString(); + } else { - if (requestContent == null || requestContent.length() == 0) { - requestContent = EMPTY; + // retreive the byte array placed by TeeFilter + byte[] inputBuffer = (byte[]) httpRequest + .getAttribute(Constants.LB_INPUT_BUFFER); + + if (inputBuffer != null) { + requestContent = new String(inputBuffer); + } + + if (requestContent == null || requestContent.length() == 0) { + requestContent = EMPTY; + } } return requestContent; @@ -344,7 +381,8 @@ return responseContent; } // retreive the byte array previously placed by TeeFilter - byte[] outputBuffer = (byte[]) httpRequest.getAttribute(Constants.LB_OUTPUT_BUFFER); + byte[] outputBuffer = (byte[]) httpRequest + .getAttribute(Constants.LB_OUTPUT_BUFFER); if (outputBuffer != null) { responseContent = new String(outputBuffer); @@ -356,6 +394,7 @@ return responseContent; } + public int getLocalPort() { if (localPort == SENTINEL) { if (httpRequest != null) {