1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.http2.parser;
20
21 import java.nio.ByteBuffer;
22
23 import org.eclipse.jetty.http2.ErrorCode;
24 import org.eclipse.jetty.http2.frames.ResetFrame;
25
26 public class ResetBodyParser extends BodyParser
27 {
28 private State state = State.PREPARE;
29 private int cursor;
30 private int error;
31
32 public ResetBodyParser(HeaderParser headerParser, Parser.Listener listener)
33 {
34 super(headerParser, listener);
35 }
36
37 private void reset()
38 {
39 state = State.PREPARE;
40 cursor = 0;
41 error = 0;
42 }
43
44 @Override
45 public boolean parse(ByteBuffer buffer)
46 {
47 while (buffer.hasRemaining())
48 {
49 switch (state)
50 {
51 case PREPARE:
52 {
53
54 if (getStreamId() == 0)
55 return connectionFailure(buffer, ErrorCode.PROTOCOL_ERROR.code, "invalid_rst_stream_frame");
56 int length = getBodyLength();
57 if (length != 4)
58 return connectionFailure(buffer, ErrorCode.FRAME_SIZE_ERROR.code, "invalid_rst_stream_frame");
59 state = State.ERROR;
60 break;
61 }
62 case ERROR:
63 {
64 if (buffer.remaining() >= 4)
65 {
66 return onReset(buffer.getInt());
67 }
68 else
69 {
70 state = State.ERROR_BYTES;
71 cursor = 4;
72 }
73 break;
74 }
75 case ERROR_BYTES:
76 {
77 int currByte = buffer.get() & 0xFF;
78 --cursor;
79 error += currByte << (8 * cursor);
80 if (cursor == 0)
81 return onReset(error);
82 break;
83 }
84 default:
85 {
86 throw new IllegalStateException();
87 }
88 }
89 }
90 return false;
91 }
92
93 private boolean onReset(int error)
94 {
95 ResetFrame frame = new ResetFrame(getStreamId(), error);
96 reset();
97 notifyReset(frame);
98 return true;
99 }
100
101 private enum State
102 {
103 PREPARE, ERROR, ERROR_BYTES
104 }
105 }