private void writeEmptyFin() { if (!isTerminated()) { unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(null, Buffers.EMPTY_BUFFER, new FlushCompletionHandler(null), null, true); } }
assertReady(); response.getHeaders().clear(); unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, false); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, isNoPayload); sendTrailers(completionHandler, messageCloner, (HttpTrailer) httpContent); close(); return; if (reserveWriteQueueSpace(spaceToReserve) > spaceToReserve) { final int fitWindowLen = checkOutputWindow(remaining); final Buffer dataChunkToStore = splitOutputBufferIfNeeded( data, fitWindowLen); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); flushToConnectionOutputSink(headerFrames, dataToSend, flushCompletionHandler, isDataCloned ? null : messageCloner,
if (isWantToWrite() && outputQueue.compareAndSetCurrentElement(outputQueueRecord, null)) { final int fitWindowLen = checkOutputWindow(currentResource.remaining()); final Buffer dataChunkToSend = currentResource.read(fitWindowLen); final int dataChunkToSendSize = dataChunkToSend.remaining(); flushToConnectionOutputSink(null, dataChunkToSend, chunkedCompletionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); releaseWriteQueueSpace(0, true, true); } else if (dataChunkToSend != null && !dataChunkToSend.hasRemaining()) { reserveWriteQueueSpace(outputQueueRecord.resource.remaining()); outputQueue.offer(outputQueueRecord);
while (isWantToWrite() && !outputQueue.isEmpty()) { releaseWriteQueueSpace(0, true, true); writeEmptyFin(); return; final int bytesToSend = checkOutputWindow(resource.remaining()); final Buffer dataChunkToSend = resource.read(bytesToSend); final boolean hasRemaining = resource.hasRemaining(); flushToConnectionOutputSink(null, dataChunkToSend, completionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); } else if (isZeroSizeData && outputQueueRecord == null) { releaseWriteQueueSpace(0, true, true); outputQueue.doNotify();
/** * Closes the output sink by adding last DataFrame with the FIN flag to a queue. * If the output sink is already closed - method does nothing. */ @Override public synchronized void close() { if (!isClosed()) { isLastFrameQueued = true; if (outputQueue.isEmpty()) { writeEmptyFin(); return; } outputQueue.reserveSpace(ZERO_QUEUE_RECORD_SIZE); outputQueue.offer(TERMINATING_QUEUE_RECORD); if (outputQueue.size() == ZERO_QUEUE_RECORD_SIZE && outputQueue.remove(TERMINATING_QUEUE_RECORD)) { writeEmptyFin(); } } }
@Override public boolean isClosed() { return isLastFrameQueued || isTerminated(); }
/** * Create HTTP2 stream. * * @param http2Session the {@link Http2Session} for this {@link Http2Stream}. * @param request the {@link HttpRequestPacket} initiating the stream. * @param streamId this stream's ID. * @param parentStreamId the parent stream, if any. * @param priority the priority of this stream. */ protected Http2Stream(final Http2Session http2Session, final HttpRequestPacket request, final int streamId, final int parentStreamId, final boolean exclusive, final int priority) { this.http2Session = http2Session; this.request = request; this.streamId = streamId; this.parentStreamId = parentStreamId; this.exclusive = exclusive; this.priority = priority; this.state = State.IDLE; inputBuffer = new DefaultInputBuffer(this); outputSink = new DefaultOutputSink(this); HTTP_RQST_HTTP2_STREAM_ATTR.set(request, this); }
private void sendTrailers(final CompletionHandler<WriteResult> completionHandler, final MessageCloner<Buffer> messageCloner, final HttpTrailer httpContent) throws IOException { http2Session.getDeflaterLock().lock(); final boolean logging = NetLogger.isActive(); final Map<String,String> capture = ((logging) ? new HashMap<>() : null); List<Http2Frame> trailerFrames = http2Session.encodeTrailersAsHeaderFrames(stream.getId(), new ArrayList<>(4), httpContent.getHeaders(), capture); if (logging) { for (Http2Frame http2Frame : trailerFrames) { if (http2Frame.getType() == PushPromiseFrame.TYPE) { NetLogger.log(NetLogger.Context.TX, http2Session, (HeadersFrame) http2Frame, capture); break; } } } unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(trailerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, true); }
assertReady(); response.getHeaders().clear(); unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, false); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, isNoPayload); sendTrailers(completionHandler, messageCloner, (HttpTrailer) httpContent); close(); return; if (reserveWriteQueueSpace(spaceToReserve) > spaceToReserve) { final int fitWindowLen = checkOutputWindow(remaining); final Buffer dataChunkToStore = splitOutputBufferIfNeeded( data, fitWindowLen); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); flushToConnectionOutputSink(headerFrames, dataToSend, flushCompletionHandler, isDataCloned ? null : messageCloner,
if (isWantToWrite() && outputQueue.compareAndSetCurrentElement(outputQueueRecord, null)) { final int fitWindowLen = checkOutputWindow(currentResource.remaining()); final Buffer dataChunkToSend = currentResource.read(fitWindowLen); final int dataChunkToSendSize = dataChunkToSend.remaining(); flushToConnectionOutputSink(null, dataChunkToSend, chunkedCompletionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); releaseWriteQueueSpace(0, true, true); } else if (dataChunkToSend != null && !dataChunkToSend.hasRemaining()) { reserveWriteQueueSpace(outputQueueRecord.resource.remaining()); outputQueue.offer(outputQueueRecord);
while (isWantToWrite() && !outputQueue.isEmpty()) { releaseWriteQueueSpace(0, true, true); writeEmptyFin(); return; final int bytesToSend = checkOutputWindow(resource.remaining()); final Buffer dataChunkToSend = resource.read(bytesToSend); final boolean hasRemaining = resource.hasRemaining(); flushToConnectionOutputSink(null, dataChunkToSend, completionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); } else if (isZeroSizeData && outputQueueRecord == null) { releaseWriteQueueSpace(0, true, true); outputQueue.doNotify();
/** * Closes the output sink by adding last DataFrame with the FIN flag to a queue. * If the output sink is already closed - method does nothing. */ @Override public synchronized void close() { if (!isClosed()) { isLastFrameQueued = true; if (outputQueue.isEmpty()) { writeEmptyFin(); return; } outputQueue.reserveSpace(ZERO_QUEUE_RECORD_SIZE); outputQueue.offer(TERMINATING_QUEUE_RECORD); if (outputQueue.size() == ZERO_QUEUE_RECORD_SIZE && outputQueue.remove(TERMINATING_QUEUE_RECORD)) { writeEmptyFin(); } } }
@Override public boolean isClosed() { return isLastFrameQueued || isTerminated(); }
/** * Create HTTP2 stream. * * @param http2Session the {@link Http2Session} for this {@link Http2Stream}. * @param request the {@link HttpRequestPacket} initiating the stream. * @param streamId this stream's ID. * @param parentStreamId the parent stream, if any. * @param priority the priority of this stream. */ protected Http2Stream(final Http2Session http2Session, final HttpRequestPacket request, final int streamId, final int parentStreamId, final boolean exclusive, final int priority) { this.http2Session = http2Session; this.request = request; this.streamId = streamId; this.parentStreamId = parentStreamId; this.exclusive = exclusive; this.priority = priority; this.state = State.IDLE; inputBuffer = new DefaultInputBuffer(this); outputSink = new DefaultOutputSink(this); HTTP_RQST_HTTP2_STREAM_ATTR.set(request, this); }
private void sendTrailers(final CompletionHandler<WriteResult> completionHandler, final MessageCloner<Buffer> messageCloner, final HttpTrailer httpContent) throws IOException { http2Session.getDeflaterLock().lock(); final boolean logging = NetLogger.isActive(); final Map<String,String> capture = ((logging) ? new HashMap<>() : null); List<Http2Frame> trailerFrames = http2Session.encodeTrailersAsHeaderFrames(stream.getId(), new ArrayList<>(4), httpContent.getHeaders(), capture); if (logging) { for (Http2Frame http2Frame : trailerFrames) { if (http2Frame.getType() == PushPromiseFrame.TYPE) { NetLogger.log(NetLogger.Context.TX, http2Session, (HeadersFrame) http2Frame, capture); break; } } } unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(trailerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, true); }
assertReady(); response.getHeaders().clear(); unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, false); flushToConnectionOutputSink(headerFrames, null, new FlushCompletionHandler(completionHandler), messageCloner, isNoPayload); sendTrailers(completionHandler, messageCloner, (HttpTrailer) httpContent); close(); return; if (reserveWriteQueueSpace(spaceToReserve) > spaceToReserve) { final int fitWindowLen = checkOutputWindow(remaining); final Buffer dataChunkToStore = splitOutputBufferIfNeeded( data, fitWindowLen); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); flushToConnectionOutputSink(headerFrames, dataToSend, flushCompletionHandler, isDataCloned ? null : messageCloner,
if (isWantToWrite() && outputQueue.compareAndSetCurrentElement(outputQueueRecord, null)) { final int fitWindowLen = checkOutputWindow(currentResource.remaining()); final Buffer dataChunkToSend = currentResource.read(fitWindowLen); final int dataChunkToSendSize = dataChunkToSend.remaining(); flushToConnectionOutputSink(null, dataChunkToSend, chunkedCompletionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); releaseWriteQueueSpace(0, true, true); } else if (dataChunkToSend != null && !dataChunkToSend.hasRemaining()) { reserveWriteQueueSpace(outputQueueRecord.resource.remaining()); outputQueue.offer(outputQueueRecord);
while (isWantToWrite() && !outputQueue.isEmpty()) { releaseWriteQueueSpace(0, true, true); writeEmptyFin(); return; final int bytesToSend = checkOutputWindow(resource.remaining()); final Buffer dataChunkToSend = resource.read(bytesToSend); final boolean hasRemaining = resource.hasRemaining(); flushToConnectionOutputSink(null, dataChunkToSend, completionHandler, null, isLast); releaseWriteQueueSpace(dataChunkToSendSize, isZeroSizeData, outputQueueRecord == null); } else if (isZeroSizeData && outputQueueRecord == null) { releaseWriteQueueSpace(0, true, true); outputQueue.doNotify();
private void writeEmptyFin() { if (!isTerminated()) { unflushedWritesCounter.incrementAndGet(); flushToConnectionOutputSink(null, Buffers.EMPTY_BUFFER, new FlushCompletionHandler(null), null, true); } }
/** * Closes the output sink by adding last DataFrame with the FIN flag to a queue. * If the output sink is already closed - method does nothing. */ @Override public synchronized void close() { if (!isClosed()) { isLastFrameQueued = true; if (outputQueue.isEmpty()) { writeEmptyFin(); return; } outputQueue.reserveSpace(ZERO_QUEUE_RECORD_SIZE); outputQueue.offer(TERMINATING_QUEUE_RECORD); if (outputQueue.size() == ZERO_QUEUE_RECORD_SIZE && outputQueue.remove(TERMINATING_QUEUE_RECORD)) { writeEmptyFin(); } } }