From a3f6bdad22b65a9b2889daeb46f7378a33b1abef Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Fri, 6 Dec 2024 10:55:24 +1100 Subject: [PATCH] Fixed #12603 Errors logged after cross context dispatch Fixed #12603 Errors logged after cross context dispatch: + Update bytes written in HttpOutput when bypassed by optimization + abort if error dispatch throws --- .../org/eclipse/jetty/ee10/servlet/HttpOutput.java | 9 +++++++++ .../jetty/ee10/servlet/ServletCoreResponse.java | 2 ++ .../org/eclipse/jetty/ee9/nested/HttpChannel.java | 12 +----------- .../org/eclipse/jetty/ee9/nested/HttpOutput.java | 9 +++++++++ .../jetty/ee9/nested/ServletCoreResponse.java | 8 +++++++- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java index 41e9624feab9..92f44e75a4da 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/HttpOutput.java @@ -176,6 +176,15 @@ public long getWritten() return _written; } + /** + * Used by ServletCoreResponse when it bypasses HttpOutput to update bytes written. + * @param written The bytes written + */ + void addBytesWritten(int written) + { + _written += written; + } + public void reopen() { try (AutoLock l = _channelState.lock()) diff --git a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletCoreResponse.java b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletCoreResponse.java index 7150cb2fa44f..2a370924711f 100644 --- a/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletCoreResponse.java +++ b/jetty-ee10/jetty-ee10-servlet/src/main/java/org/eclipse/jetty/ee10/servlet/ServletCoreResponse.java @@ -138,6 +138,8 @@ public void write(boolean last, ByteBuffer byteBuffer, Callback callback) { if (!_wrapped && !_servletContextResponse.isWritingOrStreaming()) { + // We can bypass the HttpOutput stream, but we need to update its bytes written + _servletContextResponse.getHttpOutput().addBytesWritten(byteBuffer.remaining()); _servletContextResponse.write(last, byteBuffer, callback); } else diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java index a3bf32c67fd5..7820d8cd6095 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpChannel.java @@ -56,7 +56,6 @@ import org.eclipse.jetty.server.Server; import org.eclipse.jetty.util.BufferUtil; import org.eclipse.jetty.util.Callback; -import org.eclipse.jetty.util.ExceptionUtil; import org.eclipse.jetty.util.HostPort; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.SharedBlockingCallback.Blocker; @@ -561,16 +560,7 @@ public boolean handle() { if (LOG.isDebugEnabled()) LOG.debug("Could not perform ERROR dispatch, aborting", x); - try - { - _response.resetContent(); - sendResponseAndComplete(); - } - catch (Throwable t) - { - ExceptionUtil.addSuppressedIfNotAssociated(x, t); - throw x; - } + abort(x); } finally { diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java index e4849605b04a..52e5b0f09890 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/HttpOutput.java @@ -241,6 +241,15 @@ public long getWritten() return _written; } + /** + * Used by ServletCoreResponse when it bypasses HttpOutput to update bytes written. + * @param written The bytes written + */ + void addBytesWritten(int written) + { + _written += written; + } + public void reopen() { try (AutoLock l = _channelState.lock()) diff --git a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletCoreResponse.java b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletCoreResponse.java index 0f02b0757f32..69ae41f0f780 100644 --- a/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletCoreResponse.java +++ b/jetty-ee9/jetty-ee9-nested/src/main/java/org/eclipse/jetty/ee9/nested/ServletCoreResponse.java @@ -139,10 +139,13 @@ public void write(boolean last, ByteBuffer byteBuffer, Callback callback) { if (!_wrapped && !_baseResponse.isWritingOrStreaming()) { + // We can bypass the HttpOutput stream, but we need to update its bytes written + _baseResponse.getHttpOutput().addBytesWritten(byteBuffer.remaining()); _coreResponse.write(last, byteBuffer, callback); } else { + // Write the byteBuffer via the HttpOutput stream or writer wrapping the stream if (BufferUtil.hasContent(byteBuffer)) { if (isWriting()) @@ -333,7 +336,10 @@ public Mutable add(HttpHeader header, String value) @Override public Mutable add(HttpField field) { - _response.addHeader(field.getName(), field.getValue()); + if (field.getHeader() == HttpHeader.CONTENT_LENGTH) + _response.setContentLengthLong(field.getLongValue()); + else + _response.addHeader(field.getName(), field.getValue()); return this; }