@Override public void endStream(final List<? extends Header> trailers) throws IOException { ioSession.getLock().lock(); try { if (localEndStream) { return; } localEndStream = true; if (trailers != null && !trailers.isEmpty()) { commitHeaders(id, trailers, true); } else { final RawFrame frame = frameFactory.createData(id, null, true); commitFrameInternal(frame); } } finally { ioSession.getLock().unlock(); } }
public final void onTimeout(final Timeout timeout) throws HttpException, IOException { connState = ConnectionHandshake.SHUTDOWN; final RawFrame goAway; if (localSettingState != SettingsHandshake.ACKED) { goAway = frameFactory.createGoAway(processedRemoteStreamId, H2Error.SETTINGS_TIMEOUT, "Setting timeout (" + timeout + ")"); } else { goAway = frameFactory.createGoAway(processedRemoteStreamId, H2Error.NO_ERROR, "Timeout due to inactivity (" + timeout + ")"); } commitFrame(goAway); for (final Iterator<Map.Entry<Integer, Http2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) { final Map.Entry<Integer, Http2Stream> entry = it.next(); final Http2Stream stream = entry.getValue(); stream.reset(new H2StreamResetException(H2Error.NO_ERROR, "Timeout due to inactivity (" + timeout + ")")); } streamMap.clear(); }
boolean localReset(final int code) throws IOException { ioSession.getLock().lock(); try { if (localEndStream) { return false; } localEndStream = true; deadline = System.currentTimeMillis() + LINGER_TIME; if (!idle) { final RawFrame resetStream = frameFactory.createResetStream(id, code); commitFrameInternal(resetStream); return true; } return false; } finally { ioSession.getLock().unlock(); } }
private void commitHeaders( final int streamId, final List<? extends Header> headers, final boolean endStream) throws IOException { if (streamListener != null) { streamListener.onHeaderOutput(this, streamId, headers); } final ByteArrayBuffer buf = new ByteArrayBuffer(512); hPackEncoder.encodeHeaders(buf, headers); int off = 0; int remaining = buf.length(); boolean continuation = false; while (remaining > 0) { final int chunk = Math.min(remoteConfig.getMaxFrameSize(), remaining); final ByteBuffer payload = ByteBuffer.wrap(buf.array(), off, chunk); remaining -= chunk; off += chunk; final boolean endHeaders = remaining == 0; final RawFrame frame; if (!continuation) { frame = frameFactory.createHeaders(streamId, payload, endHeaders, endStream); continuation = true; } else { frame = frameFactory.createContinuation(streamId, payload, endHeaders); } commitFrameInternal(frame); } }
final RawFrame frame; if (!continuation) { frame = frameFactory.createPushPromise(streamId, payload, endHeaders); continuation = true; } else { frame = frameFactory.createContinuation(streamId, payload, endHeaders);
} else { if (connState.compareTo(ConnectionHandshake.ACTIVE) <= 0) { final RawFrame goAway = frameFactory.createGoAway(processedRemoteStreamId, H2Error.NO_ERROR, "Graceful shutdown"); commitFrame(goAway); connState = streamMap.isEmpty() ? ConnectionHandshake.SHUTDOWN : ConnectionHandshake.GRACEFUL_SHUTDOWN; final AsyncPingHandler handler = pingCommand.getHandler(); pingHandlers.add(handler); final RawFrame ping = frameFactory.createPing(handler.getData()); commitFrame(ping); } else if (command instanceof ExecutableCommand) {
pong.put(ping); pong.flip(); final RawFrame response = frameFactory.createPingAck(pong); commitFrame(response); final RawFrame response = frameFactory.createSettingsAck(); commitFrame(response); remoteSettingState = SettingsHandshake.ACKED;
public final void onConnect(final ByteBuffer prefeed) throws HttpException, IOException { if (prefeed != null) { inputBuffer.put(prefeed); } connState = ConnectionHandshake.ACTIVE; final RawFrame settingsFrame = frameFactory.createSettings( new H2Setting(H2Param.HEADER_TABLE_SIZE, localConfig.getHeaderTableSize()), new H2Setting(H2Param.ENABLE_PUSH, localConfig.isPushEnabled() ? 1 : 0), new H2Setting(H2Param.MAX_CONCURRENT_STREAMS, localConfig.getMaxConcurrentStreams()), new H2Setting(H2Param.INITIAL_WINDOW_SIZE, localConfig.getInitialWindowSize()), new H2Setting(H2Param.MAX_FRAME_SIZE, localConfig.getMaxFrameSize()), new H2Setting(H2Param.MAX_HEADER_LIST_SIZE, localConfig.getMaxHeaderListSize())); commitFrame(settingsFrame); localSettingState = SettingsHandshake.TRANSMITTED; }
public RawFrame createResetStream(final int streamId, final H2Error error) { Args.notNull(error, "Error"); return createResetStream(streamId, error.getCode()); }
private void streamDataFrame( final int streamId, final AtomicInteger streamOutputWindow, final ByteBuffer payload, final int chunk) throws IOException { final RawFrame dataFrame = frameFactory.createData(streamId, payload, false); if (streamListener != null) { streamListener.onFrameOutput(this, streamId, dataFrame); } updateOutputWindow(0, connOutputWindow, -chunk); updateOutputWindow(streamId, streamOutputWindow, -chunk); outputBuffer.write(dataFrame, ioSession.channel()); }
errorCode = H2Error.INTERNAL_ERROR; final RawFrame goAway = frameFactory.createGoAway(processedRemoteStreamId, errorCode, cause.getMessage()); commitFrame(goAway);