Repository: cxf Updated Branches: refs/heads/master 391ab2c46 -> 976e6e6ed
[CXF-5635] Optimize the LoggingInInterceptor to only slurp in "limit" bytes from the InputStream then replay those bytes, then allow the rest to stream like normal. Should prevent very large temp files if logging is on. Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/976e6e6e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/976e6e6e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/976e6e6e Branch: refs/heads/master Commit: 976e6e6edbfeb575c58a7f75f33ca69ea3a5c896 Parents: 391ab2c Author: Daniel Kulp <[email protected]> Authored: Fri Mar 21 19:35:41 2014 -0400 Committer: Daniel Kulp <[email protected]> Committed: Fri Mar 21 20:11:43 2014 -0400 ---------------------------------------------------------------------- .../cxf/interceptor/LoggingInInterceptor.java | 123 +++++++++++-------- 1 file changed, 72 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/976e6e6e/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java b/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java index 9c9b26c..c88cd71 100644 --- a/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java +++ b/core/src/main/java/org/apache/cxf/interceptor/LoggingInInterceptor.java @@ -21,6 +21,7 @@ package org.apache.cxf.interceptor; import java.io.InputStream; import java.io.PrintWriter; import java.io.Reader; +import java.io.SequenceInputStream; import java.util.logging.Level; import java.util.logging.Logger; @@ -147,65 +148,85 @@ public class LoggingInInterceptor extends AbstractLoggingInterceptor { InputStream is = message.getContent(InputStream.class); if (is != null) { - CachedOutputStream bos = new CachedOutputStream(); - if (threshold > 0) { - bos.setThreshold(threshold); - } - try { - // use the appropriate input stream and restore it later - InputStream bis = is instanceof DelegatingInputStream - ? ((DelegatingInputStream)is).getInputStream() : is; - - IOUtils.copyAndCloseInput(bis, bos); - bos.flush(); - bis = bos.getInputStream(); - - // restore the delegating input stream or the input stream - if (is instanceof DelegatingInputStream) { - ((DelegatingInputStream)is).setInputStream(bis); - } else { - message.setContent(InputStream.class, bis); - } - - if (bos.getTempFile() != null) { - //large thing on disk... - buffer.getMessage().append("\nMessage (saved to tmp file):\n"); - buffer.getMessage().append("Filename: " + bos.getTempFile().getAbsolutePath() + "\n"); - } - if (bos.size() > limit) { - buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); - } - writePayload(buffer.getPayload(), bos, encoding, ct); - - bos.close(); - } catch (Exception e) { - throw new Fault(e); - } + logInputStream(message, is, buffer, encoding, ct); } else { Reader reader = message.getContent(Reader.class); if (reader != null) { - try { - CachedWriter writer = new CachedWriter(); - IOUtils.copyAndCloseInput(reader, writer); - message.setContent(Reader.class, writer.getReader()); - - if (writer.getTempFile() != null) { - //large thing on disk... - buffer.getMessage().append("\nMessage (saved to tmp file):\n"); - buffer.getMessage().append("Filename: " + writer.getTempFile().getAbsolutePath() + "\n"); - } - if (writer.size() > limit) { - buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); - } - writer.writeCacheTo(buffer.getPayload(), limit); - } catch (Exception e) { - throw new Fault(e); - } + logReader(message, reader, buffer); } } log(logger, formatLoggingMessage(buffer)); } + protected void logReader(Message message, Reader reader, LoggingMessage buffer) { + try { + CachedWriter writer = new CachedWriter(); + IOUtils.copyAndCloseInput(reader, writer); + message.setContent(Reader.class, writer.getReader()); + + if (writer.getTempFile() != null) { + //large thing on disk... + buffer.getMessage().append("\nMessage (saved to tmp file):\n"); + buffer.getMessage().append("Filename: " + writer.getTempFile().getAbsolutePath() + "\n"); + } + if (writer.size() > limit) { + buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); + } + writer.writeCacheTo(buffer.getPayload(), limit); + } catch (Exception e) { + throw new Fault(e); + } + } + protected void logInputStream(Message message, InputStream is, LoggingMessage buffer, + String encoding, String ct) { + CachedOutputStream bos = new CachedOutputStream(); + if (threshold > 0) { + bos.setThreshold(threshold); + } + try { + // use the appropriate input stream and restore it later + InputStream bis = is instanceof DelegatingInputStream + ? ((DelegatingInputStream)is).getInputStream() : is; + + + //only copy up to the limit since that's all we need to log + //we can stream the rest + byte bytes[] = new byte[2048]; + int i = bis.read(bytes); + int count = 0; + while (count <= limit && i != -1) { + bos.write(bytes, 0, i); + count += i; + i = bis.read(bytes); + } + if (i > 0) { + bos.write(bytes, 0, i); + } + bos.flush(); + bis = new SequenceInputStream(bos.getInputStream(), bis); + + // restore the delegating input stream or the input stream + if (is instanceof DelegatingInputStream) { + ((DelegatingInputStream)is).setInputStream(bis); + } else { + message.setContent(InputStream.class, bis); + } + + if (bos.getTempFile() != null) { + //large thing on disk... + buffer.getMessage().append("\nMessage (saved to tmp file):\n"); + buffer.getMessage().append("Filename: " + bos.getTempFile().getAbsolutePath() + "\n"); + } + if (bos.size() > limit) { + buffer.getMessage().append("(message truncated to " + limit + " bytes)\n"); + } + writePayload(buffer.getPayload(), bos, encoding, ct); + + bos.close(); + } catch (Exception e) { + throw new Fault(e); + } + } protected String formatLoggingMessage(LoggingMessage loggingMessage) {
