@Override public boolean invoke(ClientRequestContext ctx, HttpRequest req, DecodedHttpResponse res) { res.close(ClosedSessionException.get()); return false; }
protected final ChannelFuture newClosedSessionFuture() { return newFailedFuture(ClosedSessionException.get()); }
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { if (res != null) { res.close(ClosedSessionException.get()); } ctx.fireChannelInactive(); }
@Override public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { super.channelUnregistered(ctx); if (req != null) { // Ignored if the stream has already been closed. req.close(ClosedSessionException.get()); } }
@Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { active = false; // Protocol upgrade has failed, but needs to retry. if (needsRetryWithH1C) { assert responseDecoder == null || !responseDecoder.hasUnfinishedResponses(); sessionTimeoutFuture.cancel(false); channelPool.connect(channel.remoteAddress(), H1C, sessionPromise); } else { // Fail all pending responses. failUnfinishedResponses(ClosedSessionException.get()); // Cancel the timeout and reject the sessionPromise just in case the connection has been closed // even before the session protocol negotiation is done. sessionTimeoutFuture.cancel(false); sessionPromise.tryFailure(ClosedSessionException.get()); } }
private void write(HttpObject o, boolean endOfStream, boolean flush) { if (!ch.isActive()) { ReferenceCountUtil.safeRelease(o); fail(ClosedSessionException.get()); return; } if (endOfStream) { state = State.DONE; } write0(o, endOfStream, flush); }
@Override protected void doClose() { if (pendingWritesMap.isEmpty()) { return; } final ClosedSessionException cause = ClosedSessionException.get(); for (Queue<Entry<HttpObject, ChannelPromise>> queue : pendingWritesMap.values()) { for (;;) { final Entry<HttpObject, ChannelPromise> e = queue.poll(); if (e == null) { break; } e.getValue().tryFailure(cause); } } pendingWritesMap.clear(); }
@Override protected ChannelFuture doWriteReset(int id, int streamId, Http2Error error) { // NB: this.minClosedId can be overwritten more than once when 3+ pipelined requests are received // and they are handled by different threads simultaneously. // e.g. when the 3rd request triggers a reset and then the 2nd one triggers another. minClosedId = Math.min(minClosedId, id); for (int i = minClosedId; i <= maxIdWithPendingWrites; i++) { final PendingWrites pendingWrites = pendingWritesMap.remove(i); for (;;) { final Entry<HttpObject, ChannelPromise> e = pendingWrites.poll(); if (e == null) { break; } e.getValue().tryFailure(ClosedSessionException.get()); } } final ChannelFuture f = ch.write(Unpooled.EMPTY_BUFFER); if (currentId >= minClosedId) { f.addListener(ChannelFutureListener.CLOSE); } return f; }
@Override public void onRstStreamRead(ChannelHandlerContext ctx, int streamId, long errorCode) throws Http2Exception { final HttpResponseWrapper res = removeResponse(streamIdToId(streamId)); if (res == null) { if (conn.streamMayHaveExisted(streamId)) { if (logger.isDebugEnabled()) { logger.debug("{} Received a late RST_STREAM frame for a closed stream: {}", ctx.channel(), streamId); } } else { throw connectionError(PROTOCOL_ERROR, "received a RST_STREAM frame for an unknown stream: %d", streamId); } return; } res.close(ClosedSessionException.get()); }
@Override public void onStreamClosed(Http2Stream stream) { goAwayHandler.onStreamClosed(channel, stream); final DecodedHttpRequest req = requests.remove(stream.id()); if (req != null) { // Ignored if the stream has already been closed. req.close(ClosedSessionException.get()); } }
private void cleanup() { if (responseEncoder != null) { responseEncoder.close(); } unfinishedRequests.forEach((req, res) -> { // Mark the request stream as closed due to disconnection. req.close(ClosedSessionException.get()); // XXX(trustin): Should we allow aborting with an exception other than AbortedStreamException? // (ClosedSessionException in this case.) res.abort(); }); }
@Test public void closedIfCancelled() { assertThat(call.isCancelled()).isFalse(); completionFuture.completeExceptionally(ClosedSessionException.get()); await().untilAsserted(() -> assertThat(call.isCancelled()).isTrue()); } }
@Override public void onStreamClosed(Http2Stream stream) { goAwayHandler.onStreamClosed(channel(), stream); final HttpResponseWrapper res = getResponse(streamIdToId(stream.id()), true); if (res == null) { return; } if (!goAwayHandler.receivedGoAway()) { res.close(ClosedSessionException.get()); return; } final int lastStreamId = conn.local().lastStreamKnownByPeer(); if (stream.id() > lastStreamId) { res.close(UnprocessedRequestException.get()); } else { res.close(ClosedSessionException.get()); } // Send a GOAWAY frame if the connection has been scheduled for disconnection and // it did not receive or send a GOAWAY frame. if (needsToDisconnectNow() && !goAwayHandler.sentGoAway() && !goAwayHandler.receivedGoAway()) { channel().close(); } }