Mercurial Hosting > luan
comparison src/org/eclipse/jetty/server/AbstractConnector.java @ 802:3428c60d7cfc
replace jetty jars with source
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Wed, 07 Sep 2016 21:15:48 -0600 |
parents | |
children | ad292e148964 |
comparison
equal
deleted
inserted
replaced
801:6a21393191c1 | 802:3428c60d7cfc |
---|---|
1 // | |
2 // ======================================================================== | |
3 // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. | |
4 // ------------------------------------------------------------------------ | |
5 // All rights reserved. This program and the accompanying materials | |
6 // are made available under the terms of the Eclipse Public License v1.0 | |
7 // and Apache License v2.0 which accompanies this distribution. | |
8 // | |
9 // The Eclipse Public License is available at | |
10 // http://www.eclipse.org/legal/epl-v10.html | |
11 // | |
12 // The Apache License v2.0 is available at | |
13 // http://www.opensource.org/licenses/apache2.0.php | |
14 // | |
15 // You may elect to redistribute this code under either of these licenses. | |
16 // ======================================================================== | |
17 // | |
18 | |
19 package org.eclipse.jetty.server; | |
20 | |
21 import java.io.IOException; | |
22 import java.net.InetAddress; | |
23 import java.net.Socket; | |
24 import java.net.UnknownHostException; | |
25 import java.util.concurrent.atomic.AtomicLong; | |
26 | |
27 import javax.servlet.ServletRequest; | |
28 | |
29 import org.eclipse.jetty.http.HttpBuffers; | |
30 import org.eclipse.jetty.http.HttpBuffersImpl; | |
31 import org.eclipse.jetty.http.HttpFields; | |
32 import org.eclipse.jetty.http.HttpHeaders; | |
33 import org.eclipse.jetty.http.HttpSchemes; | |
34 import org.eclipse.jetty.io.Buffers; | |
35 import org.eclipse.jetty.io.Buffers.Type; | |
36 import org.eclipse.jetty.io.Connection; | |
37 import org.eclipse.jetty.io.EndPoint; | |
38 import org.eclipse.jetty.io.EofException; | |
39 import org.eclipse.jetty.util.component.AggregateLifeCycle; | |
40 import org.eclipse.jetty.util.component.Dumpable; | |
41 import org.eclipse.jetty.util.log.Log; | |
42 import org.eclipse.jetty.util.log.Logger; | |
43 import org.eclipse.jetty.util.statistic.CounterStatistic; | |
44 import org.eclipse.jetty.util.statistic.SampleStatistic; | |
45 import org.eclipse.jetty.util.thread.ThreadPool; | |
46 | |
47 /** | |
48 * Abstract Connector implementation. This abstract implementation of the Connector interface provides: | |
49 * <ul> | |
50 * <li>AbstractLifeCycle implementation</li> | |
51 * <li>Implementations for connector getters and setters</li> | |
52 * <li>Buffer management</li> | |
53 * <li>Socket configuration</li> | |
54 * <li>Base acceptor thread</li> | |
55 * <li>Optional reverse proxy headers checking</li> | |
56 * </ul> | |
57 */ | |
58 public abstract class AbstractConnector extends AggregateLifeCycle implements HttpBuffers, Connector, Dumpable | |
59 { | |
60 private static final Logger LOG = Log.getLogger(AbstractConnector.class); | |
61 | |
62 private String _name; | |
63 | |
64 private Server _server; | |
65 private ThreadPool _threadPool; | |
66 private String _host; | |
67 private int _port = 0; | |
68 private String _integralScheme = HttpSchemes.HTTPS; | |
69 private int _integralPort = 0; | |
70 private String _confidentialScheme = HttpSchemes.HTTPS; | |
71 private int _confidentialPort = 0; | |
72 private int _acceptQueueSize = 0; | |
73 private int _acceptors = 1; | |
74 private int _acceptorPriorityOffset = 0; | |
75 private boolean _useDNS; | |
76 private boolean _forwarded; | |
77 private String _hostHeader; | |
78 | |
79 private String _forwardedHostHeader = HttpHeaders.X_FORWARDED_HOST; | |
80 private String _forwardedServerHeader = HttpHeaders.X_FORWARDED_SERVER; | |
81 private String _forwardedForHeader = HttpHeaders.X_FORWARDED_FOR; | |
82 private String _forwardedProtoHeader = HttpHeaders.X_FORWARDED_PROTO; | |
83 private String _forwardedCipherSuiteHeader; | |
84 private String _forwardedSslSessionIdHeader; | |
85 private boolean _reuseAddress = true; | |
86 | |
87 protected int _maxIdleTime = 200000; | |
88 protected int _lowResourceMaxIdleTime = -1; | |
89 protected int _soLingerTime = -1; | |
90 | |
91 private transient Thread[] _acceptorThreads; | |
92 | |
93 private final AtomicLong _statsStartedAt = new AtomicLong(-1L); | |
94 | |
95 /** connections to server */ | |
96 private final CounterStatistic _connectionStats = new CounterStatistic(); | |
97 /** requests per connection */ | |
98 private final SampleStatistic _requestStats = new SampleStatistic(); | |
99 /** duration of a connection */ | |
100 private final SampleStatistic _connectionDurationStats = new SampleStatistic(); | |
101 | |
102 protected final HttpBuffersImpl _buffers = new HttpBuffersImpl(); | |
103 | |
104 /* ------------------------------------------------------------ */ | |
105 /** | |
106 */ | |
107 public AbstractConnector() | |
108 { | |
109 addBean(_buffers); | |
110 } | |
111 | |
112 /* ------------------------------------------------------------ */ | |
113 /* | |
114 */ | |
115 public Server getServer() | |
116 { | |
117 return _server; | |
118 } | |
119 | |
120 /* ------------------------------------------------------------ */ | |
121 public void setServer(Server server) | |
122 { | |
123 _server = server; | |
124 } | |
125 | |
126 /* ------------------------------------------------------------ */ | |
127 public ThreadPool getThreadPool() | |
128 { | |
129 return _threadPool; | |
130 } | |
131 | |
132 /* ------------------------------------------------------------ */ | |
133 /** Set the ThreadPool. | |
134 * The threadpool passed is added via {@link #addBean(Object)} so that | |
135 * it's lifecycle may be managed as a {@link AggregateLifeCycle}. | |
136 * @param pool the threadPool to set | |
137 */ | |
138 public void setThreadPool(ThreadPool pool) | |
139 { | |
140 removeBean(_threadPool); | |
141 _threadPool = pool; | |
142 addBean(_threadPool); | |
143 } | |
144 | |
145 /* ------------------------------------------------------------ */ | |
146 /** | |
147 */ | |
148 public void setHost(String host) | |
149 { | |
150 _host = host; | |
151 } | |
152 | |
153 /* ------------------------------------------------------------ */ | |
154 /* | |
155 */ | |
156 public String getHost() | |
157 { | |
158 return _host; | |
159 } | |
160 | |
161 /* ------------------------------------------------------------ */ | |
162 public void setPort(int port) | |
163 { | |
164 _port = port; | |
165 } | |
166 | |
167 /* ------------------------------------------------------------ */ | |
168 public int getPort() | |
169 { | |
170 return _port; | |
171 } | |
172 | |
173 /* ------------------------------------------------------------ */ | |
174 /** | |
175 * @return Returns the maxIdleTime. | |
176 */ | |
177 public int getMaxIdleTime() | |
178 { | |
179 return _maxIdleTime; | |
180 } | |
181 | |
182 /* ------------------------------------------------------------ */ | |
183 /** | |
184 * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations | |
185 * other mechanisms may be used to implement the timeout. The max idle time is applied: | |
186 * <ul> | |
187 * <li>When waiting for a new request to be received on a connection</li> | |
188 * <li>When reading the headers and content of a request</li> | |
189 * <li>When writing the headers and content of a response</li> | |
190 * </ul> | |
191 * Jetty interprets this value as the maximum time between some progress being made on the connection. So if a single byte is read or written, then the | |
192 * timeout (if implemented by jetty) is reset. However, in many instances, the reading/writing is delegated to the JVM, and the semantic is more strictly | |
193 * enforced as the maximum time a single read/write operation can take. Note, that as Jetty supports writes of memory mapped file buffers, then a write may | |
194 * take many 10s of seconds for large content written to a slow device. | |
195 * <p> | |
196 * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so | |
197 * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand). | |
198 * | |
199 * @param maxIdleTime | |
200 * The maxIdleTime to set. | |
201 */ | |
202 public void setMaxIdleTime(int maxIdleTime) | |
203 { | |
204 _maxIdleTime = maxIdleTime; | |
205 } | |
206 | |
207 /* ------------------------------------------------------------ */ | |
208 /** | |
209 * @return Returns the maxIdleTime when resources are low. | |
210 */ | |
211 public int getLowResourcesMaxIdleTime() | |
212 { | |
213 return _lowResourceMaxIdleTime; | |
214 } | |
215 | |
216 /* ------------------------------------------------------------ */ | |
217 /** | |
218 * @param maxIdleTime | |
219 * The maxIdleTime to set when resources are low. | |
220 */ | |
221 public void setLowResourcesMaxIdleTime(int maxIdleTime) | |
222 { | |
223 _lowResourceMaxIdleTime = maxIdleTime; | |
224 } | |
225 | |
226 /* ------------------------------------------------------------ */ | |
227 /** | |
228 * @return Returns the maxIdleTime when resources are low. | |
229 * @deprecated | |
230 */ | |
231 @Deprecated | |
232 public final int getLowResourceMaxIdleTime() | |
233 { | |
234 return getLowResourcesMaxIdleTime(); | |
235 } | |
236 | |
237 /* ------------------------------------------------------------ */ | |
238 /** | |
239 * @param maxIdleTime | |
240 * The maxIdleTime to set when resources are low. | |
241 * @deprecated | |
242 */ | |
243 @Deprecated | |
244 public final void setLowResourceMaxIdleTime(int maxIdleTime) | |
245 { | |
246 setLowResourcesMaxIdleTime(maxIdleTime); | |
247 } | |
248 | |
249 /* ------------------------------------------------------------ */ | |
250 /** | |
251 * @return Returns the soLingerTime. | |
252 */ | |
253 public int getSoLingerTime() | |
254 { | |
255 return _soLingerTime; | |
256 } | |
257 | |
258 /* ------------------------------------------------------------ */ | |
259 /** | |
260 * @return Returns the acceptQueueSize. | |
261 */ | |
262 public int getAcceptQueueSize() | |
263 { | |
264 return _acceptQueueSize; | |
265 } | |
266 | |
267 /* ------------------------------------------------------------ */ | |
268 /** | |
269 * @param acceptQueueSize | |
270 * The acceptQueueSize to set. | |
271 */ | |
272 public void setAcceptQueueSize(int acceptQueueSize) | |
273 { | |
274 _acceptQueueSize = acceptQueueSize; | |
275 } | |
276 | |
277 /* ------------------------------------------------------------ */ | |
278 /** | |
279 * @return Returns the number of acceptor threads. | |
280 */ | |
281 public int getAcceptors() | |
282 { | |
283 return _acceptors; | |
284 } | |
285 | |
286 /* ------------------------------------------------------------ */ | |
287 /** | |
288 * @param acceptors | |
289 * The number of acceptor threads to set. | |
290 */ | |
291 public void setAcceptors(int acceptors) | |
292 { | |
293 if (acceptors > 2 * Runtime.getRuntime().availableProcessors()) | |
294 LOG.warn("Acceptors should be <=2*availableProcessors: " + this); | |
295 _acceptors = acceptors; | |
296 } | |
297 | |
298 /* ------------------------------------------------------------ */ | |
299 /** | |
300 * @param soLingerTime | |
301 * The soLingerTime to set or -1 to disable. | |
302 */ | |
303 public void setSoLingerTime(int soLingerTime) | |
304 { | |
305 _soLingerTime = soLingerTime; | |
306 } | |
307 | |
308 /* ------------------------------------------------------------ */ | |
309 @Override | |
310 protected void doStart() throws Exception | |
311 { | |
312 if (_server == null) | |
313 throw new IllegalStateException("No server"); | |
314 | |
315 // open listener port | |
316 open(); | |
317 | |
318 if (_threadPool == null) | |
319 { | |
320 _threadPool = _server.getThreadPool(); | |
321 addBean(_threadPool,false); | |
322 } | |
323 | |
324 super.doStart(); | |
325 | |
326 // Start selector thread | |
327 synchronized (this) | |
328 { | |
329 _acceptorThreads = new Thread[getAcceptors()]; | |
330 | |
331 for (int i = 0; i < _acceptorThreads.length; i++) | |
332 if (!_threadPool.dispatch(new Acceptor(i))) | |
333 throw new IllegalStateException("!accepting"); | |
334 if (_threadPool.isLowOnThreads()) | |
335 LOG.warn("insufficient threads configured for {}",this); | |
336 } | |
337 | |
338 LOG.info("Started {}",this); | |
339 } | |
340 | |
341 /* ------------------------------------------------------------ */ | |
342 @Override | |
343 protected void doStop() throws Exception | |
344 { | |
345 try | |
346 { | |
347 close(); | |
348 } | |
349 catch (IOException e) | |
350 { | |
351 LOG.warn(e); | |
352 } | |
353 | |
354 super.doStop(); | |
355 | |
356 Thread[] acceptors; | |
357 synchronized (this) | |
358 { | |
359 acceptors = _acceptorThreads; | |
360 _acceptorThreads = null; | |
361 } | |
362 if (acceptors != null) | |
363 { | |
364 for (Thread thread : acceptors) | |
365 { | |
366 if (thread != null) | |
367 thread.interrupt(); | |
368 } | |
369 } | |
370 } | |
371 | |
372 /* ------------------------------------------------------------ */ | |
373 public void join() throws InterruptedException | |
374 { | |
375 Thread[] threads; | |
376 synchronized(this) | |
377 { | |
378 threads=_acceptorThreads; | |
379 } | |
380 if (threads != null) | |
381 for (Thread thread : threads) | |
382 if (thread != null) | |
383 thread.join(); | |
384 } | |
385 | |
386 /* ------------------------------------------------------------ */ | |
387 protected void configure(Socket socket) throws IOException | |
388 { | |
389 try | |
390 { | |
391 socket.setTcpNoDelay(true); | |
392 if (_soLingerTime >= 0) | |
393 socket.setSoLinger(true,_soLingerTime / 1000); | |
394 else | |
395 socket.setSoLinger(false,0); | |
396 } | |
397 catch (Exception e) | |
398 { | |
399 LOG.ignore(e); | |
400 } | |
401 } | |
402 | |
403 /* ------------------------------------------------------------ */ | |
404 public void customize(EndPoint endpoint, Request request) throws IOException | |
405 { | |
406 if (isForwarded()) | |
407 checkForwardedHeaders(endpoint,request); | |
408 } | |
409 | |
410 /* ------------------------------------------------------------ */ | |
411 protected void checkForwardedHeaders(EndPoint endpoint, Request request) throws IOException | |
412 { | |
413 HttpFields httpFields = request.getConnection().getRequestFields(); | |
414 | |
415 // Do SSL first | |
416 if (getForwardedCipherSuiteHeader()!=null) | |
417 { | |
418 String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader()); | |
419 if (cipher_suite!=null) | |
420 request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite); | |
421 } | |
422 if (getForwardedSslSessionIdHeader()!=null) | |
423 { | |
424 String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader()); | |
425 if(ssl_session_id!=null) | |
426 { | |
427 request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id); | |
428 request.setScheme(HttpSchemes.HTTPS); | |
429 } | |
430 } | |
431 | |
432 // Retrieving headers from the request | |
433 String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader()); | |
434 String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader()); | |
435 String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader()); | |
436 String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader()); | |
437 | |
438 if (_hostHeader != null) | |
439 { | |
440 // Update host header | |
441 httpFields.put(HttpHeaders.HOST_BUFFER,_hostHeader); | |
442 request.setServerName(null); | |
443 request.setServerPort(-1); | |
444 request.getServerName(); | |
445 } | |
446 else if (forwardedHost != null) | |
447 { | |
448 // Update host header | |
449 httpFields.put(HttpHeaders.HOST_BUFFER,forwardedHost); | |
450 request.setServerName(null); | |
451 request.setServerPort(-1); | |
452 request.getServerName(); | |
453 } | |
454 else if (forwardedServer != null) | |
455 { | |
456 // Use provided server name | |
457 request.setServerName(forwardedServer); | |
458 } | |
459 | |
460 if (forwardedFor != null) | |
461 { | |
462 request.setRemoteAddr(forwardedFor); | |
463 InetAddress inetAddress = null; | |
464 | |
465 if (_useDNS) | |
466 { | |
467 try | |
468 { | |
469 inetAddress = InetAddress.getByName(forwardedFor); | |
470 } | |
471 catch (UnknownHostException e) | |
472 { | |
473 LOG.ignore(e); | |
474 } | |
475 } | |
476 | |
477 request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName()); | |
478 } | |
479 | |
480 if (forwardedProto != null) | |
481 { | |
482 request.setScheme(forwardedProto); | |
483 } | |
484 } | |
485 | |
486 /* ------------------------------------------------------------ */ | |
487 protected String getLeftMostFieldValue(HttpFields fields, String header) | |
488 { | |
489 if (header == null) | |
490 return null; | |
491 | |
492 String headerValue = fields.getStringField(header); | |
493 | |
494 if (headerValue == null) | |
495 return null; | |
496 | |
497 int commaIndex = headerValue.indexOf(','); | |
498 | |
499 if (commaIndex == -1) | |
500 { | |
501 // Single value | |
502 return headerValue; | |
503 } | |
504 | |
505 // The left-most value is the farthest downstream client | |
506 return headerValue.substring(0,commaIndex); | |
507 } | |
508 | |
509 /* ------------------------------------------------------------ */ | |
510 public void persist(EndPoint endpoint) throws IOException | |
511 { | |
512 } | |
513 | |
514 /* ------------------------------------------------------------ */ | |
515 /* | |
516 * @see org.eclipse.jetty.server.Connector#getConfidentialPort() | |
517 */ | |
518 public int getConfidentialPort() | |
519 { | |
520 return _confidentialPort; | |
521 } | |
522 | |
523 /* ------------------------------------------------------------ */ | |
524 /* ------------------------------------------------------------ */ | |
525 /* | |
526 * @see org.eclipse.jetty.server.Connector#getConfidentialScheme() | |
527 */ | |
528 public String getConfidentialScheme() | |
529 { | |
530 return _confidentialScheme; | |
531 } | |
532 | |
533 /* ------------------------------------------------------------ */ | |
534 /* | |
535 * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server .Request) | |
536 */ | |
537 public boolean isIntegral(Request request) | |
538 { | |
539 return false; | |
540 } | |
541 | |
542 /* ------------------------------------------------------------ */ | |
543 /* | |
544 * @see org.eclipse.jetty.server.Connector#getConfidentialPort() | |
545 */ | |
546 public int getIntegralPort() | |
547 { | |
548 return _integralPort; | |
549 } | |
550 | |
551 /* ------------------------------------------------------------ */ | |
552 /* | |
553 * @see org.eclipse.jetty.server.Connector#getIntegralScheme() | |
554 */ | |
555 public String getIntegralScheme() | |
556 { | |
557 return _integralScheme; | |
558 } | |
559 | |
560 /* ------------------------------------------------------------ */ | |
561 /* | |
562 * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request) | |
563 */ | |
564 public boolean isConfidential(Request request) | |
565 { | |
566 return _forwarded && request.getScheme().equalsIgnoreCase(HttpSchemes.HTTPS); | |
567 } | |
568 | |
569 /* ------------------------------------------------------------ */ | |
570 /** | |
571 * @param confidentialPort | |
572 * The confidentialPort to set. | |
573 */ | |
574 public void setConfidentialPort(int confidentialPort) | |
575 { | |
576 _confidentialPort = confidentialPort; | |
577 } | |
578 | |
579 /* ------------------------------------------------------------ */ | |
580 /** | |
581 * @param confidentialScheme | |
582 * The confidentialScheme to set. | |
583 */ | |
584 public void setConfidentialScheme(String confidentialScheme) | |
585 { | |
586 _confidentialScheme = confidentialScheme; | |
587 } | |
588 | |
589 /* ------------------------------------------------------------ */ | |
590 /** | |
591 * @param integralPort | |
592 * The integralPort to set. | |
593 */ | |
594 public void setIntegralPort(int integralPort) | |
595 { | |
596 _integralPort = integralPort; | |
597 } | |
598 | |
599 /* ------------------------------------------------------------ */ | |
600 /** | |
601 * @param integralScheme | |
602 * The integralScheme to set. | |
603 */ | |
604 public void setIntegralScheme(String integralScheme) | |
605 { | |
606 _integralScheme = integralScheme; | |
607 } | |
608 | |
609 /* ------------------------------------------------------------ */ | |
610 protected abstract void accept(int acceptorID) throws IOException, InterruptedException; | |
611 | |
612 /* ------------------------------------------------------------ */ | |
613 public void stopAccept(int acceptorID) throws Exception | |
614 { | |
615 } | |
616 | |
617 /* ------------------------------------------------------------ */ | |
618 public boolean getResolveNames() | |
619 { | |
620 return _useDNS; | |
621 } | |
622 | |
623 /* ------------------------------------------------------------ */ | |
624 public void setResolveNames(boolean resolve) | |
625 { | |
626 _useDNS = resolve; | |
627 } | |
628 | |
629 /* ------------------------------------------------------------ */ | |
630 /** | |
631 * Is reverse proxy handling on? | |
632 * | |
633 * @return true if this connector is checking the x-forwarded-for/host/server headers | |
634 */ | |
635 public boolean isForwarded() | |
636 { | |
637 return _forwarded; | |
638 } | |
639 | |
640 /* ------------------------------------------------------------ */ | |
641 /** | |
642 * Set reverse proxy handling. If set to true, then the X-Forwarded headers (or the headers set in their place) are looked for to set the request protocol, | |
643 * host, server and client ip. | |
644 * | |
645 * @param check | |
646 * true if this connector is checking the x-forwarded-for/host/server headers | |
647 * @see #setForwardedForHeader(String) | |
648 * @see #setForwardedHostHeader(String) | |
649 * @see #setForwardedProtoHeader(String) | |
650 * @see #setForwardedServerHeader(String) | |
651 */ | |
652 public void setForwarded(boolean check) | |
653 { | |
654 if (check) | |
655 LOG.debug("{} is forwarded",this); | |
656 _forwarded = check; | |
657 } | |
658 | |
659 /* ------------------------------------------------------------ */ | |
660 public String getHostHeader() | |
661 { | |
662 return _hostHeader; | |
663 } | |
664 | |
665 /* ------------------------------------------------------------ */ | |
666 /** | |
667 * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}. | |
668 * This value is only used if {@link #isForwarded()} is true. | |
669 * | |
670 * @param hostHeader | |
671 * The value of the host header to force. | |
672 */ | |
673 public void setHostHeader(String hostHeader) | |
674 { | |
675 _hostHeader = hostHeader; | |
676 } | |
677 | |
678 /* ------------------------------------------------------------ */ | |
679 /* | |
680 * | |
681 * @see #setForwarded(boolean) | |
682 */ | |
683 public String getForwardedHostHeader() | |
684 { | |
685 return _forwardedHostHeader; | |
686 } | |
687 | |
688 /* ------------------------------------------------------------ */ | |
689 /** | |
690 * @param forwardedHostHeader | |
691 * The header name for forwarded hosts (default x-forwarded-host) | |
692 * @see #setForwarded(boolean) | |
693 */ | |
694 public void setForwardedHostHeader(String forwardedHostHeader) | |
695 { | |
696 _forwardedHostHeader = forwardedHostHeader; | |
697 } | |
698 | |
699 /* ------------------------------------------------------------ */ | |
700 /** | |
701 * @return the header name for forwarded server. | |
702 * @see #setForwarded(boolean) | |
703 */ | |
704 public String getForwardedServerHeader() | |
705 { | |
706 return _forwardedServerHeader; | |
707 } | |
708 | |
709 /* ------------------------------------------------------------ */ | |
710 /** | |
711 * @param forwardedServerHeader | |
712 * The header name for forwarded server (default x-forwarded-server) | |
713 * @see #setForwarded(boolean) | |
714 */ | |
715 public void setForwardedServerHeader(String forwardedServerHeader) | |
716 { | |
717 _forwardedServerHeader = forwardedServerHeader; | |
718 } | |
719 | |
720 /* ------------------------------------------------------------ */ | |
721 /** | |
722 * @see #setForwarded(boolean) | |
723 */ | |
724 public String getForwardedForHeader() | |
725 { | |
726 return _forwardedForHeader; | |
727 } | |
728 | |
729 /* ------------------------------------------------------------ */ | |
730 /** | |
731 * @param forwardedRemoteAddressHeader | |
732 * The header name for forwarded for (default x-forwarded-for) | |
733 * @see #setForwarded(boolean) | |
734 */ | |
735 public void setForwardedForHeader(String forwardedRemoteAddressHeader) | |
736 { | |
737 _forwardedForHeader = forwardedRemoteAddressHeader; | |
738 } | |
739 | |
740 /* ------------------------------------------------------------ */ | |
741 /** | |
742 * Get the forwardedProtoHeader. | |
743 * | |
744 * @return the forwardedProtoHeader (default X-Forwarded-For) | |
745 * @see #setForwarded(boolean) | |
746 */ | |
747 public String getForwardedProtoHeader() | |
748 { | |
749 return _forwardedProtoHeader; | |
750 } | |
751 | |
752 /* ------------------------------------------------------------ */ | |
753 /** | |
754 * Set the forwardedProtoHeader. | |
755 * | |
756 * @param forwardedProtoHeader | |
757 * the forwardedProtoHeader to set (default X-Forwarded-For) | |
758 * @see #setForwarded(boolean) | |
759 */ | |
760 public void setForwardedProtoHeader(String forwardedProtoHeader) | |
761 { | |
762 _forwardedProtoHeader = forwardedProtoHeader; | |
763 } | |
764 | |
765 /* ------------------------------------------------------------ */ | |
766 /** | |
767 * @return The header name holding a forwarded cipher suite (default null) | |
768 */ | |
769 public String getForwardedCipherSuiteHeader() | |
770 { | |
771 return _forwardedCipherSuiteHeader; | |
772 } | |
773 | |
774 /* ------------------------------------------------------------ */ | |
775 /** | |
776 * @param forwardedCipherSuite | |
777 * The header name holding a forwarded cipher suite (default null) | |
778 */ | |
779 public void setForwardedCipherSuiteHeader(String forwardedCipherSuite) | |
780 { | |
781 _forwardedCipherSuiteHeader = forwardedCipherSuite; | |
782 } | |
783 | |
784 /* ------------------------------------------------------------ */ | |
785 /** | |
786 * @return The header name holding a forwarded SSL Session ID (default null) | |
787 */ | |
788 public String getForwardedSslSessionIdHeader() | |
789 { | |
790 return _forwardedSslSessionIdHeader; | |
791 } | |
792 | |
793 /* ------------------------------------------------------------ */ | |
794 /** | |
795 * @param forwardedSslSessionId | |
796 * The header name holding a forwarded SSL Session ID (default null) | |
797 */ | |
798 public void setForwardedSslSessionIdHeader(String forwardedSslSessionId) | |
799 { | |
800 _forwardedSslSessionIdHeader = forwardedSslSessionId; | |
801 } | |
802 | |
803 public int getRequestBufferSize() | |
804 { | |
805 return _buffers.getRequestBufferSize(); | |
806 } | |
807 | |
808 public void setRequestBufferSize(int requestBufferSize) | |
809 { | |
810 _buffers.setRequestBufferSize(requestBufferSize); | |
811 } | |
812 | |
813 public int getRequestHeaderSize() | |
814 { | |
815 return _buffers.getRequestHeaderSize(); | |
816 } | |
817 | |
818 public void setRequestHeaderSize(int requestHeaderSize) | |
819 { | |
820 _buffers.setRequestHeaderSize(requestHeaderSize); | |
821 } | |
822 | |
823 public int getResponseBufferSize() | |
824 { | |
825 return _buffers.getResponseBufferSize(); | |
826 } | |
827 | |
828 public void setResponseBufferSize(int responseBufferSize) | |
829 { | |
830 _buffers.setResponseBufferSize(responseBufferSize); | |
831 } | |
832 | |
833 public int getResponseHeaderSize() | |
834 { | |
835 return _buffers.getResponseHeaderSize(); | |
836 } | |
837 | |
838 public void setResponseHeaderSize(int responseHeaderSize) | |
839 { | |
840 _buffers.setResponseHeaderSize(responseHeaderSize); | |
841 } | |
842 | |
843 public Type getRequestBufferType() | |
844 { | |
845 return _buffers.getRequestBufferType(); | |
846 } | |
847 | |
848 public Type getRequestHeaderType() | |
849 { | |
850 return _buffers.getRequestHeaderType(); | |
851 } | |
852 | |
853 public Type getResponseBufferType() | |
854 { | |
855 return _buffers.getResponseBufferType(); | |
856 } | |
857 | |
858 public Type getResponseHeaderType() | |
859 { | |
860 return _buffers.getResponseHeaderType(); | |
861 } | |
862 | |
863 public void setRequestBuffers(Buffers requestBuffers) | |
864 { | |
865 _buffers.setRequestBuffers(requestBuffers); | |
866 } | |
867 | |
868 public void setResponseBuffers(Buffers responseBuffers) | |
869 { | |
870 _buffers.setResponseBuffers(responseBuffers); | |
871 } | |
872 | |
873 public Buffers getRequestBuffers() | |
874 { | |
875 return _buffers.getRequestBuffers(); | |
876 } | |
877 | |
878 public Buffers getResponseBuffers() | |
879 { | |
880 return _buffers.getResponseBuffers(); | |
881 } | |
882 | |
883 public void setMaxBuffers(int maxBuffers) | |
884 { | |
885 _buffers.setMaxBuffers(maxBuffers); | |
886 } | |
887 | |
888 public int getMaxBuffers() | |
889 { | |
890 return _buffers.getMaxBuffers(); | |
891 } | |
892 | |
893 /* ------------------------------------------------------------ */ | |
894 @Override | |
895 public String toString() | |
896 { | |
897 return String.format("%s@%s:%d", | |
898 getClass().getSimpleName(), | |
899 getHost()==null?"0.0.0.0":getHost(), | |
900 getLocalPort()<=0?getPort():getLocalPort()); | |
901 } | |
902 | |
903 /* ------------------------------------------------------------ */ | |
904 /* ------------------------------------------------------------ */ | |
905 /* ------------------------------------------------------------ */ | |
906 private class Acceptor implements Runnable | |
907 { | |
908 int _acceptor = 0; | |
909 | |
910 Acceptor(int id) | |
911 { | |
912 _acceptor = id; | |
913 } | |
914 | |
915 /* ------------------------------------------------------------ */ | |
916 public void run() | |
917 { | |
918 Thread current = Thread.currentThread(); | |
919 String name; | |
920 synchronized (AbstractConnector.this) | |
921 { | |
922 if (_acceptorThreads == null) | |
923 return; | |
924 | |
925 _acceptorThreads[_acceptor] = current; | |
926 name = _acceptorThreads[_acceptor].getName(); | |
927 current.setName(name + " Acceptor" + _acceptor + " " + AbstractConnector.this); | |
928 } | |
929 int old_priority = current.getPriority(); | |
930 | |
931 try | |
932 { | |
933 current.setPriority(old_priority - _acceptorPriorityOffset); | |
934 while (isRunning() && getConnection() != null) | |
935 { | |
936 try | |
937 { | |
938 accept(_acceptor); | |
939 } | |
940 catch (EofException e) | |
941 { | |
942 LOG.ignore(e); | |
943 } | |
944 catch (IOException e) | |
945 { | |
946 LOG.ignore(e); | |
947 } | |
948 catch (InterruptedException x) | |
949 { | |
950 // Connector has been stopped | |
951 LOG.ignore(x); | |
952 } | |
953 catch (Throwable e) | |
954 { | |
955 LOG.warn(e); | |
956 } | |
957 } | |
958 } | |
959 finally | |
960 { | |
961 current.setPriority(old_priority); | |
962 current.setName(name); | |
963 | |
964 synchronized (AbstractConnector.this) | |
965 { | |
966 if (_acceptorThreads != null) | |
967 _acceptorThreads[_acceptor] = null; | |
968 } | |
969 } | |
970 } | |
971 } | |
972 | |
973 /* ------------------------------------------------------------ */ | |
974 public String getName() | |
975 { | |
976 if (_name == null) | |
977 _name = (getHost() == null?"0.0.0.0":getHost()) + ":" + (getLocalPort() <= 0?getPort():getLocalPort()); | |
978 return _name; | |
979 } | |
980 | |
981 /* ------------------------------------------------------------ */ | |
982 public void setName(String name) | |
983 { | |
984 _name = name; | |
985 } | |
986 | |
987 /* ------------------------------------------------------------ */ | |
988 /** | |
989 * @return Get the number of requests handled by this connector since last call of statsReset(). If setStatsOn(false) then this is undefined. | |
990 */ | |
991 public int getRequests() | |
992 { | |
993 return (int)_requestStats.getTotal(); | |
994 } | |
995 | |
996 /* ------------------------------------------------------------ */ | |
997 /** | |
998 * @return Returns the connectionsDurationTotal. | |
999 */ | |
1000 public long getConnectionsDurationTotal() | |
1001 { | |
1002 return _connectionDurationStats.getTotal(); | |
1003 } | |
1004 | |
1005 /* ------------------------------------------------------------ */ | |
1006 /** | |
1007 * @return Number of connections accepted by the server since statsReset() called. Undefined if setStatsOn(false). | |
1008 */ | |
1009 public int getConnections() | |
1010 { | |
1011 return (int)_connectionStats.getTotal(); | |
1012 } | |
1013 | |
1014 /* ------------------------------------------------------------ */ | |
1015 /** | |
1016 * @return Number of connections currently open that were opened since statsReset() called. Undefined if setStatsOn(false). | |
1017 */ | |
1018 public int getConnectionsOpen() | |
1019 { | |
1020 return (int)_connectionStats.getCurrent(); | |
1021 } | |
1022 | |
1023 /* ------------------------------------------------------------ */ | |
1024 /** | |
1025 * @return Maximum number of connections opened simultaneously since statsReset() called. Undefined if setStatsOn(false). | |
1026 */ | |
1027 public int getConnectionsOpenMax() | |
1028 { | |
1029 return (int)_connectionStats.getMax(); | |
1030 } | |
1031 | |
1032 /* ------------------------------------------------------------ */ | |
1033 /** | |
1034 * @return Mean duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false). | |
1035 */ | |
1036 public double getConnectionsDurationMean() | |
1037 { | |
1038 return _connectionDurationStats.getMean(); | |
1039 } | |
1040 | |
1041 /* ------------------------------------------------------------ */ | |
1042 /** | |
1043 * @return Maximum duration in milliseconds of an open connection since statsReset() called. Undefined if setStatsOn(false). | |
1044 */ | |
1045 public long getConnectionsDurationMax() | |
1046 { | |
1047 return _connectionDurationStats.getMax(); | |
1048 } | |
1049 | |
1050 /* ------------------------------------------------------------ */ | |
1051 /** | |
1052 * @return Standard deviation of duration in milliseconds of open connections since statsReset() called. Undefined if setStatsOn(false). | |
1053 */ | |
1054 public double getConnectionsDurationStdDev() | |
1055 { | |
1056 return _connectionDurationStats.getStdDev(); | |
1057 } | |
1058 | |
1059 /* ------------------------------------------------------------ */ | |
1060 /** | |
1061 * @return Mean number of requests per connection since statsReset() called. Undefined if setStatsOn(false). | |
1062 */ | |
1063 public double getConnectionsRequestsMean() | |
1064 { | |
1065 return _requestStats.getMean(); | |
1066 } | |
1067 | |
1068 /* ------------------------------------------------------------ */ | |
1069 /** | |
1070 * @return Maximum number of requests per connection since statsReset() called. Undefined if setStatsOn(false). | |
1071 */ | |
1072 public int getConnectionsRequestsMax() | |
1073 { | |
1074 return (int)_requestStats.getMax(); | |
1075 } | |
1076 | |
1077 /* ------------------------------------------------------------ */ | |
1078 /** | |
1079 * @return Standard deviation of number of requests per connection since statsReset() called. Undefined if setStatsOn(false). | |
1080 */ | |
1081 public double getConnectionsRequestsStdDev() | |
1082 { | |
1083 return _requestStats.getStdDev(); | |
1084 } | |
1085 | |
1086 /* ------------------------------------------------------------ */ | |
1087 /** | |
1088 * Reset statistics. | |
1089 */ | |
1090 public void statsReset() | |
1091 { | |
1092 updateNotEqual(_statsStartedAt,-1,System.currentTimeMillis()); | |
1093 | |
1094 _requestStats.reset(); | |
1095 _connectionStats.reset(); | |
1096 _connectionDurationStats.reset(); | |
1097 } | |
1098 | |
1099 /* ------------------------------------------------------------ */ | |
1100 public void setStatsOn(boolean on) | |
1101 { | |
1102 if (on && _statsStartedAt.get() != -1) | |
1103 return; | |
1104 | |
1105 if (LOG.isDebugEnabled()) | |
1106 LOG.debug("Statistics on = " + on + " for " + this); | |
1107 | |
1108 statsReset(); | |
1109 _statsStartedAt.set(on?System.currentTimeMillis():-1); | |
1110 } | |
1111 | |
1112 /* ------------------------------------------------------------ */ | |
1113 /** | |
1114 * @return True if statistics collection is turned on. | |
1115 */ | |
1116 public boolean getStatsOn() | |
1117 { | |
1118 return _statsStartedAt.get() != -1; | |
1119 } | |
1120 | |
1121 /* ------------------------------------------------------------ */ | |
1122 /** | |
1123 * @return Timestamp stats were started at. | |
1124 */ | |
1125 public long getStatsOnMs() | |
1126 { | |
1127 long start = _statsStartedAt.get(); | |
1128 | |
1129 return (start != -1)?(System.currentTimeMillis() - start):0; | |
1130 } | |
1131 | |
1132 /* ------------------------------------------------------------ */ | |
1133 protected void connectionOpened(Connection connection) | |
1134 { | |
1135 if (_statsStartedAt.get() == -1) | |
1136 return; | |
1137 | |
1138 _connectionStats.increment(); | |
1139 } | |
1140 | |
1141 /* ------------------------------------------------------------ */ | |
1142 protected void connectionUpgraded(Connection oldConnection, Connection newConnection) | |
1143 { | |
1144 _requestStats.set((oldConnection instanceof AbstractHttpConnection)?((AbstractHttpConnection)oldConnection).getRequests():0); | |
1145 } | |
1146 | |
1147 /* ------------------------------------------------------------ */ | |
1148 protected void connectionClosed(Connection connection) | |
1149 { | |
1150 connection.onClose(); | |
1151 | |
1152 if (_statsStartedAt.get() == -1) | |
1153 return; | |
1154 | |
1155 long duration = System.currentTimeMillis() - connection.getTimeStamp(); | |
1156 int requests = (connection instanceof AbstractHttpConnection)?((AbstractHttpConnection)connection).getRequests():0; | |
1157 _requestStats.set(requests); | |
1158 _connectionStats.decrement(); | |
1159 _connectionDurationStats.set(duration); | |
1160 } | |
1161 | |
1162 /* ------------------------------------------------------------ */ | |
1163 /** | |
1164 * @return the acceptorPriority | |
1165 */ | |
1166 public int getAcceptorPriorityOffset() | |
1167 { | |
1168 return _acceptorPriorityOffset; | |
1169 } | |
1170 | |
1171 /* ------------------------------------------------------------ */ | |
1172 /** | |
1173 * Set the priority offset of the acceptor threads. The priority is adjusted by this amount (default 0) to either favour the acceptance of new threads and | |
1174 * newly active connections or to favour the handling of already dispatched connections. | |
1175 * | |
1176 * @param offset | |
1177 * the amount to alter the priority of the acceptor threads. | |
1178 */ | |
1179 public void setAcceptorPriorityOffset(int offset) | |
1180 { | |
1181 _acceptorPriorityOffset = offset; | |
1182 } | |
1183 | |
1184 /* ------------------------------------------------------------ */ | |
1185 /** | |
1186 * @return True if the the server socket will be opened in SO_REUSEADDR mode. | |
1187 */ | |
1188 public boolean getReuseAddress() | |
1189 { | |
1190 return _reuseAddress; | |
1191 } | |
1192 | |
1193 /* ------------------------------------------------------------ */ | |
1194 /** | |
1195 * @param reuseAddress | |
1196 * True if the the server socket will be opened in SO_REUSEADDR mode. | |
1197 */ | |
1198 public void setReuseAddress(boolean reuseAddress) | |
1199 { | |
1200 _reuseAddress = reuseAddress; | |
1201 } | |
1202 | |
1203 /* ------------------------------------------------------------ */ | |
1204 public boolean isLowResources() | |
1205 { | |
1206 if (_threadPool != null) | |
1207 return _threadPool.isLowOnThreads(); | |
1208 return _server.getThreadPool().isLowOnThreads(); | |
1209 } | |
1210 | |
1211 /* ------------------------------------------------------------ */ | |
1212 private void updateNotEqual(AtomicLong valueHolder, long compare, long value) | |
1213 { | |
1214 long oldValue = valueHolder.get(); | |
1215 while (compare != oldValue) | |
1216 { | |
1217 if (valueHolder.compareAndSet(oldValue,value)) | |
1218 break; | |
1219 oldValue = valueHolder.get(); | |
1220 } | |
1221 } | |
1222 } |