1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.http2.server;
20
21 import java.util.Collections;
22 import java.util.Map;
23
24 import org.eclipse.jetty.http.MetaData;
25 import org.eclipse.jetty.http2.ErrorCode;
26 import org.eclipse.jetty.http2.FlowControlStrategy;
27 import org.eclipse.jetty.http2.HTTP2Session;
28 import org.eclipse.jetty.http2.IStream;
29 import org.eclipse.jetty.http2.api.Session;
30 import org.eclipse.jetty.http2.api.Stream;
31 import org.eclipse.jetty.http2.api.server.ServerSessionListener;
32 import org.eclipse.jetty.http2.frames.Frame;
33 import org.eclipse.jetty.http2.frames.HeadersFrame;
34 import org.eclipse.jetty.http2.frames.PushPromiseFrame;
35 import org.eclipse.jetty.http2.frames.SettingsFrame;
36 import org.eclipse.jetty.http2.generator.Generator;
37 import org.eclipse.jetty.http2.parser.ServerParser;
38 import org.eclipse.jetty.io.EndPoint;
39 import org.eclipse.jetty.util.Callback;
40 import org.eclipse.jetty.util.log.Log;
41 import org.eclipse.jetty.util.log.Logger;
42 import org.eclipse.jetty.util.thread.Scheduler;
43
44 public class HTTP2ServerSession extends HTTP2Session implements ServerParser.Listener
45 {
46 private static final Logger LOG = Log.getLogger(HTTP2ServerSession.class);
47
48 private final ServerSessionListener listener;
49
50 public HTTP2ServerSession(Scheduler scheduler, EndPoint endPoint, Generator generator, ServerSessionListener listener, FlowControlStrategy flowControl)
51 {
52 super(scheduler, endPoint, generator, listener, flowControl, 2);
53 this.listener = listener;
54 }
55
56 @Override
57 public void onPreface()
58 {
59
60 Map<Integer, Integer> settings = notifyPreface(this);
61 if (settings == null)
62 settings = Collections.emptyMap();
63 SettingsFrame frame = new SettingsFrame(settings, false);
64
65 frames(null, Callback.NOOP, frame, Frame.EMPTY_ARRAY);
66 }
67
68 @Override
69 public void onHeaders(HeadersFrame frame)
70 {
71 if (LOG.isDebugEnabled())
72 LOG.debug("Received {}", frame);
73
74 MetaData metaData = frame.getMetaData();
75 if (metaData.isRequest())
76 {
77 IStream stream = createRemoteStream(frame.getStreamId());
78 if (stream != null)
79 {
80 stream.process(frame, Callback.NOOP);
81 Stream.Listener listener = notifyNewStream(stream, frame);
82 stream.setListener(listener);
83 }
84 }
85 else
86 {
87 onConnectionFailure(ErrorCode.INTERNAL_ERROR.code, "invalid_request");
88 }
89 }
90
91 @Override
92 public void onPushPromise(PushPromiseFrame frame)
93 {
94 onConnectionFailure(ErrorCode.PROTOCOL_ERROR.code, "push_promise");
95 }
96
97 private Map<Integer, Integer> notifyPreface(Session session)
98 {
99 try
100 {
101 return listener.onPreface(session);
102 }
103 catch (Throwable x)
104 {
105 LOG.info("Failure while notifying listener " + listener, x);
106 return null;
107 }
108 }
109
110 @Override
111 public void onFrame(Frame frame)
112 {
113 switch (frame.getType())
114 {
115 case PREFACE:
116 onPreface();
117 break;
118 case SETTINGS:
119
120 onSettings((SettingsFrame)frame, false);
121 break;
122 case HEADERS:
123 onHeaders((HeadersFrame)frame);
124 break;
125 default:
126 super.onFrame(frame);
127 break;
128 }
129 }
130 }