Fix JAX-RS filter NPE for empty entities #1909
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In JAX-RS, when Logbook is registered as a response filter, and the response entity is empty, an NPE is thrown.
Same seems to be the case for request filter and an empty request.
Description
The issue was reported to us but marked as not reproducible (see below). However, I could reproduce it here:
https://github.com/msdousti/quarkus-logbook
If you use install this branch to your local Maven, it works as expected. However, if you change
logbook-bom.version
in the above repo to3.9.0
(current Logbook version), and run the test:In the server logs:
Root Cause
LogbookServerFilter#filter
calls response.expose().expose
calls state.buffer(context)buffer
is implemented as follows:logbook/logbook-jaxrs/src/main/java/org/zalando/logbook/jaxrs/LocalResponse.java
Lines 57 to 62 in 05ede67
When the response has no entity, then
context.getEntityStream()
is null. As such,TeeOutputStream
will have anull
stream (called "original"). When original.close is called, an NPE is thrown.The exact same issue happens for Request Filters, when request.expose is called.
Fix
The fix is to call expose methods conditionally, only when the request/response entity exists.The fix is to annotate
origin
inTeeOutputStream
as nullable, and then handle nullability everywhere. Thanks to @kasmarian for the suggestion!Test
The existing tests use
ResourceConfig
(example), and they don't seem to suffer from this issue.Quarkus does not seem to support ResourceConfig, so in my Quarkus project, I used a
@Provider
(see LogbookFilterSetup).I wasn't able to write an automated test to cover this, but the existing tests plus cover for all branches already. Suggestions are welcome.Motivation and Context
Addresses #1384
Types of changes
Checklist: