You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Charlie Read <ch...@beebell.com> on 2014/02/26 22:01:28 UTC

error: "Stream closed"; interceptor logs request-body content; CachedOutputStream

See code below.  This logic _works_ in that it does extract the
request-body.
The problem is that further downstream the marshaling phase fails with this
message:  "Stream closed".

I have modeled my code after the standard LoggingInterceptor from CXF.
Can anyone explain why the marshaling phase is getting a closed stream,
and how to resolve that error?

Thanks!
Charlie

    private String extractRequestBody(Message message, HttpServletRequest
request)
            throws WebApplicationException {

        log.info("Inside TraceApiCall.extractRequestBody");
        String requestBody = null;
        if (request.getContentLength() > 0) {
            log.info("Inside TraceApiCall.extractRequestBody: body is
non-empty");
            try {
                InputStream is = request.getInputStream();
                if (is != null) {
                    log.info("Inside TraceApiCall.extractRequestBody:
processing input stream");
                    CachedOutputStream cos = new CachedOutputStream();
                    IOUtils.copy(is, cos);
                    cos.flush();
                    is.close();
                    message.setContent(InputStream.class,
cos.getInputStream());

                    byte[] b = cos.getBytes();
                    if (b != null) {
                        requestBody = new String(b, 0, b.length);
                    }
                    cos.close();
                }
            } catch (IOException ioe) {
                throw new WebApplicationException(ioe);
            }
        }
        return requestBody;
    }

    public TraceApiCall() {
        super(Phase.RECEIVE);
    }

    public void handleMessage(Message message) throws Fault {
        log.info("Inside TraceApiCall.handleMessage");
        HttpServletRequest request = (HttpServletRequest)
message.get(AbstractHTTPDestination.HTTP_REQUEST);
        log.info("TraceApiCall.handleMessage; request: " +
ServiceUtils.prettyPrintRequest(request));
        String requestBody = extractRequestBody(message, request);
        ....
    }

Re: error: "Stream closed"; interceptor logs request-body content; CachedOutputStream

Posted by Sergey Beryozkin <sb...@gmail.com>.
We have many tests where LoggingInInterceptor logs POST payloads and the 
endpoints or follow-up interceptors get the payload if needed

Cheers, Sergey
On 27/02/14 14:11, charlie wrote:
> I copied LoggingInInterceptor verbatim into my project,
> renamed it, and triggered the logging() method on a
> POST with a non-empty body / content.
>
> The same bug occurred -- namely, that in one of the
> downstream phases (I believe the marshaling phase),
> the stream for Message is found to be closed.
>
> This suggests to me that the bug is in CXF; again,
> I am using milestone1.
>
> Charlie
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/error-Stream-closed-interceptor-logs-request-body-content-CachedOutputStream-tp5740545p5740580.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>



Re: error: "Stream closed"; interceptor logs request-body content; CachedOutputStream

Posted by charlie <ch...@beebell.com>.
I copied LoggingInInterceptor verbatim into my project,
renamed it, and triggered the logging() method on a
POST with a non-empty body / content.

The same bug occurred -- namely, that in one of the
downstream phases (I believe the marshaling phase),
the stream for Message is found to be closed.

This suggests to me that the bug is in CXF; again,
I am using milestone1.

Charlie



--
View this message in context: http://cxf.547215.n5.nabble.com/error-Stream-closed-interceptor-logs-request-body-content-CachedOutputStream-tp5740545p5740580.html
Sent from the cxf-user mailing list archive at Nabble.com.

Re: error: "Stream closed"; interceptor logs request-body content; CachedOutputStream

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi, I guess the only way to trace the problem is closely compare your 
logic with LoggingInInterceptor one and try to find out which part of 
your code causes the side-effects...

Cheers, Sergey
On 27/02/14 00:34, charlie wrote:
> I did some further research on this issue.  Note:  I am using CXF
> 3.0.0-milestone1.
>
> In milestone1 release, LoggingInInterceptor checks for a
> DelegatingInputStream; see below.
> But using similar logic in my interceptor also leads to the "Stream closed"
> error.
>
> It appears in my configuration, the DelegatingInputStream
> is not markable (ie, markSupported() returns false), so the
> InputStream.reset() option is not available.
>
> I also tried calling DelegatingInputStream.cacheInput(), to see if caching
> the input would
> circumvent the "Stream closed" error.  That did not help.
>
> Lastly, I do have an input-validation-interceptor that runs during the
> INVOKE phase, I believe;
> commenting out that validation-interceptor in the application-context
> configuration had no effect.
>
> Why is the input stream on the Message not being kept open after I reset it
> (ie, call Message.setContent) ?
>
> Thanks!
> Charlie
>
>   148         InputStream is = message.getContent(InputStream.class);
>   149         if (is != null) {
>   150             CachedOutputStream bos = new CachedOutputStream();
>   151             if (threshold > 0) {
>   152                 bos.setThreshold(threshold);
>   153             }
>   154             try {
>   155                 // use the appropriate input stream and restore it
> later
>   156                 InputStream bis = is instanceof DelegatingInputStream
>   157                     ? ((DelegatingInputStream)is).getInputStream() :
> is;
>   158
>   159                 IOUtils.copyAndCloseInput(bis, bos);
>   160                 bos.flush();
>   161                 bis = bos.getInputStream();
>   162
>   163                 // restore the delegating input stream or the input
> stream
>   164                 if (is instanceof DelegatingInputStream) {
>   165                     ((DelegatingInputStream)is).setInputStream(bis);
>   166                 } else {
>   167                     message.setContent(InputStream.class, bis);
>   168                 }
>   169
>   170                 if (bos.getTempFile() != null) {
>   171                     //large thing on disk...
>   172                     buffer.getMessage().append("\nMessage (saved to tmp
> file):\n");
>   173                     buffer.getMessage().append("Filename: " +
> bos.getTempFile().getAbsolutePath() + "\n");
>   174                 }
>   175                 if (bos.size() > limit) {
>   176                     buffer.getMessage().append("(message truncated to "
> + limit + " bytes)\n");
>   177                 }
>   178                 writePayload(buffer.getPayload(), bos, encoding, ct);
>   179
>   180                 bos.close();
>   181             } catch (Exception e) {
>   182                 throw new Fault(e);
>   183             }
>
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/error-Stream-closed-interceptor-logs-request-body-content-CachedOutputStream-tp5740545p5740554.html
> Sent from the cxf-user mailing list archive at Nabble.com.
>


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com

Re: error: "Stream closed"; interceptor logs request-body content; CachedOutputStream

Posted by charlie <ch...@beebell.com>.
I did some further research on this issue.  Note:  I am using CXF
3.0.0-milestone1.

In milestone1 release, LoggingInInterceptor checks for a
DelegatingInputStream; see below.
But using similar logic in my interceptor also leads to the "Stream closed"
error.

It appears in my configuration, the DelegatingInputStream
is not markable (ie, markSupported() returns false), so the
InputStream.reset() option is not available.

I also tried calling DelegatingInputStream.cacheInput(), to see if caching
the input would
circumvent the "Stream closed" error.  That did not help.  

Lastly, I do have an input-validation-interceptor that runs during the
INVOKE phase, I believe;
commenting out that validation-interceptor in the application-context
configuration had no effect.

Why is the input stream on the Message not being kept open after I reset it
(ie, call Message.setContent) ?

Thanks!
Charlie

 148         InputStream is = message.getContent(InputStream.class);
 149         if (is != null) {
 150             CachedOutputStream bos = new CachedOutputStream();
 151             if (threshold > 0) {
 152                 bos.setThreshold(threshold);
 153             }
 154             try {
 155                 // use the appropriate input stream and restore it
later
 156                 InputStream bis = is instanceof DelegatingInputStream 
 157                     ? ((DelegatingInputStream)is).getInputStream() :
is;
 158                 
 159                 IOUtils.copyAndCloseInput(bis, bos);
 160                 bos.flush();
 161                 bis = bos.getInputStream();
 162                 
 163                 // restore the delegating input stream or the input
stream
 164                 if (is instanceof DelegatingInputStream) {
 165                     ((DelegatingInputStream)is).setInputStream(bis);
 166                 } else {
 167                     message.setContent(InputStream.class, bis);
 168                 }
 169 
 170                 if (bos.getTempFile() != null) {
 171                     //large thing on disk...
 172                     buffer.getMessage().append("\nMessage (saved to tmp
file):\n");
 173                     buffer.getMessage().append("Filename: " +
bos.getTempFile().getAbsolutePath() + "\n");
 174                 }
 175                 if (bos.size() > limit) {
 176                     buffer.getMessage().append("(message truncated to "
+ limit + " bytes)\n");
 177                 }
 178                 writePayload(buffer.getPayload(), bos, encoding, ct); 
 179                     
 180                 bos.close();
 181             } catch (Exception e) {
 182                 throw new Fault(e);
 183             }



--
View this message in context: http://cxf.547215.n5.nabble.com/error-Stream-closed-interceptor-logs-request-body-content-CachedOutputStream-tp5740545p5740554.html
Sent from the cxf-user mailing list archive at Nabble.com.