Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimone Bordet2015-12-08 21:10:27 +0000
committerSimone Bordet2015-12-08 21:10:27 +0000
commit1693dd135d70b892da51a6a810e1a7379a64067e (patch)
tree4bf57cff5f8d018aa8f2fcd098f8f7c430f26c0b
parent657b570716b80cc7d62adfb7a45ac7782de08572 (diff)
downloadorg.eclipse.jetty.project-1693dd135d70b892da51a6a810e1a7379a64067e.tar.gz
org.eclipse.jetty.project-1693dd135d70b892da51a6a810e1a7379a64067e.tar.xz
org.eclipse.jetty.project-1693dd135d70b892da51a6a810e1a7379a64067e.zip
483857 - jetty-client onComplete isn't called in case of exception in GZIPContentDecoder.
Fixed by catching the exceptions and failing the callbacks. Also using return values from HttpReceiver to compute what to return to the parser.
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java41
-rw-r--r--jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java22
-rw-r--r--jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java35
-rw-r--r--jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java7
-rw-r--r--jetty-util/src/main/java/org/eclipse/jetty/util/CompletableCallback.java8
5 files changed, 82 insertions, 31 deletions
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
index deb6069e52..6c63293275 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/HttpReceiver.java
@@ -323,27 +323,34 @@ public abstract class HttpReceiver
}
else
{
- List<ByteBuffer> decodeds = new ArrayList<>(2);
- while (buffer.hasRemaining())
+ try
{
- ByteBuffer decoded = decoder.decode(buffer);
- if (!decoded.hasRemaining())
- continue;
- decodeds.add(decoded);
- if (LOG.isDebugEnabled())
- LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded));
- }
+ List<ByteBuffer> decodeds = new ArrayList<>(2);
+ while (buffer.hasRemaining())
+ {
+ ByteBuffer decoded = decoder.decode(buffer);
+ if (!decoded.hasRemaining())
+ continue;
+ decodeds.add(decoded);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded));
+ }
- if (decodeds.isEmpty())
- {
- callback.succeeded();
+ if (decodeds.isEmpty())
+ {
+ callback.succeeded();
+ }
+ else
+ {
+ int size = decodeds.size();
+ CountingCallback counter = new CountingCallback(callback, size);
+ for (int i = 0; i < size; ++i)
+ notifier.notifyContent(listeners, response, decodeds.get(i), counter);
+ }
}
- else
+ catch (Throwable x)
{
- int size = decodeds.size();
- CountingCallback counter = new CountingCallback(callback, size);
- for (int i = 0; i < size; ++i)
- notifier.notifyContent(listeners, response, decodeds.get(i), counter);
+ callback.failed(x);
}
}
diff --git a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
index d4d037844b..02b6c37f0f 100644
--- a/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
+++ b/jetty-client/src/main/java/org/eclipse/jetty/client/http/HttpReceiverOverHTTP.java
@@ -205,8 +205,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
parser.setHeadResponse(HttpMethod.HEAD.is(method) || HttpMethod.CONNECT.is(method));
exchange.getResponse().version(version).status(status).reason(reason);
- responseBegin(exchange);
- return false;
+ return !responseBegin(exchange);
}
@Override
@@ -216,8 +215,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
if (exchange == null)
return false;
- responseHeader(exchange, field);
- return false;
+ return !responseHeader(exchange, field);
}
@Override
@@ -227,8 +225,7 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
if (exchange == null)
return false;
- responseHeaders(exchange);
- return false;
+ return !responseHeaders(exchange);
}
@Override
@@ -253,17 +250,20 @@ public class HttpReceiverOverHTTP extends HttpReceiver implements HttpParser.Res
failAndClose(x);
}
};
- responseContent(exchange, buffer, callback);
- return callback.tryComplete();
+ // Do not short circuit these calls.
+ boolean proceed = responseContent(exchange, buffer, callback);
+ boolean async = callback.tryComplete();
+ return !proceed || async;
}
@Override
public boolean messageComplete()
{
HttpExchange exchange = getHttpExchange();
- if (exchange != null)
- responseSuccess(exchange);
- return false;
+ if (exchange == null)
+ return false;
+
+ return !responseSuccess(exchange);
}
@Override
diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
index bd45bb8201..d348c6cea3 100644
--- a/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
+++ b/jetty-client/src/test/java/org/eclipse/jetty/client/HttpClientGZIPTest.java
@@ -22,14 +22,18 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.zip.GZIPOutputStream;
+
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.client.api.ContentResponse;
+import org.eclipse.jetty.client.api.Response;
+import org.eclipse.jetty.client.api.Result;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
@@ -195,6 +199,37 @@ public class HttpClientGZIPTest extends AbstractHttpClientServerTest
Assert.assertArrayEquals(data, response.getContent());
}
+ @Test
+ public void testGZIPContentCorrupted() throws Exception
+ {
+ start(new AbstractHandler()
+ {
+ @Override
+ public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ baseRequest.setHandled(true);
+ response.setHeader("Content-Encoding", "gzip");
+ // Not gzipped, will cause the client to blow up.
+ response.getOutputStream().print("0123456789");
+ }
+ });
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ client.newRequest("localhost", connector.getLocalPort())
+ .scheme(scheme)
+ .send(new Response.CompleteListener()
+ {
+ @Override
+ public void onComplete(Result result)
+ {
+ if (result.isFailed())
+ latch.countDown();
+ }
+ });
+
+ Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
+ }
+
private static void sleep(long ms) throws IOException
{
try
diff --git a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
index 8d7c224da9..e68999c4c3 100644
--- a/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
+++ b/jetty-fcgi/fcgi-client/src/main/java/org/eclipse/jetty/fcgi/client/http/HttpConnectionOverFCGI.java
@@ -377,9 +377,10 @@ public class HttpConnectionOverFCGI extends AbstractConnection implements Connec
close(x);
}
};
- if (!channel.content(buffer, callback))
- return true;
- return callback.tryComplete();
+ // Do not short circuit these calls.
+ boolean proceed = channel.content(buffer, callback);
+ boolean async = callback.tryComplete();
+ return !proceed || async;
}
else
{
diff --git a/jetty-util/src/main/java/org/eclipse/jetty/util/CompletableCallback.java b/jetty-util/src/main/java/org/eclipse/jetty/util/CompletableCallback.java
index 1020bb6267..5c401341dc 100644
--- a/jetty-util/src/main/java/org/eclipse/jetty/util/CompletableCallback.java
+++ b/jetty-util/src/main/java/org/eclipse/jetty/util/CompletableCallback.java
@@ -82,6 +82,10 @@ public abstract class CompletableCallback implements Callback
}
break;
}
+ case FAILED:
+ {
+ return;
+ }
default:
{
throw new IllegalStateException(current.toString());
@@ -108,6 +112,10 @@ public abstract class CompletableCallback implements Callback
}
break;
}
+ case FAILED:
+ {
+ return;
+ }
default:
{
throw new IllegalStateException(current.toString());

Back to the top