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.Flags;
25 import org.eclipse.jetty.http2.frames.FrameType;
26 import org.eclipse.jetty.io.ByteBufferPool;
27 import org.eclipse.jetty.util.BufferUtil;
28 import org.eclipse.jetty.util.log.Log;
29 import org.eclipse.jetty.util.log.Logger;
30
31 public class ServerParser extends Parser
32 {
33 private static final Logger LOG = Log.getLogger(ServerParser.class);
34
35 private final Listener listener;
36 private final PrefaceParser prefaceParser;
37 private State state = State.PREFACE;
38 private boolean notifyPreface = true;
39
40 public ServerParser(ByteBufferPool byteBufferPool, Listener listener, int maxDynamicTableSize, int maxHeaderSize)
41 {
42 super(byteBufferPool, listener, maxDynamicTableSize, maxHeaderSize);
43 this.listener = listener;
44 this.prefaceParser = new PrefaceParser(listener);
45 }
46
47
48
49
50
51
52
53
54
55
56
57
58
59 public void directUpgrade()
60 {
61 if (state != State.PREFACE)
62 throw new IllegalStateException();
63 prefaceParser.directUpgrade();
64 }
65
66
67
68
69 public void standardUpgrade()
70 {
71 if (state != State.PREFACE)
72 throw new IllegalStateException();
73 notifyPreface = false;
74 }
75
76 @Override
77 public void parse(ByteBuffer buffer)
78 {
79 try
80 {
81 if (LOG.isDebugEnabled())
82 LOG.debug("Parsing {}", buffer);
83
84 while (true)
85 {
86 switch (state)
87 {
88 case PREFACE:
89 {
90 if (!prefaceParser.parse(buffer))
91 return;
92 if (notifyPreface)
93 onPreface();
94 state = State.SETTINGS;
95 break;
96 }
97 case SETTINGS:
98 {
99 if (!parseHeader(buffer))
100 return;
101 if (getFrameType() != FrameType.SETTINGS.getType() || hasFlag(Flags.ACK))
102 {
103 BufferUtil.clear(buffer);
104 notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "invalid_preface");
105 return;
106 }
107 if (!parseBody(buffer))
108 return;
109 state = State.FRAMES;
110 break;
111 }
112 case FRAMES:
113 {
114
115 super.parse(buffer);
116 return;
117 }
118 default:
119 {
120 throw new IllegalStateException();
121 }
122 }
123 }
124 }
125 catch (Throwable x)
126 {
127 LOG.debug(x);
128 BufferUtil.clear(buffer);
129 notifyConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "parser_error");
130 }
131 }
132
133 protected void onPreface()
134 {
135 notifyPreface();
136 }
137
138 private void notifyPreface()
139 {
140 try
141 {
142 listener.onPreface();
143 }
144 catch (Throwable x)
145 {
146 LOG.info("Failure while notifying listener " + listener, x);
147 }
148 }
149
150 public interface Listener extends Parser.Listener
151 {
152 public void onPreface();
153
154 public static class Adapter extends Parser.Listener.Adapter implements Listener
155 {
156 @Override
157 public void onPreface()
158 {
159 }
160 }
161 }
162
163 private enum State
164 {
165 PREFACE, SETTINGS, FRAMES
166 }
167 }