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.HashMap;
22 import java.util.Map;
23
24 import org.eclipse.jetty.http2.ErrorCode;
25 import org.eclipse.jetty.http2.HTTP2Cipher;
26 import org.eclipse.jetty.http2.IStream;
27 import org.eclipse.jetty.http2.api.Session;
28 import org.eclipse.jetty.http2.api.Stream;
29 import org.eclipse.jetty.http2.api.server.ServerSessionListener;
30 import org.eclipse.jetty.http2.frames.DataFrame;
31 import org.eclipse.jetty.http2.frames.HeadersFrame;
32 import org.eclipse.jetty.http2.frames.PushPromiseFrame;
33 import org.eclipse.jetty.http2.frames.ResetFrame;
34 import org.eclipse.jetty.http2.frames.SettingsFrame;
35 import org.eclipse.jetty.io.EndPoint;
36 import org.eclipse.jetty.server.Connector;
37 import org.eclipse.jetty.server.HttpConfiguration;
38 import org.eclipse.jetty.server.NegotiatingServerConnection.CipherDiscriminator;
39 import org.eclipse.jetty.util.Callback;
40 import org.eclipse.jetty.util.annotation.Name;
41 import org.eclipse.jetty.util.log.Log;
42 import org.eclipse.jetty.util.log.Logger;
43
44 public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionFactory implements CipherDiscriminator
45 {
46 private static final Logger LOG = Log.getLogger(HTTP2ServerConnectionFactory.class);
47
48 public HTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
49 {
50 super(httpConfiguration);
51 }
52
53 protected HTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration,String... protocols)
54 {
55 super(httpConfiguration,protocols);
56 }
57
58 @Override
59 protected ServerSessionListener newSessionListener(Connector connector, EndPoint endPoint)
60 {
61 return new HTTPServerSessionListener(connector, endPoint);
62 }
63
64 @Override
65 public boolean isAcceptable(String protocol, String tlsProtocol, String tlsCipher)
66 {
67
68
69 boolean acceptable = "h2-14".equals(protocol) || !(HTTP2Cipher.isBlackListProtocol(tlsProtocol) && HTTP2Cipher.isBlackListCipher(tlsCipher));
70 if (LOG.isDebugEnabled())
71 LOG.debug("proto={} tls={} cipher={} 9.2.2-acceptable={}",protocol,tlsProtocol,tlsCipher,acceptable);
72 return acceptable;
73 }
74
75 private class HTTPServerSessionListener extends ServerSessionListener.Adapter implements Stream.Listener
76 {
77 private final Connector connector;
78 private final EndPoint endPoint;
79
80 public HTTPServerSessionListener(Connector connector, EndPoint endPoint)
81 {
82 this.connector = connector;
83 this.endPoint = endPoint;
84 }
85
86 private HTTP2ServerConnection getConnection()
87 {
88 return (HTTP2ServerConnection)endPoint.getConnection();
89 }
90
91 @Override
92 public Map<Integer, Integer> onPreface(Session session)
93 {
94 Map<Integer, Integer> settings = new HashMap<>();
95 settings.put(SettingsFrame.HEADER_TABLE_SIZE, getMaxDynamicTableSize());
96 settings.put(SettingsFrame.INITIAL_WINDOW_SIZE, getInitialStreamRecvWindow());
97 int maxConcurrentStreams = getMaxConcurrentStreams();
98 if (maxConcurrentStreams >= 0)
99 settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
100 settings.put(SettingsFrame.MAX_HEADER_LIST_SIZE, getHttpConfiguration().getRequestHeaderSize());
101 return settings;
102 }
103
104 @Override
105 public void onSettings(Session session, SettingsFrame frame)
106 {
107 HttpConfiguration httpConfig = getHttpConfiguration();
108 Integer mhls = frame.getSettings().get(SettingsFrame.MAX_HEADER_LIST_SIZE);
109 if (mhls != null && mhls < httpConfig.getResponseHeaderSize())
110 LOG.warn("MAX_HEADER_LIST_SIZE<{} for {}",getHttpConfiguration().getResponseHeaderSize(),session);
111 }
112
113 @Override
114 public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
115 {
116 getConnection().onNewStream(connector, (IStream)stream, frame);
117 return frame.isEndStream() ? null : this;
118 }
119
120 @Override
121 public void onHeaders(Stream stream, HeadersFrame frame)
122 {
123
124 close(stream, "response_headers");
125 }
126
127 @Override
128 public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
129 {
130
131 close(stream, "push_promise");
132 return null;
133 }
134
135 @Override
136 public void onData(Stream stream, DataFrame frame, Callback callback)
137 {
138 getConnection().onData((IStream)stream, frame, callback);
139 }
140
141 @Override
142 public void onReset(Stream stream, ResetFrame frame)
143 {
144
145 }
146
147 @Override
148 public void onTimeout(Stream stream, Throwable x)
149 {
150
151 }
152
153 private void close(Stream stream, String reason)
154 {
155 final Session session = stream.getSession();
156 session.close(ErrorCode.PROTOCOL_ERROR.code, reason, Callback.NOOP);
157 }
158 }
159
160 }