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