use of org.apache.hc.core5.http2.H2ConnectionException in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method applyLocalSettings.
private void applyLocalSettings() throws H2ConnectionException {
hPackDecoder.setMaxTableSize(localConfig.getHeaderTableSize());
hPackDecoder.setMaxListSize(localConfig.getMaxHeaderListSize());
final int delta = localConfig.getInitialWindowSize() - initInputWinSize;
initInputWinSize = localConfig.getInitialWindowSize();
if (delta != 0 && !streamMap.isEmpty()) {
for (final Iterator<Map.Entry<Integer, H2Stream>> it = streamMap.entrySet().iterator(); it.hasNext(); ) {
final Map.Entry<Integer, H2Stream> entry = it.next();
final H2Stream stream = entry.getValue();
try {
updateInputWindow(stream.getId(), stream.getInputWindow(), delta);
} catch (final ArithmeticException ex) {
throw new H2ConnectionException(H2Error.FLOW_CONTROL_ERROR, ex.getMessage());
}
}
}
lowMark = initInputWinSize / 2;
}
use of org.apache.hc.core5.http2.H2ConnectionException in project httpcomponents-core by apache.
the class ClientH2StreamMultiplexer method createLocallyInitiatedStream.
@Override
H2StreamHandler createLocallyInitiatedStream(final ExecutableCommand command, final H2StreamChannel channel, final HttpProcessor httpProcessor, final BasicHttpConnectionMetrics connMetrics) throws IOException {
if (command instanceof RequestExecutionCommand) {
final RequestExecutionCommand executionCommand = (RequestExecutionCommand) command;
final AsyncClientExchangeHandler exchangeHandler = executionCommand.getExchangeHandler();
final HandlerFactory<AsyncPushConsumer> pushHandlerFactory = executionCommand.getPushHandlerFactory();
final HttpCoreContext context = HttpCoreContext.adapt(executionCommand.getContext());
context.setAttribute(HttpCoreContext.SSL_SESSION, getSSLSession());
context.setAttribute(HttpCoreContext.CONNECTION_ENDPOINT, getEndpointDetails());
return new ClientH2StreamHandler(channel, httpProcessor, connMetrics, exchangeHandler, pushHandlerFactory != null ? pushHandlerFactory : this.pushHandlerFactory, context);
}
throw new H2ConnectionException(H2Error.INTERNAL_ERROR, "Unexpected executable command");
}
use of org.apache.hc.core5.http2.H2ConnectionException in project httpcomponents-core by apache.
the class FrameInputBuffer method read.
/**
* Attempts to read a complete frame from the given source buffer and the underlying data
* channel. The source buffer is consumed first. More data can be read from the channel
* if required.
*
* @param src the source buffer or {@code null} if not available.
* @param channel the underlying data channel.
*
* @return a complete frame or {@code null} a complete frame cannot be read.
*
* @since 5.1
*/
public RawFrame read(final ByteBuffer src, final ReadableByteChannel channel) throws IOException {
for (; ; ) {
if (src != null) {
if (buffer.hasRemaining()) {
buffer.compact();
} else {
buffer.clear();
}
final int remaining = buffer.remaining();
if (remaining >= src.remaining()) {
buffer.put(src);
} else {
final int limit = src.limit();
src.limit(remaining);
buffer.put(src);
src.limit(limit);
}
buffer.flip();
}
switch(state) {
case HEAD_EXPECTED:
if (buffer.remaining() >= FrameConsts.HEAD_LEN) {
final int lengthAndType = buffer.getInt();
payloadLen = lengthAndType >> 8;
if (payloadLen > maxFramePayloadSize) {
throw new H2ConnectionException(H2Error.FRAME_SIZE_ERROR, "Frame size exceeds maximum");
}
type = lengthAndType & 0xff;
flags = buffer.get();
streamId = Math.abs(buffer.getInt());
state = State.PAYLOAD_EXPECTED;
} else {
break;
}
case PAYLOAD_EXPECTED:
if (buffer.remaining() >= payloadLen) {
if ((flags & FrameFlag.PADDED.getValue()) > 0) {
if (payloadLen == 0) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Inconsistent padding");
}
buffer.mark();
final int padding = buffer.get();
if (payloadLen < padding + 1) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, "Inconsistent padding");
}
buffer.reset();
}
final ByteBuffer payload = payloadLen > 0 ? ByteBuffer.wrap(bytes, buffer.position(), payloadLen) : null;
buffer.position(buffer.position() + payloadLen);
state = State.HEAD_EXPECTED;
metrics.incrementFramesTransferred();
return new RawFrame(type, flags, streamId, payload);
}
}
if (buffer.hasRemaining()) {
buffer.compact();
} else {
buffer.clear();
}
final int bytesRead = channel.read(buffer);
buffer.flip();
if (bytesRead > 0) {
metrics.incrementBytesTransferred(bytesRead);
}
if (bytesRead == 0) {
break;
} else if (bytesRead < 0) {
if (state != State.HEAD_EXPECTED || buffer.hasRemaining()) {
throw new H2CorruptFrameException("Corrupt or incomplete HTTP2 frame");
} else {
throw new ConnectionClosedException();
}
}
}
return null;
}
use of org.apache.hc.core5.http2.H2ConnectionException in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method consumeSettingsFrame.
private void consumeSettingsFrame(final ByteBuffer payload) throws HttpException, IOException {
final H2Config.Builder configBuilder = H2Config.initial();
while (payload.hasRemaining()) {
final int code = payload.getShort();
final int value = payload.getInt();
final H2Param param = H2Param.valueOf(code);
if (param != null) {
switch(param) {
case HEADER_TABLE_SIZE:
try {
configBuilder.setHeaderTableSize(value);
} catch (final IllegalArgumentException ex) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
break;
case MAX_CONCURRENT_STREAMS:
try {
configBuilder.setMaxConcurrentStreams(value);
} catch (final IllegalArgumentException ex) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
break;
case ENABLE_PUSH:
configBuilder.setPushEnabled(value == 1);
break;
case INITIAL_WINDOW_SIZE:
try {
configBuilder.setInitialWindowSize(value);
} catch (final IllegalArgumentException ex) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
break;
case MAX_FRAME_SIZE:
try {
configBuilder.setMaxFrameSize(value);
} catch (final IllegalArgumentException ex) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
break;
case MAX_HEADER_LIST_SIZE:
try {
configBuilder.setMaxHeaderListSize(value);
} catch (final IllegalArgumentException ex) {
throw new H2ConnectionException(H2Error.PROTOCOL_ERROR, ex.getMessage());
}
break;
}
}
}
applyRemoteSettings(configBuilder.build());
}
use of org.apache.hc.core5.http2.H2ConnectionException in project httpcomponents-core by apache.
the class AbstractH2StreamMultiplexer method commitPushPromise.
private void commitPushPromise(final int streamId, final int promisedStreamId, final List<Header> headers) throws IOException {
if (headers == null || headers.isEmpty()) {
throw new H2ConnectionException(H2Error.INTERNAL_ERROR, "Message headers are missing");
}
if (streamListener != null) {
streamListener.onHeaderOutput(this, streamId, headers);
}
final ByteArrayBuffer buf = new ByteArrayBuffer(512);
buf.append((byte) (promisedStreamId >> 24));
buf.append((byte) (promisedStreamId >> 16));
buf.append((byte) (promisedStreamId >> 8));
buf.append((byte) (promisedStreamId));
hPackEncoder.encodeHeaders(buf, headers, localConfig.isCompressionEnabled());
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.createPushPromise(streamId, payload, endHeaders);
continuation = true;
} else {
frame = frameFactory.createContinuation(streamId, payload, endHeaders);
}
commitFrameInternal(frame);
}
}
Aggregations