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.frames.Frame;
24
25
26
27
28
29
30 public class HeaderParser
31 {
32 private State state = State.LENGTH;
33 private int cursor;
34
35 private int length;
36 private int type;
37 private int flags;
38 private int streamId;
39
40 protected void reset()
41 {
42 state = State.LENGTH;
43 cursor = 0;
44
45 length = 0;
46 type = 0;
47 flags = 0;
48 streamId = 0;
49 }
50
51
52
53
54
55
56
57
58
59
60 public boolean parse(ByteBuffer buffer)
61 {
62 while (buffer.hasRemaining())
63 {
64 switch (state)
65 {
66 case LENGTH:
67 {
68 int octet = buffer.get() & 0xFF;
69 length = (length << 8) + octet;
70 if (++cursor == 3)
71 {
72 length &= Frame.MAX_MAX_LENGTH;
73 state = State.TYPE;
74 }
75 break;
76 }
77 case TYPE:
78 {
79 type = buffer.get() & 0xFF;
80 state = State.FLAGS;
81 break;
82 }
83 case FLAGS:
84 {
85 flags = buffer.get() & 0xFF;
86 state = State.STREAM_ID;
87 break;
88 }
89 case STREAM_ID:
90 {
91 if (buffer.remaining() >= 4)
92 {
93 streamId = buffer.getInt();
94
95 streamId &= 0x7F_FF_FF_FF;
96 return true;
97 }
98 else
99 {
100 state = State.STREAM_ID_BYTES;
101 cursor = 4;
102 }
103 break;
104 }
105 case STREAM_ID_BYTES:
106 {
107 int currByte = buffer.get() & 0xFF;
108 --cursor;
109 streamId += currByte << (8 * cursor);
110 if (cursor == 0)
111 {
112
113 streamId &= 0x7F_FF_FF_FF;
114 return true;
115 }
116 break;
117 }
118 default:
119 {
120 throw new IllegalStateException();
121 }
122 }
123 }
124 return false;
125 }
126
127 public int getLength()
128 {
129 return length;
130 }
131
132 public int getFrameType()
133 {
134 return type;
135 }
136
137 public boolean hasFlag(int bit)
138 {
139 return (flags & bit) == bit;
140 }
141
142 public int getStreamId()
143 {
144 return streamId;
145 }
146
147 private enum State
148 {
149 LENGTH, TYPE, FLAGS, STREAM_ID, STREAM_ID_BYTES
150 }
151 }