Skip to content

Commit

Permalink
Merge pull request #3006 from jamezp/RESTEASY-3072-5.0
Browse files Browse the repository at this point in the history
[RESTEASY-3072] Retrieving the output stream needs to be deferred.
  • Loading branch information
jamezp committed Jan 7, 2022
2 parents 088889b + 8d83fb7 commit 69cf4a8
Showing 1 changed file with 30 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -147,42 +147,41 @@ public boolean suppressExceptionDuringChunkedTransfer() {
*/
protected class DeferredOutputStream extends AsyncOutputStream implements WriteListener
{
private final ServletOutputStream out;
// Guarded by this
private final Queue<AsyncOperation> asyncQueue;
private final AtomicBoolean asyncRegistered;
// Guarded by this
private AsyncOperation lastAsyncOperation;
private volatile boolean asyncListenerCalled;
private volatile ServletOutputStream lazyOut;

DeferredOutputStream() throws IOException {
asyncQueue = new LinkedList<>();
out = response.getOutputStream();
asyncRegistered = new AtomicBoolean();
}

@Override
public void write(int i) throws IOException
{
out.write(i);
getServletOutputStream().write(i);
}

@Override
public void write(byte[] bytes) throws IOException
{
out.write(bytes);
getServletOutputStream().write(bytes);
}

@Override
public void write(byte[] bytes, int i, int i1) throws IOException
{
out.write(bytes, i, i1);
getServletOutputStream().write(bytes, i, i1);
}

@Override
public void flush() throws IOException
{
out.flush();
getServletOutputStream().flush();
}

@Override
Expand Down Expand Up @@ -213,6 +212,13 @@ private void queue(AsyncOperation op)
HttpRequest resteasyRequest = (HttpRequest) contextDataMap.get(HttpRequest.class);
if(request.isAsyncStarted() && !resteasyRequest.getAsyncContext().isOnInitialRequest()) {
boolean flush = false;
final ServletOutputStream out;
try {
out = getServletOutputStream();
} catch (IOException e) {
op.future.completeExceptionally(e);
return;
}
if (asyncRegistered.compareAndSet(false, true)) {
out.setWriteListener(this);
}
Expand Down Expand Up @@ -246,7 +252,13 @@ private void flushQueue()
}
lastAsyncOperation = null;
}

final ServletOutputStream out;
try {
out = getServletOutputStream();
} catch (IOException e) {
onError(e);
return;
}
while (out.isReady() && (lastAsyncOperation = asyncQueue.poll()) != null) {
lastAsyncOperation.work(out);
}
Expand Down Expand Up @@ -275,6 +287,17 @@ public void onError(Throwable t)
}
}
}

private ServletOutputStream getServletOutputStream() throws IOException {
if (lazyOut == null) {
synchronized (this) {
if (lazyOut == null) {
lazyOut = response.getOutputStream();
}
}
}
return lazyOut;
}
}

public HttpServletResponseWrapper(final HttpServletResponse response, final HttpServletRequest request, final ResteasyProviderFactory factory)
Expand Down

0 comments on commit 69cf4a8

Please sign in to comment.