Source:
<code>public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback callback) { final Request jettyRequest = translateRequest(jerseyRequest); final ContentProvider entity = getStreamProvider(jerseyRequest); if (entity != null) { jettyRequest.content(entity); } final Throwable[] failure = new Throwable[1]; final ClientResponse[] jerseyResponse = new ClientResponse[1]; try { buildAsyncRequest(jettyRequest) .send(new Response.Listener.Empty() { @Override public void onContent(Response jettyResponse, ByteBuffer content) { jerseyResponse[0] = translateResponse(jerseyRequest, jettyResponse, content); <START> callback.response(jerseyResponse[0]); <END> } @Override public void onFailure(Response response, Throwable t) { failure[0] = t; callback.failure(t); } }); return Futures.immediateFuture(jerseyResponse[0]); } catch (Throwable t) { failure[0] = t; callback.failure(t); } final SettableFuture<Object> errorFuture = SettableFuture.create(); errorFuture.setException(failure[0]); return errorFuture; }</code><technical_language>afraid this is correct. Jetty Response.Listener.onContent(...) invoked multiple times, Jersey AsyncConnectorCallback.response(...) invoked once. [GrizzlyConnector](<LINK_1> is solved in Grizzly async client. A good test if async client support works is [try connector a SSE endpoint](<LINK_0></technical_language>

Target:
public Future<?> apply(final ClientRequest jerseyRequest, final AsyncConnectorCallback callback) { final Request jettyRequest = translateRequest(jerseyRequest); final ContentProvider entity = getStreamProvider(jerseyRequest); if (entity != null) { jettyRequest.content(entity); } final AtomicBoolean callbackInvoked = new AtomicBoolean(false); Throwable failure; try { final SettableFuture<ClientResponse> responseFuture = SettableFuture.create(); Futures.addCallback(responseFuture, new FutureCallback<ClientResponse>() { @Override public void onSuccess(ClientResponse result) { } @Override public void onFailure(Throwable t) { if (t instanceof CancellationException) { jettyRequest.abort(t); } } }); final AtomicReference<ClientResponse> jerseyResponse = new AtomicReference<ClientResponse>(); final ByteBufferInputStream entityStream = new ByteBufferInputStream(); buildAsyncRequest(jettyRequest) .send(new Response.Listener.Empty() { @Override public void onHeaders(Response jettyResponse) { if (responseFuture.isDone()) if (!callbackInvoked.compareAndSet(false, true)) { return; } final ClientResponse response = translateResponse(jerseyRequest, jettyResponse, entityStream); jerseyResponse.set(response); callback.response(response); } @Override public void onContent(Response jettyResponse, ByteBuffer content) { try { entityStream.put(content); } catch (InterruptedException ex) { final ProcessingException pe = new ProcessingException(ex); entityStream.closeQueue(pe); responseFuture.setException(pe); Thread.currentThread().interrupt(); } } @Override public void onComplete(Result result) { entityStream.closeQueue(); responseFuture.set(jerseyResponse.get()); } @Override public void onFailure(Response response, Throwable t) { entityStream.closeQueue(t); responseFuture.setException(t); if (callbackInvoked.compareAndSet(false, true)) { callback.failure(t); } } }); return responseFuture; } catch (Throwable t) { failure = t; } if (callbackInvoked.compareAndSet(false, true)) { callback.failure(failure); } return Futures.immediateFailedFuture(failure); }