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, getInitialStreamSendWindow());
97 int maxConcurrentStreams = getMaxConcurrentStreams();
98 if (maxConcurrentStreams >= 0)
99 settings.put(SettingsFrame.MAX_CONCURRENT_STREAMS, maxConcurrentStreams);
100 return settings;
101 }
102
103 @Override
104 public Stream.Listener onNewStream(Stream stream, HeadersFrame frame)
105 {
106 getConnection().onNewStream(connector, (IStream)stream, frame);
107 return frame.isEndStream() ? null : this;
108 }
109
110 @Override
111 public void onHeaders(Stream stream, HeadersFrame frame)
112 {
113
114 close(stream, "response_headers");
115 }
116
117 @Override
118 public Stream.Listener onPush(Stream stream, PushPromiseFrame frame)
119 {
120
121 close(stream, "push_promise");
122 return null;
123 }
124
125 @Override
126 public void onData(Stream stream, DataFrame frame, Callback callback)
127 {
128 getConnection().onData((IStream)stream, frame, callback);
129 }
130
131 @Override
132 public void onReset(Stream stream, ResetFrame frame)
133 {
134
135 }
136
137 @Override
138 public void onTimeout(Stream stream, Throwable x)
139 {
140
141 }
142
143 private void close(Stream stream, String reason)
144 {
145 final Session session = stream.getSession();
146 session.close(ErrorCode.PROTOCOL_ERROR.code, reason, Callback.NOOP);
147 }
148 }
149
150 }