[undertow-dev] receiveFullBytes callbacks never called

Oliver Dain oliver at analyticspot.com
Tue May 10 20:54:39 EDT 2016


I've got a case where I can call receiveFullBytes but neither the success
nor the error handler is ever called. My code looks like this:

public static CompletableFuture<ByteSource>
getCompleteBody(HttpServerExchange exchange) {
  log.debug("In getCompleteBody.");
  CompletableFuture<ByteSource> finalResult = new CompletableFuture<>();
  try {
    log.debug("Calling receiveFullBytes.");
    exchange.getRequestReceiver().receiveFullBytes(
        // Success case.
        (HttpServerExchange excng, byte[] bytes) -> {
          log.debug("getFullBytes completed with success.");
          finalResult.complete(ByteSource.wrap(bytes));
        },

        // Error case
        (HttpServerExchange exchng, IOException t) -> {
          log.warn("getFullBytes completed with an error:", t);
          finalResult.completeExceptionally(t);
        }
    );
  } catch (Throwable t) {
    log.warn("receiveFullBytes threw an exception:", t);
    finalResult.completeExceptionally(t);
  }

  return finalResult;
}

I've got a unit test that opens a socket, starts sending data, and
then, intentionally throws an exception. The test then ensures that
the CompletableFuture above completes with an exception. Except, it
never completes.. the test just hangs forever. You can see that the
"log.debug("Calling receiveFullBytes.")" line does get called and that
the neither of the log lines in either callback is ever called. The
full test looks like this:

@Test
public void getCompleteBodyCompletesWithExceptionOnBodyFailure()
throws Exception {
  AtomicBoolean futureRedeemedWithError = new AtomicBoolean(false);
  CountDownLatch waitForInputToFail = new CountDownLatch(1);

  HttpHandler handler = new HttpHandler() {
    @Override
    public void handleRequest(HttpServerExchange exchange) throws Exception {
      log.info("Handler called.");
      exchange.dispatch();
      log.info("Calling getCompleteBody");
      UndertowUtils.getCompleteBody(exchange).exceptionally((Throwable t) -> {
        log.debug("As expected, received an exception:", t);
        futureRedeemedWithError.set(true);
        waitForInputToFail.countDown();
        return null;
      });
    }
  };
  UndertowTestUtils.RunningServer server =
UndertowTestUtils.startUndertowOnFreePort(handler);

  // A Body() implementation that will return a few chunks of data but the fail
  Body failingRequestBody = new Body() {
    private AtomicInteger readCalls = new AtomicInteger(0);
    @Override
    public long getContentLength() {
      return 1000;
    }

    @Override
    public long read(ByteBuffer buffer) throws IOException {
      if (readCalls.getAndIncrement() < 2) {
        byte[] toSend = "some data".getBytes(Charsets.UTF_8);
        buffer.put(toSend);
        return toSend.length;
      } else {
        throw new RuntimeException("Fake error on sending data.");
      }
    }

    @Override
    public void close() throws IOException {
    }
  };

  // A body generator using the above, busted Body.
  BodyGenerator failingBodyGenerator = new BodyGenerator() {
    @Override
    public Body createBody() throws IOException {
      return failingRequestBody;
    }
  };

  // This will start sending data so our handler gets invoked but it
will then fail partway through.
  SimpleAsyncHttpClient client = new SimpleAsyncHttpClient.Builder()
      .setUrl(String.format("http://localhost:%s", server.getPort()))
      .build();

  client.post(failingBodyGenerator);


  // Test hangs here forever
  waitForInputToFail.await();

  assertThat(futureRedeemedWithError.get()).isTrue();
}


This feels like a bug. I'd expect the contract of "receiveFullBytes" to be
that either the success or failure handler gets called exactly once. Is
this a bug? If not, what am I doing wrong?

Thanks,

Oliver

-- 
CTO, Analytic Spot
44 West Broadway #222
Eugene, OR 97401
analyticspot.com • 425-296-6556
www.linkedin.com/in/oliverdain
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/undertow-dev/attachments/20160511/c79efc4e/attachment-0001.html 


More information about the undertow-dev mailing list