Clearing the buffer in case of parser errors that lead to a
connection failure.
This commit is contained in:
parent
1c2c83e962
commit
7f98b64658
|
@ -31,6 +31,7 @@ import org.eclipse.jetty.http2.frames.PushPromiseFrame;
|
|||
import org.eclipse.jetty.http2.frames.ResetFrame;
|
||||
import org.eclipse.jetty.http2.frames.SettingsFrame;
|
||||
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -49,8 +50,9 @@ public abstract class BodyParser
|
|||
|
||||
public abstract Result parse(ByteBuffer buffer);
|
||||
|
||||
protected boolean emptyBody()
|
||||
protected boolean emptyBody(ByteBuffer buffer)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_frame");
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -45,10 +45,11 @@ public class DataBodyParser extends BodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean emptyBody()
|
||||
protected boolean emptyBody(ByteBuffer buffer)
|
||||
{
|
||||
if (isPadding())
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_data_frame");
|
||||
return false;
|
||||
}
|
||||
|
@ -68,6 +69,7 @@ public class DataBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_data_frame");
|
||||
}
|
||||
length = getBodyLength();
|
||||
|
@ -91,6 +93,7 @@ public class DataBodyParser extends BodyParser
|
|||
loop = length == 0;
|
||||
if (length < 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_data_frame_padding");
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.frames.GoAwayFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class GoAwayBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -70,6 +71,7 @@ public class GoAwayBodyParser extends BodyParser
|
|||
length -= 4;
|
||||
if (length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_go_away_frame");
|
||||
}
|
||||
}
|
||||
|
@ -88,6 +90,7 @@ public class GoAwayBodyParser extends BodyParser
|
|||
--length;
|
||||
if (cursor > 0 && length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_go_away_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
@ -96,6 +99,7 @@ public class GoAwayBodyParser extends BodyParser
|
|||
state = State.ERROR;
|
||||
if (length == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_go_away_frame");
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +114,7 @@ public class GoAwayBodyParser extends BodyParser
|
|||
length -= 4;
|
||||
if (length < 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_go_away_frame");
|
||||
}
|
||||
if (length == 0)
|
||||
|
@ -132,6 +137,7 @@ public class GoAwayBodyParser extends BodyParser
|
|||
--length;
|
||||
if (cursor > 0 && length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_go_away_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
|
|
@ -56,7 +56,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean emptyBody()
|
||||
protected boolean emptyBody(ByteBuffer buffer)
|
||||
{
|
||||
MetaData metaData = headerBlockParser.parse(BufferUtil.EMPTY_BUFFER, 0);
|
||||
boolean result = onHeaders(0, 0, false, metaData);
|
||||
|
@ -77,12 +77,14 @@ public class HeadersBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_headers_frame");
|
||||
}
|
||||
|
||||
// For now we don't support HEADERS frames that don't have END_HEADERS.
|
||||
if (!hasFlag(Flags.END_HEADERS))
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.INTERNAL_ERROR, "unsupported_headers_frame");
|
||||
}
|
||||
|
||||
|
@ -111,6 +113,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
loop = length == 0;
|
||||
if (length < 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_headers_frame_padding");
|
||||
}
|
||||
break;
|
||||
|
@ -134,6 +137,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
state = State.WEIGHT;
|
||||
if (length < 1)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_headers_frame");
|
||||
}
|
||||
}
|
||||
|
@ -152,6 +156,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
--length;
|
||||
if (cursor > 0 && length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_headers_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
@ -160,6 +165,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
state = State.WEIGHT;
|
||||
if (length < 1)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_headers_frame");
|
||||
}
|
||||
}
|
||||
|
@ -178,6 +184,7 @@ public class HeadersBodyParser extends BodyParser
|
|||
MetaData metaData = headerBlockParser.parse(buffer, length);
|
||||
if (metaData != null)
|
||||
{
|
||||
// TODO: optimize of paddingLength==0: reset() here.
|
||||
state = State.PADDING;
|
||||
loop = paddingLength == 0;
|
||||
if (onHeaders(streamId, weight, exclusive, metaData))
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.http2.frames.SettingsFrame;
|
|||
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
|
||||
import org.eclipse.jetty.http2.hpack.HpackDecoder;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -94,12 +95,13 @@ public class Parser
|
|||
if (type < 0 || type >= bodyParsers.length)
|
||||
{
|
||||
notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "unknown_frame_type_" + type);
|
||||
BufferUtil.clear(buffer);
|
||||
return false;
|
||||
}
|
||||
BodyParser bodyParser = bodyParsers[type];
|
||||
if (headerParser.getLength() == 0)
|
||||
{
|
||||
boolean async = bodyParser.emptyBody();
|
||||
boolean async = bodyParser.emptyBody(buffer);
|
||||
reset();
|
||||
if (async)
|
||||
return true;
|
||||
|
@ -151,6 +153,7 @@ public class Parser
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug(x);
|
||||
notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "parser_error");
|
||||
BufferUtil.clear(buffer);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.nio.ByteBuffer;
|
|||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.Flags;
|
||||
import org.eclipse.jetty.http2.frames.PingFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class PingBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -54,11 +55,13 @@ public class PingBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() != 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_ping_frame");
|
||||
}
|
||||
// SPEC: wrong body length is treated as connection error.
|
||||
if (getBodyLength() != 8)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_ping_frame");
|
||||
}
|
||||
state = State.PAYLOAD;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.frames.PrefaceFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -45,6 +46,7 @@ public class PrefaceParser
|
|||
if (currByte != PrefaceFrame.PREFACE_BYTES[cursor])
|
||||
{
|
||||
notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_preface");
|
||||
BufferUtil.clear(buffer);
|
||||
return false;
|
||||
}
|
||||
++cursor;
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.frames.PriorityFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class PriorityBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -55,11 +56,13 @@ public class PriorityBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_priority_frame");
|
||||
}
|
||||
int length = getBodyLength();
|
||||
if (length != 5)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_priority_frame");
|
||||
}
|
||||
state = State.EXCLUSIVE;
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.eclipse.jetty.http.MetaData;
|
|||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.Flags;
|
||||
import org.eclipse.jetty.http2.frames.PushPromiseFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class PushPromiseBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -62,12 +63,14 @@ public class PushPromiseBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_push_promise_frame");
|
||||
}
|
||||
|
||||
// For now we don't support PUSH_PROMISE frames that don't have END_HEADERS.
|
||||
if (!hasFlag(Flags.END_HEADERS))
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.INTERNAL_ERROR, "unsupported_push_promise_frame");
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,7 @@ public class PushPromiseBodyParser extends BodyParser
|
|||
state = State.STREAM_ID;
|
||||
if (length < 4)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_push_promise_frame");
|
||||
}
|
||||
break;
|
||||
|
@ -120,6 +124,7 @@ public class PushPromiseBodyParser extends BodyParser
|
|||
--length;
|
||||
if (cursor > 0 && length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_push_promise_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.frames.ResetFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class ResetBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -53,11 +54,13 @@ public class ResetBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() == 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_rst_stream_frame");
|
||||
}
|
||||
int length = getBodyLength();
|
||||
if (length != 4)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_rst_stream_frame");
|
||||
}
|
||||
state = State.ERROR;
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Map;
|
|||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.Flags;
|
||||
import org.eclipse.jetty.http2.frames.SettingsFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -54,7 +55,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
}
|
||||
|
||||
@Override
|
||||
protected boolean emptyBody()
|
||||
protected boolean emptyBody(ByteBuffer buffer)
|
||||
{
|
||||
return onSettings(new HashMap<Integer, Integer>()) == Result.ASYNC;
|
||||
}
|
||||
|
@ -71,6 +72,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
// SPEC: wrong streamId is treated as connection error.
|
||||
if (getStreamId() != 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.PROTOCOL_ERROR, "invalid_settings_frame");
|
||||
}
|
||||
length = getBodyLength();
|
||||
|
@ -87,6 +89,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
length -= 2;
|
||||
if (length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_settings_frame");
|
||||
}
|
||||
}
|
||||
|
@ -106,6 +109,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
--length;
|
||||
if (length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_settings_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
@ -145,6 +149,7 @@ public class SettingsBodyParser extends BodyParser
|
|||
--length;
|
||||
if (cursor > 0 && length <= 0)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_settings_frame");
|
||||
}
|
||||
if (cursor == 0)
|
||||
|
|
|
@ -22,6 +22,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import org.eclipse.jetty.http2.ErrorCodes;
|
||||
import org.eclipse.jetty.http2.frames.WindowUpdateFrame;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
|
||||
public class WindowUpdateBodyParser extends BodyParser
|
||||
{
|
||||
|
@ -53,6 +54,7 @@ public class WindowUpdateBodyParser extends BodyParser
|
|||
int length = getBodyLength();
|
||||
if (length != 4)
|
||||
{
|
||||
BufferUtil.clear(buffer);
|
||||
return notifyConnectionFailure(ErrorCodes.FRAME_SIZE_ERROR, "invalid_window_update_frame");
|
||||
}
|
||||
state = State.WINDOW_DELTA;
|
||||
|
|
Loading…
Reference in New Issue