1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.spdy.proxy;
20
21 import java.net.InetSocketAddress;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.concurrent.ConcurrentHashMap;
25
26 import org.eclipse.jetty.spdy.api.GoAwayInfo;
27 import org.eclipse.jetty.spdy.api.Headers;
28 import org.eclipse.jetty.spdy.api.PingInfo;
29 import org.eclipse.jetty.spdy.api.RstInfo;
30 import org.eclipse.jetty.spdy.api.Session;
31 import org.eclipse.jetty.spdy.api.Stream;
32 import org.eclipse.jetty.spdy.api.StreamFrameListener;
33 import org.eclipse.jetty.spdy.api.StreamStatus;
34 import org.eclipse.jetty.spdy.api.SynInfo;
35 import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
36 import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
37 import org.eclipse.jetty.util.log.Log;
38 import org.eclipse.jetty.util.log.Logger;
39
40
41
42
43
44
45
46
47
48
49
50 public class ProxyEngineSelector extends ServerSessionFrameListener.Adapter
51 {
52 protected final Logger logger = Log.getLogger(getClass());
53 private final Map<String, ProxyServerInfo> proxyInfos = new ConcurrentHashMap<>();
54 private final Map<String, ProxyEngine> proxyEngines = new ConcurrentHashMap<>();
55
56 @Override
57 public final StreamFrameListener onSyn(final Stream clientStream, SynInfo clientSynInfo)
58 {
59 logger.debug("C -> P {} on {}", clientSynInfo, clientStream);
60
61 final Session clientSession = clientStream.getSession();
62 short clientVersion = clientSession.getVersion();
63 Headers headers = new Headers(clientSynInfo.getHeaders(), false);
64
65 Headers.Header hostHeader = headers.get(HTTPSPDYHeader.HOST.name(clientVersion));
66 if (hostHeader == null)
67 {
68 logger.debug("No host header found: " + headers);
69 rst(clientStream);
70 return null;
71 }
72
73 String host = hostHeader.value();
74 int colon = host.indexOf(':');
75 if (colon >= 0)
76 host = host.substring(0, colon);
77
78 ProxyServerInfo proxyServerInfo = getProxyServerInfo(host);
79 if (proxyServerInfo == null)
80 {
81 logger.debug("No matching ProxyServerInfo found for: " + host);
82 rst(clientStream);
83 return null;
84 }
85
86 String protocol = proxyServerInfo.getProtocol();
87 ProxyEngine proxyEngine = proxyEngines.get(protocol);
88 if (proxyEngine == null)
89 {
90 logger.debug("No matching ProxyEngine found for: " + protocol);
91 rst(clientStream);
92 return null;
93 }
94
95 return proxyEngine.proxy(clientStream, clientSynInfo, proxyServerInfo);
96 }
97
98 @Override
99 public void onPing(Session clientSession, PingInfo pingInfo)
100 {
101
102
103 }
104
105 @Override
106 public void onGoAway(Session session, GoAwayInfo goAwayInfo)
107 {
108
109 }
110
111 public Map<String, ProxyEngine> getProxyEngines()
112 {
113 return new HashMap<>(proxyEngines);
114 }
115
116 public void setProxyEngines(Map<String, ProxyEngine> proxyEngines)
117 {
118 this.proxyEngines.clear();
119 this.proxyEngines.putAll(proxyEngines);
120 }
121
122 public ProxyEngine getProxyEngine(String protocol)
123 {
124 return proxyEngines.get(protocol);
125 }
126
127 public void putProxyEngine(String protocol, ProxyEngine proxyEngine)
128 {
129 proxyEngines.put(protocol, proxyEngine);
130 }
131
132 public Map<String, ProxyServerInfo> getProxyServerInfos()
133 {
134 return new HashMap<>(proxyInfos);
135 }
136
137 protected ProxyServerInfo getProxyServerInfo(String host)
138 {
139 return proxyInfos.get(host);
140 }
141
142 public void setProxyServerInfos(Map<String, ProxyServerInfo> proxyServerInfos)
143 {
144 this.proxyInfos.clear();
145 this.proxyInfos.putAll(proxyServerInfos);
146 }
147
148 public void putProxyServerInfo(String host, ProxyServerInfo proxyServerInfo)
149 {
150 proxyInfos.put(host, proxyServerInfo);
151 }
152
153 private void rst(Stream stream)
154 {
155 RstInfo rstInfo = new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM);
156 stream.getSession().rst(rstInfo);
157 }
158
159 public static class ProxyServerInfo
160 {
161 private final String protocol;
162 private final String host;
163 private final InetSocketAddress address;
164
165 public ProxyServerInfo(String protocol, String host, int port)
166 {
167 this.protocol = protocol;
168 this.host = host;
169 this.address = new InetSocketAddress(host, port);
170 }
171
172 public String getProtocol()
173 {
174 return protocol;
175 }
176
177 public String getHost()
178 {
179 return host;
180 }
181
182 public InetSocketAddress getAddress()
183 {
184 return address;
185 }
186 }
187 }