switch (frameType) { case DATA:
readDataFrame(streamId, flags, payloadSize, null); break; case HEADERS:
readHeadersFrame(streamId, flags, payloadSize, null); break; case PRIORITY:
readPriorityFrame(streamId, null); break; case RST:
readRstFrame(streamId, null); break; case SETTINGS:
readSettingsFrame(flags, payloadSize, null); break; case PUSH_PROMISE:
readPushPromiseFrame(streamId, flags, payloadSize, null); break; case PING:
readPingFrame(flags, null); break; case GOAWAY:
readGoawayFrame(payloadSize, null); break; case WINDOW_UPDATE:
readWindowUpdateFrame(streamId, null); break; case CONTINUATION:
readContinuationFrame(streamId, flags, payloadSize, null); break; case PRIORITY_UPDATE:
readPriorityUpdateFrame(payloadSize, null); break; case UNKNOWN:
readUnknownFrame(streamId, frameTypeId, flags, payloadSize, null);
}
returntrue;
}
protectedvoid readDataFrame(int streamId, int flags, int payloadSize, ByteBuffer buffer) throws Http2Exception, IOException { // Process the Stream int padLength = 0;
boolean endOfStream = Flags.isEndOfStream(flags);
int dataLength; if (Flags.hasPadding(flags)) { if (buffer == null) { byte[] b = newbyte[1];
input.fill(true, b);
padLength = b[0] & 0xFF;
} else {
padLength = buffer.get() & 0xFF;
}
if (padLength >= payloadSize) { thrownew ConnectionException(
sm.getString("http2Parser.processFrame.tooMuchPadding", connectionId,
Integer.toString(streamId), Integer.toString(padLength), Integer.toString(payloadSize)),
Http2Error.PROTOCOL_ERROR);
} // +1 is for the padding length byte we just read above
dataLength = payloadSize - (padLength + 1);
} else {
dataLength = payloadSize;
}
ByteBuffer dest = output.startRequestBodyFrame(streamId, payloadSize, endOfStream); if (dest == null) {
swallowPayload(streamId, FrameType.DATA.getId(), dataLength, false, buffer); // Process padding before sending any notifications in case padding // is invalid. if (Flags.hasPadding(flags)) {
swallowPayload(streamId, FrameType.DATA.getId(), padLength, true, buffer);
} if (endOfStream) {
output.receivedEndOfStream(streamId);
}
} else { synchronized (dest) { if (dest.remaining() < payloadSize) { // Client has sent more data than permitted by Window size
swallowPayload(streamId, FrameType.DATA.getId(), dataLength, false, buffer); if (Flags.hasPadding(flags)) {
swallowPayload(streamId, FrameType.DATA.getId(), padLength, true, buffer);
} thrownew StreamException(sm.getString("http2Parser.processFrameData.window", connectionId),
Http2Error.FLOW_CONTROL_ERROR, streamId);
} if (buffer == null) {
input.fill(true, dest, dataLength);
} else { int oldLimit = buffer.limit();
buffer.limit(buffer.position() + dataLength);
dest.put(buffer);
buffer.limit(oldLimit);
} // Process padding before sending any notifications in case // padding is invalid. if (Flags.hasPadding(flags)) {
swallowPayload(streamId, FrameType.DATA.getId(), padLength, true, buffer);
} if (endOfStream) {
output.receivedEndOfStream(streamId);
}
output.endRequestBodyFrame(streamId, dataLength);
}
}
}
protectedvoid readHeadersFrame(int streamId, int flags, int payloadSize, ByteBuffer buffer) throws Http2Exception, IOException {
protectedvoid readPriorityFrame(int streamId, ByteBuffer buffer) throws IOException { // RFC 7450 priority frames are ignored. Still need to treat as overhead. try {
swallowPayload(streamId, FrameType.PRIORITY.getId(), 5, false, buffer);
} catch (ConnectionException e) { // Will never happen because swallowPayload() is called with isPadding set // to false
}
output.increaseOverheadCount(FrameType.PRIORITY);
}
int prioritizedStreamID = ByteUtil.get31Bits(payload, 0);
if (prioritizedStreamID == 0) { thrownew ConnectionException(sm.getString("http2Parser.processFramePriorityUpdate.streamZero"),
Http2Error.PROTOCOL_ERROR);
}
ByteArrayInputStream bais = new ByteArrayInputStream(payload, 4, payloadSize - 4);
Reader r = new BufferedReader(new InputStreamReader(bais, StandardCharsets.US_ASCII));
Priority p = Priority.parsePriority(r);
if (log.isDebugEnabled()) {
log.debug(sm.getString("http2Parser.processFramePriorityUpdate.debug", connectionId,
Integer.toString(prioritizedStreamID), Integer.toString(p.getUrgency()), Boolean.valueOf(p.getIncremental())));
}
protectedvoid readUnknownFrame(int streamId, int frameTypeId, int flags, int payloadSize, ByteBuffer buffer) throws IOException { try {
swallowPayload(streamId, frameTypeId, payloadSize, false, buffer);
} catch (ConnectionException e) { // Will never happen because swallowPayload() is called with isPadding set // to false
} finally {
output.onSwallowedUnknownFrame(streamId, frameTypeId, flags, payloadSize);
}
}
/** *SwallowsomeorallofthebytesfromthepayloadofanHTTP/2frame. * *@paramstreamIdStreambeingswallowed *@paramframeTypeIdTypeofHTTP/2frameforwhichthebyteswillbeswallowed *@paramlenNumberofbytestoswallow *@paramisPaddingArethebytestobeswallowedpaddingbytes? *@parambyteBufferUsedwith{@linkHttp2AsyncParser}toaccessthedatathathasalreadybeenread * *@throwsIOExceptionIfanI/Oerroroccursreadingadditionalbytesintotheinputbuffer. *@throwsConnectionExceptionIftheswallowedbytesareexpectedtohaveavalueofzerobutdonot
*/ protectedvoid swallowPayload(int streamId, int frameTypeId, int len, boolean isPadding, ByteBuffer byteBuffer) throws IOException, ConnectionException { if (log.isDebugEnabled()) {
log.debug(sm.getString("http2Parser.swallow.debug", connectionId, Integer.toString(streamId),
Integer.toString(len)));
} try { if (len == 0) { return;
} if (!isPadding && byteBuffer != null) {
byteBuffer.position(byteBuffer.position() + len);
} else { int read = 0; byte[] buffer = newbyte[1024]; while (read < len) { int thisTime = Math.min(buffer.length, len - read); if (byteBuffer == null) {
input.fill(true, buffer, 0, thisTime);
} else {
byteBuffer.get(buffer, 0, thisTime);
} if (isPadding) { // Validate the padding is zero since receiving non-zero padding // is a strong indication of either a faulty client or a server // side bug. for (int i = 0; i < thisTime; i++) { if (buffer[i] != 0) { thrownew ConnectionException(sm.getString("http2Parser.nonZeroPadding", connectionId,
Integer.toString(streamId)), Http2Error.PROTOCOL_ERROR);
}
}
}
read += thisTime;
}
}
} finally { if (FrameType.DATA.getIdByte() == frameTypeId) { if (isPadding) { // Need to add 1 for the padding length bytes that was also // part of the payload.
len += 1;
} if (len > 0) {
output.onSwallowedDataFramePayload(streamId, len);
}
}
}
}
protectedvoid onHeadersComplete(int streamId) throws Http2Exception { // Any left over data is a compression error if (headerReadBuffer.position() > 0) { thrownew ConnectionException(sm.getString("http2Parser.processFrameHeaders.decodingDataLeft"),
Http2Error.COMPRESSION_ERROR);
}
// Delay validation (and triggering any exception) until this point // since all the headers still have to be read if a StreamException is // going to be thrown.
hpackDecoder.getHeaderEmitter().validateHeaders();
if (headersEndStream) {
headersEndStream = false;
}
}
// Reset size for new request if the buffer was previously expanded if (headerReadBuffer.capacity() > Constants.DEFAULT_HEADER_READ_BUFFER_SIZE) {
headerReadBuffer = ByteBuffer.allocate(Constants.DEFAULT_HEADER_READ_BUFFER_SIZE);
}
}
/* *Implementationnote:Validationapplicabletoallincomingframesshouldbeimplementedhere.Frametypespecific *validationshouldbeperformedintheappropriatereadXxxFrame()method.Forvalidationapplicabletosomebut *notallframetypes,useyourjudgement.
*/ protectedvoid validateFrame(FrameType expected, FrameType frameType, int streamId, int flags, int payloadSize) throws Http2Exception {
if (log.isDebugEnabled()) {
log.debug(sm.getString("http2Parser.processFrame", connectionId, Integer.toString(streamId), frameType,
Integer.toString(flags), Integer.toString(payloadSize)));
}
for (int i = 0; i < CLIENT_PREFACE_START.length; i++) { if (CLIENT_PREFACE_START[i] != data[i]) { thrownew ProtocolException(sm.getString("http2Parser.preface.invalid"));
}
}
// Must always be followed by a settings frame
readFrame(true, FrameType.SETTINGS);
} catch (IOException ioe) { thrownew ProtocolException(sm.getString("http2Parser.preface.io"), ioe);
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.15Bemerkung:
(vorverarbeitet am 2026-10-04)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.