1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.server;
20
21 import java.net.InetSocketAddress;
22
23 import javax.servlet.ServletRequest;
24
25 import org.eclipse.jetty.http.HostPortHttpField;
26 import org.eclipse.jetty.http.HttpField;
27 import org.eclipse.jetty.http.HttpFields;
28 import org.eclipse.jetty.http.HttpHeader;
29 import org.eclipse.jetty.http.HttpScheme;
30 import org.eclipse.jetty.http.QuotedCSV;
31 import org.eclipse.jetty.server.HttpConfiguration.Customizer;
32 import org.eclipse.jetty.util.StringUtil;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class ForwardedRequestCustomizer implements Customizer
56 {
57 private HostPortHttpField _forcedHost;
58 private String _forwardedHeader = HttpHeader.FORWARDED.toString();
59 private String _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
60 private String _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
61 private String _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
62 private String _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
63 private String _forwardedHttpsHeader = "X-Proxied-Https";
64 private String _forwardedCipherSuiteHeader = "Proxy-auth-cert";
65 private String _forwardedSslSessionIdHeader = "Proxy-ssl-id";
66 private boolean _proxyAsAuthority=false;
67 private boolean _sslIsSecure=true;
68
69
70
71
72
73
74 public boolean getProxyAsAuthority()
75 {
76 return _proxyAsAuthority;
77 }
78
79
80
81
82
83 public void setProxyAsAuthority(boolean proxyAsAuthority)
84 {
85 _proxyAsAuthority = proxyAsAuthority;
86 }
87
88
89
90
91
92
93
94 public void setForwardedOnly(boolean rfc7239only)
95 {
96 if (rfc7239only)
97 {
98 if (_forwardedHeader==null)
99 _forwardedHeader=HttpHeader.FORWARDED.toString();
100 _forwardedHostHeader=null;
101 _forwardedHostHeader=null;
102 _forwardedServerHeader=null;
103 _forwardedForHeader=null;
104 _forwardedProtoHeader=null;
105 _forwardedHttpsHeader=null;
106 }
107 else
108 {
109 if (_forwardedHostHeader==null)
110 _forwardedHostHeader = HttpHeader.X_FORWARDED_HOST.toString();
111 if (_forwardedServerHeader==null)
112 _forwardedServerHeader = HttpHeader.X_FORWARDED_SERVER.toString();
113 if (_forwardedForHeader==null)
114 _forwardedForHeader = HttpHeader.X_FORWARDED_FOR.toString();
115 if (_forwardedProtoHeader==null)
116 _forwardedProtoHeader = HttpHeader.X_FORWARDED_PROTO.toString();
117 if (_forwardedHttpsHeader==null)
118 _forwardedHttpsHeader = "X-Proxied-Https";
119 }
120 }
121
122 public String getForcedHost()
123 {
124 return _forcedHost.getValue();
125 }
126
127
128
129
130
131
132
133 public void setForcedHost(String hostAndPort)
134 {
135 _forcedHost = new HostPortHttpField(hostAndPort);
136 }
137
138
139
140
141 public String getForwardedHeader()
142 {
143 return _forwardedHeader;
144 }
145
146
147
148
149
150 public void setForwardedHeader(String forwardedHeader)
151 {
152 _forwardedHeader = forwardedHeader;
153 }
154
155 public String getForwardedHostHeader()
156 {
157 return _forwardedHostHeader;
158 }
159
160
161
162
163
164 public void setForwardedHostHeader(String forwardedHostHeader)
165 {
166 _forwardedHostHeader = forwardedHostHeader;
167 }
168
169
170
171
172 public String getForwardedServerHeader()
173 {
174 return _forwardedServerHeader;
175 }
176
177
178
179
180
181 public void setForwardedServerHeader(String forwardedServerHeader)
182 {
183 _forwardedServerHeader = forwardedServerHeader;
184 }
185
186
187
188
189 public String getForwardedForHeader()
190 {
191 return _forwardedForHeader;
192 }
193
194
195
196
197
198 public void setForwardedForHeader(String forwardedRemoteAddressHeader)
199 {
200 _forwardedForHeader = forwardedRemoteAddressHeader;
201 }
202
203
204
205
206
207
208 public String getForwardedProtoHeader()
209 {
210 return _forwardedProtoHeader;
211 }
212
213
214
215
216
217
218
219 public void setForwardedProtoHeader(String forwardedProtoHeader)
220 {
221 _forwardedProtoHeader = forwardedProtoHeader;
222 }
223
224
225
226
227 public String getForwardedCipherSuiteHeader()
228 {
229 return _forwardedCipherSuiteHeader;
230 }
231
232
233
234
235
236 public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
237 {
238 _forwardedCipherSuiteHeader = forwardedCipherSuite;
239 }
240
241
242
243
244 public String getForwardedSslSessionIdHeader()
245 {
246 return _forwardedSslSessionIdHeader;
247 }
248
249
250
251
252
253 public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
254 {
255 _forwardedSslSessionIdHeader = forwardedSslSessionId;
256 }
257
258
259
260
261 public String getForwardedHttpsHeader()
262 {
263 return _forwardedHttpsHeader;
264 }
265
266
267
268
269 public void setForwardedHttpsHeader(String forwardedHttpsHeader)
270 {
271 _forwardedHttpsHeader = forwardedHttpsHeader;
272 }
273
274
275
276
277
278 public boolean isSslIsSecure()
279 {
280 return _sslIsSecure;
281 }
282
283
284
285
286
287 public void setSslIsSecure(boolean sslIsSecure)
288 {
289 _sslIsSecure = sslIsSecure;
290 }
291
292 @Override
293 public void customize(Connector connector, HttpConfiguration config, Request request)
294 {
295 HttpFields httpFields = request.getHttpFields();
296
297 RFC7239 rfc7239 = null;
298 String forwardedHost = null;
299 String forwardedServer = null;
300 String forwardedFor = null;
301 String forwardedProto = null;
302 String forwardedHttps = null;
303
304
305 for (HttpField field : httpFields)
306 {
307 String name = field.getName();
308
309 if (getForwardedCipherSuiteHeader()!=null && getForwardedCipherSuiteHeader().equalsIgnoreCase(name))
310 {
311 request.setAttribute("javax.servlet.request.cipher_suite",field.getValue());
312 if (isSslIsSecure())
313 {
314 request.setSecure(true);
315 request.setScheme(config.getSecureScheme());
316 }
317 }
318
319 if (getForwardedSslSessionIdHeader()!=null && getForwardedSslSessionIdHeader().equalsIgnoreCase(name))
320 {
321 request.setAttribute("javax.servlet.request.ssl_session_id", field.getValue());
322 if (isSslIsSecure())
323 {
324 request.setSecure(true);
325 request.setScheme(config.getSecureScheme());
326 }
327 }
328
329 if (forwardedHost==null && _forwardedHostHeader!=null && _forwardedHostHeader.equalsIgnoreCase(name))
330 forwardedHost = getLeftMost(field.getValue());
331
332 if (forwardedServer==null && _forwardedServerHeader!=null && _forwardedServerHeader.equalsIgnoreCase(name))
333 forwardedServer = getLeftMost(field.getValue());
334
335 if (forwardedFor==null && _forwardedForHeader!=null && _forwardedForHeader.equalsIgnoreCase(name))
336 forwardedFor = getLeftMost(field.getValue());
337
338 if (forwardedProto==null && _forwardedProtoHeader!=null && _forwardedProtoHeader.equalsIgnoreCase(name))
339 forwardedProto = getLeftMost(field.getValue());
340
341 if (forwardedHttps==null && _forwardedHttpsHeader!=null && _forwardedHttpsHeader.equalsIgnoreCase(name))
342 forwardedHttps = getLeftMost(field.getValue());
343
344 if (_forwardedHeader!=null && _forwardedHeader.equalsIgnoreCase(name))
345 {
346 if (rfc7239==null)
347 rfc7239= new RFC7239();
348 rfc7239.addValue(field.getValue());
349 }
350 }
351
352
353 if (_forcedHost != null)
354 {
355
356 httpFields.put(_forcedHost);
357 request.setAuthority(_forcedHost.getHost(),_forcedHost.getPort());
358 }
359 else if (rfc7239!=null && rfc7239._host!=null)
360 {
361 HostPortHttpField auth = rfc7239._host;
362 httpFields.put(auth);
363 request.setAuthority(auth.getHost(),auth.getPort());
364 }
365 else if (forwardedHost != null)
366 {
367 HostPortHttpField auth = new HostPortHttpField(forwardedHost);
368 httpFields.put(auth);
369 request.setAuthority(auth.getHost(),auth.getPort());
370 }
371 else if (_proxyAsAuthority)
372 {
373 if (rfc7239!=null && rfc7239._by!=null)
374 {
375 HostPortHttpField auth = rfc7239._by;
376 httpFields.put(auth);
377 request.setAuthority(auth.getHost(),auth.getPort());
378 }
379 else if (forwardedServer != null)
380 {
381 request.setAuthority(forwardedServer,request.getServerPort());
382 }
383 }
384
385
386 if (rfc7239!=null && rfc7239._for!=null)
387 {
388 request.setRemoteAddr(InetSocketAddress.createUnresolved(rfc7239._for.getHost(),rfc7239._for.getPort()));
389 }
390 else if (forwardedFor != null)
391 {
392 request.setRemoteAddr(InetSocketAddress.createUnresolved(forwardedFor,request.getRemotePort()));
393 }
394
395
396 if (rfc7239!=null && rfc7239._proto!=null)
397 {
398 request.setScheme(rfc7239._proto);
399 if (rfc7239._proto.equals(config.getSecureScheme()))
400 request.setSecure(true);
401 }
402 else if (forwardedProto != null)
403 {
404 request.setScheme(forwardedProto);
405 if (forwardedProto.equals(config.getSecureScheme()))
406 request.setSecure(true);
407 }
408 else if (forwardedHttps !=null && ("on".equalsIgnoreCase(forwardedHttps)||"true".equalsIgnoreCase(forwardedHttps)))
409 {
410 request.setScheme(HttpScheme.HTTPS.asString());
411 if (HttpScheme.HTTPS.asString().equals(config.getSecureScheme()))
412 request.setSecure(true);
413 }
414 }
415
416
417 protected String getLeftMost(String headerValue)
418 {
419 if (headerValue == null)
420 return null;
421
422 int commaIndex = headerValue.indexOf(',');
423
424 if (commaIndex == -1)
425 {
426
427 return headerValue;
428 }
429
430
431 return headerValue.substring(0,commaIndex).trim();
432 }
433
434 @Override
435 public String toString()
436 {
437 return String.format("%s@%x",this.getClass().getSimpleName(),hashCode());
438 }
439
440 @Deprecated
441 public String getHostHeader()
442 {
443 return _forcedHost.getValue();
444 }
445
446
447
448
449
450
451
452 @Deprecated
453 public void setHostHeader(String hostHeader)
454 {
455 _forcedHost = new HostPortHttpField(hostHeader);
456 }
457
458 private final class RFC7239 extends QuotedCSV
459 {
460 HostPortHttpField _by;
461 HostPortHttpField _for;
462 HostPortHttpField _host;
463 String _proto;
464
465 private RFC7239()
466 {
467 super(false);
468 }
469
470 @Override
471 protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue)
472 {
473 if (valueLength==0 && paramValue>paramName)
474 {
475 String name=StringUtil.asciiToLowerCase(buffer.substring(paramName,paramValue-1));
476 String value=buffer.substring(paramValue);
477 switch(name)
478 {
479 case "by":
480 if (_by==null && !value.startsWith("_") && !"unknown".equals(value))
481 _by=new HostPortHttpField(value);
482 break;
483 case "for":
484 if (_for==null && !value.startsWith("_") && !"unknown".equals(value))
485 _for=new HostPortHttpField(value);
486 break;
487 case "host":
488 if (_host==null)
489 _host=new HostPortHttpField(value);
490 break;
491 case "proto":
492 if (_proto==null)
493 _proto=value;
494 break;
495 }
496 }
497 }
498 }
499 }