comparison src/org/eclipse/jetty/server/Connector.java @ 885:150092cebf3e

remove AbstractConnector
author Franklin Schmidt <fschmidt@gmail.com>
date Tue, 04 Oct 2016 20:11:48 -0600
parents 6b210bb66c63
children df84a1741687
comparison
equal deleted inserted replaced
884:cb78ee27b0e0 885:150092cebf3e
17 // 17 //
18 18
19 package org.eclipse.jetty.server; 19 package org.eclipse.jetty.server;
20 20
21 import java.io.IOException; 21 import java.io.IOException;
22 22 import java.net.InetAddress;
23 import java.net.Socket;
24 import java.net.UnknownHostException;
25 import java.util.concurrent.ThreadPoolExecutor;
26 import java.util.concurrent.atomic.AtomicLong;
27
28 import javax.servlet.ServletRequest;
29
30 import org.eclipse.jetty.http.HttpBuffers;
31 import org.eclipse.jetty.http.HttpBuffersImpl;
32 import org.eclipse.jetty.http.HttpFields;
33 import org.eclipse.jetty.http.HttpHeaders;
34 import org.eclipse.jetty.http.HttpSchemes;
23 import org.eclipse.jetty.io.Buffers; 35 import org.eclipse.jetty.io.Buffers;
36 import org.eclipse.jetty.io.Buffers.Type;
37 import org.eclipse.jetty.io.Connection;
24 import org.eclipse.jetty.io.EndPoint; 38 import org.eclipse.jetty.io.EndPoint;
25 import org.eclipse.jetty.util.component.LifeCycle; 39 import org.eclipse.jetty.io.EofException;
26 40 import org.eclipse.jetty.util.component.AggregateLifeCycle;
27 /** HTTP Connector. 41 import org.eclipse.jetty.util.component.Dumpable;
28 * Implementations of this interface provide connectors for the HTTP protocol. 42 import org.slf4j.Logger;
29 * A connector receives requests (normally from a socket) and calls the 43 import org.slf4j.LoggerFactory;
30 * handle method of the Handler object. These operations are performed using 44
31 * threads from the ThreadPool set on the connector. 45 /**
32 * 46 * Abstract Connector implementation. This abstract implementation of the Connector interface provides:
33 * When a connector is registered with an instance of Server, then the server 47 * <ul>
34 * will set itself as both the ThreadPool and the Handler. Note that a connector 48 * <li>AbstractLifeCycle implementation</li>
35 * can be used without a Server if a thread pool and handler are directly provided. 49 * <li>Implementations for connector getters and setters</li>
36 * 50 * <li>Buffer management</li>
37 * 51 * <li>Socket configuration</li>
38 * 52 * <li>Base acceptor thread</li>
53 * <li>Optional reverse proxy headers checking</li>
54 * </ul>
39 */ 55 */
40 /** 56 public abstract class Connector extends AggregateLifeCycle implements HttpBuffers, Dumpable
41 * @author gregw 57 {
42 * 58 private static final Logger LOG = LoggerFactory.getLogger(Connector.class);
43 */ 59
44 public interface Connector extends LifeCycle 60 private String _name;
45 { 61
46 /* ------------------------------------------------------------ */ 62 private Server _server;
47 /** 63 private String _host;
48 * @return the name of the connector. Defaults to the HostName:port 64 private int _port = 0;
49 */ 65 private String _integralScheme = HttpSchemes.HTTPS;
50 String getName(); 66 private int _integralPort = 0;
51 67 private String _confidentialScheme = HttpSchemes.HTTPS;
52 /* ------------------------------------------------------------ */ 68 private int _confidentialPort = 0;
53 /** 69 private int _acceptQueueSize = 0;
54 * Opens the connector 70 private int _acceptors = 1;
55 * @throws IOException 71 private int _acceptorPriorityOffset = 0;
56 */ 72 private boolean _useDNS;
57 void open() throws IOException; 73 private boolean _forwarded;
58 74 private String _hostHeader;
59 /* ------------------------------------------------------------ */ 75
60 void close() throws IOException; 76 private String _forwardedHostHeader = HttpHeaders.X_FORWARDED_HOST;
61 77 private String _forwardedServerHeader = HttpHeaders.X_FORWARDED_SERVER;
62 /* ------------------------------------------------------------ */ 78 private String _forwardedForHeader = HttpHeaders.X_FORWARDED_FOR;
63 void setServer(Server server); 79 private String _forwardedProtoHeader = HttpHeaders.X_FORWARDED_PROTO;
64 80 private String _forwardedCipherSuiteHeader;
65 /* ------------------------------------------------------------ */ 81 private String _forwardedSslSessionIdHeader;
66 Server getServer(); 82 private boolean _reuseAddress = true;
67 83
68 /* ------------------------------------------------------------ */ 84 protected int _maxIdleTime = 200000;
69 /** 85 protected int _lowResourceMaxIdleTime = -1;
70 * @return Returns the request header buffer size in bytes. 86 protected int _soLingerTime = -1;
71 */ 87
72 int getRequestHeaderSize(); 88 private transient Thread[] _acceptorThreads;
73 89
74 /* ------------------------------------------------------------ */ 90 protected final HttpBuffersImpl _buffers = new HttpBuffersImpl();
75 /** 91
76 * Set the size of the buffer to be used for request headers. 92 /* ------------------------------------------------------------ */
77 * @param size The size in bytes. 93 /**
78 */ 94 */
79 void setRequestHeaderSize(int size); 95 public Connector()
80 96 {
81 /* ------------------------------------------------------------ */ 97 addBean(_buffers);
82 /** 98 }
83 * @return Returns the response header buffer size in bytes. 99
84 */ 100 /* ------------------------------------------------------------ */
85 int getResponseHeaderSize(); 101 /*
86 102 */
87 /* ------------------------------------------------------------ */ 103 public Server getServer()
88 /** 104 {
89 * Set the size of the buffer to be used for request headers. 105 return _server;
90 * @param size The size in bytes. 106 }
91 */ 107
92 void setResponseHeaderSize(int size); 108 /* ------------------------------------------------------------ */
93 109 public void setServer(Server server)
94 110 {
95 /* ------------------------------------------------------------ */ 111 _server = server;
96 /** 112 }
97 * @return factory for request buffers 113
98 */ 114 /* ------------------------------------------------------------ */
99 Buffers getRequestBuffers(); 115 public ThreadPoolExecutor getThreadPool()
100 116 {
101 /* ------------------------------------------------------------ */ 117 return _server.threadPool;
102 /** 118 }
103 * @return factory for response buffers 119
104 */ 120 /* ------------------------------------------------------------ */
105 Buffers getResponseBuffers(); 121 /**
106 122 */
107 123 public void setHost(String host)
108 /* ------------------------------------------------------------ */ 124 {
109 /** 125 _host = host;
110 * @return Returns the requestBufferSize. 126 }
111 */ 127
112 int getRequestBufferSize(); 128 /* ------------------------------------------------------------ */
113 129 /*
114 /* ------------------------------------------------------------ */ 130 */
115 /** 131 public String getHost()
116 * Set the size of the content buffer for receiving requests. 132 {
117 * These buffers are only used for active connections that have 133 return _host;
118 * requests with bodies that will not fit within the header buffer. 134 }
119 * @param requestBufferSize The requestBufferSize to set. 135
120 */ 136 /* ------------------------------------------------------------ */
121 void setRequestBufferSize(int requestBufferSize); 137 public void setPort(int port)
122 138 {
123 /* ------------------------------------------------------------ */ 139 _port = port;
124 /** 140 }
125 * @return Returns the responseBufferSize. 141
126 */ 142 /* ------------------------------------------------------------ */
127 int getResponseBufferSize(); 143 public int getPort()
128 144 {
129 /* ------------------------------------------------------------ */ 145 return _port;
130 /** 146 }
131 * Set the size of the content buffer for sending responses. 147
132 * These buffers are only used for active connections that are sending 148 /* ------------------------------------------------------------ */
133 * responses with bodies that will not fit within the header buffer. 149 /**
134 * @param responseBufferSize The responseBufferSize to set. 150 * @return Returns the maxIdleTime.
135 */ 151 */
136 void setResponseBufferSize(int responseBufferSize); 152 public int getMaxIdleTime()
137 153 {
138 154 return _maxIdleTime;
139 /* ------------------------------------------------------------ */ 155 }
140 /** 156
141 * @return The port to use when redirecting a request if a data constraint of integral is 157 /* ------------------------------------------------------------ */
142 * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()} 158 /**
143 */ 159 * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations
144 int getIntegralPort(); 160 * other mechanisms may be used to implement the timeout. The max idle time is applied:
145 161 * <ul>
146 /* ------------------------------------------------------------ */ 162 * <li>When waiting for a new request to be received on a connection</li>
147 /** 163 * <li>When reading the headers and content of a request</li>
148 * @return The schema to use when redirecting a request if a data constraint of integral is 164 * <li>When writing the headers and content of a response</li>
149 * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()} 165 * </ul>
150 */ 166 * 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
151 String getIntegralScheme(); 167 * 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
152 168 * 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
153 /* ------------------------------------------------------------ */ 169 * take many 10s of seconds for large content written to a slow device.
154 /**
155 * @param request A request
156 * @return true if the request is integral. This normally means the https schema has been used.
157 */
158 boolean isIntegral(Request request);
159
160 /* ------------------------------------------------------------ */
161 /**
162 * @return The port to use when redirecting a request if a data constraint of confidential is
163 * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
164 */
165 int getConfidentialPort();
166
167
168 /* ------------------------------------------------------------ */
169 /**
170 * @return The schema to use when redirecting a request if a data constraint of confidential is
171 * required. See {@link org.eclipse.jetty.util.security.Constraint#getDataConstraint()}
172 */
173 String getConfidentialScheme();
174
175 /* ------------------------------------------------------------ */
176 /**
177 * @param request A request
178 * @return true if the request is confidential. This normally means the https schema has been used.
179 */
180 boolean isConfidential(Request request);
181
182 /* ------------------------------------------------------------ */
183 /** Customize a request for an endpoint.
184 * Called on every request to allow customization of the request for
185 * the particular endpoint (eg security properties from a SSL connection).
186 * @param endpoint
187 * @param request
188 * @throws IOException
189 */
190 void customize(EndPoint endpoint, Request request) throws IOException;
191
192 /* ------------------------------------------------------------ */
193 /** Persist an endpoint.
194 * Called after every request if the connection is to remain open.
195 * @param endpoint
196 * @throws IOException
197 */
198 void persist(EndPoint endpoint) throws IOException;
199
200 /* ------------------------------------------------------------ */
201 /**
202 * @return The hostname representing the interface to which
203 * this connector will bind, or null for all interfaces.
204 */
205 String getHost();
206
207 /* ------------------------------------------------------------ */
208 /**
209 * Set the hostname of the interface to bind to.
210 * @param hostname The hostname representing the interface to which
211 * this connector will bind, or null for all interfaces.
212 */
213 void setHost(String hostname);
214
215 /* ------------------------------------------------------------ */
216 /**
217 * @param port The port to listen of for connections or 0 if any available
218 * port may be used.
219 */
220 void setPort(int port);
221
222 /* ------------------------------------------------------------ */
223 /**
224 * @return The configured port for the connector or 0 if any available
225 * port may be used.
226 */
227 int getPort();
228
229 /* ------------------------------------------------------------ */
230 /**
231 * @return The actual port the connector is listening on or
232 * -1 if it has not been opened, or -2 if it has been closed.
233 */
234 int getLocalPort();
235
236 /* ------------------------------------------------------------ */
237 /**
238 * @return Max Idle time for connections in milliseconds
239 */
240 int getMaxIdleTime();
241
242 /**
243 * @param ms Max Idle time for connections in milliseconds
244 */
245 void setMaxIdleTime(int ms);
246
247 /* ------------------------------------------------------------ */
248 int getLowResourceMaxIdleTime();
249 void setLowResourceMaxIdleTime(int ms);
250
251 /* ------------------------------------------------------------ */
252 /**
253 * @return the underlying socket, channel, buffer etc. for the connector.
254 */
255 Object getConnection();
256
257
258 /* ------------------------------------------------------------ */
259 /**
260 * @return true if names resolution should be done.
261 */
262 boolean getResolveNames();
263
264
265
266 /* ------------------------------------------------------------ */
267 /** Check if low on resources.
268 * For most connectors, low resources is measured by calling
269 * {@link Server#isLowOnThreads()} on the connector threadpool
270 * or the server threadpool if there is no connector threadpool.
271 * <p> 170 * <p>
272 * For blocking connectors, low resources is used to trigger 171 * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so
273 * usage of {@link #getLowResourceMaxIdleTime()} for the timeout 172 * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand).
274 * of an idle connection. 173 *
275 * <p> 174 * @param maxIdleTime
276 * for non-blocking connectors, the number of connections is 175 * The maxIdleTime to set.
277 * used instead of this method, to select the timeout of an 176 */
278 * idle connection. 177 public void setMaxIdleTime(int maxIdleTime)
279 * <p> 178 {
280 * For all connectors, low resources is used to trigger the 179 _maxIdleTime = maxIdleTime;
281 * usage of {@link #getLowResourceMaxIdleTime()} for read and 180 }
282 * write operations. 181
283 * 182 /* ------------------------------------------------------------ */
284 * @return true if this connector is low on resources. 183 /**
285 */ 184 * @return Returns the maxIdleTime when resources are low.
286 public boolean isLowResources(); 185 */
186 public int getLowResourcesMaxIdleTime()
187 {
188 return _lowResourceMaxIdleTime;
189 }
190
191 /* ------------------------------------------------------------ */
192 /**
193 * @param maxIdleTime
194 * The maxIdleTime to set when resources are low.
195 */
196 public void setLowResourcesMaxIdleTime(int maxIdleTime)
197 {
198 _lowResourceMaxIdleTime = maxIdleTime;
199 }
200
201 /* ------------------------------------------------------------ */
202 /**
203 * @return Returns the maxIdleTime when resources are low.
204 * @deprecated
205 */
206 @Deprecated
207 public final int getLowResourceMaxIdleTime()
208 {
209 return getLowResourcesMaxIdleTime();
210 }
211
212 /* ------------------------------------------------------------ */
213 /**
214 * @param maxIdleTime
215 * The maxIdleTime to set when resources are low.
216 * @deprecated
217 */
218 @Deprecated
219 public final void setLowResourceMaxIdleTime(int maxIdleTime)
220 {
221 setLowResourcesMaxIdleTime(maxIdleTime);
222 }
223
224 /* ------------------------------------------------------------ */
225 /**
226 * @return Returns the soLingerTime.
227 */
228 public int getSoLingerTime()
229 {
230 return _soLingerTime;
231 }
232
233 /* ------------------------------------------------------------ */
234 /**
235 * @return Returns the acceptQueueSize.
236 */
237 public int getAcceptQueueSize()
238 {
239 return _acceptQueueSize;
240 }
241
242 /* ------------------------------------------------------------ */
243 /**
244 * @param acceptQueueSize
245 * The acceptQueueSize to set.
246 */
247 public void setAcceptQueueSize(int acceptQueueSize)
248 {
249 _acceptQueueSize = acceptQueueSize;
250 }
251
252 /* ------------------------------------------------------------ */
253 /**
254 * @return Returns the number of acceptor threads.
255 */
256 public int getAcceptors()
257 {
258 return _acceptors;
259 }
260
261 /* ------------------------------------------------------------ */
262 /**
263 * @param acceptors
264 * The number of acceptor threads to set.
265 */
266 public void setAcceptors(int acceptors)
267 {
268 if (acceptors > 2 * Runtime.getRuntime().availableProcessors())
269 LOG.warn("Acceptors should be <=2*availableProcessors: " + this);
270 _acceptors = acceptors;
271 }
272
273 /* ------------------------------------------------------------ */
274 /**
275 * @param soLingerTime
276 * The soLingerTime to set or -1 to disable.
277 */
278 public void setSoLingerTime(int soLingerTime)
279 {
280 _soLingerTime = soLingerTime;
281 }
282
283 /* ------------------------------------------------------------ */
284 @Override
285 protected void doStart() throws Exception
286 {
287 if (_server == null)
288 throw new IllegalStateException("No server");
289
290 // open listener port
291 open();
292
293 super.doStart();
294
295 // Start selector thread
296 synchronized (this)
297 {
298 _acceptorThreads = new Thread[getAcceptors()];
299
300 ThreadPoolExecutor _threadPool = getThreadPool();
301 for (int i = 0; i < _acceptorThreads.length; i++)
302 _threadPool.execute(new Acceptor(i));
303 if (_server.isLowOnThreads())
304 LOG.warn("insufficient threads configured for {}",this);
305 }
306
307 LOG.info("Started {}",this);
308 }
309
310 /* ------------------------------------------------------------ */
311 @Override
312 protected void doStop() throws Exception
313 {
314 try
315 {
316 close();
317 }
318 catch (IOException e)
319 {
320 LOG.warn("",e);
321 }
322
323 super.doStop();
324
325 Thread[] acceptors;
326 synchronized (this)
327 {
328 acceptors = _acceptorThreads;
329 _acceptorThreads = null;
330 }
331 if (acceptors != null)
332 {
333 for (Thread thread : acceptors)
334 {
335 if (thread != null)
336 thread.interrupt();
337 }
338 }
339 }
340
341 /* ------------------------------------------------------------ */
342 public void join() throws InterruptedException
343 {
344 Thread[] threads;
345 synchronized(this)
346 {
347 threads=_acceptorThreads;
348 }
349 if (threads != null)
350 for (Thread thread : threads)
351 if (thread != null)
352 thread.join();
353 }
354
355 /* ------------------------------------------------------------ */
356 protected void configure(Socket socket) throws IOException
357 {
358 try
359 {
360 socket.setTcpNoDelay(true);
361 if (_soLingerTime >= 0)
362 socket.setSoLinger(true,_soLingerTime / 1000);
363 else
364 socket.setSoLinger(false,0);
365 }
366 catch (Exception e)
367 {
368 LOG.trace("",e);
369 }
370 }
371
372 /* ------------------------------------------------------------ */
373 public void customize(EndPoint endpoint, Request request) throws IOException
374 {
375 if (isForwarded())
376 checkForwardedHeaders(endpoint,request);
377 }
378
379 /* ------------------------------------------------------------ */
380 protected void checkForwardedHeaders(EndPoint endpoint, Request request) throws IOException
381 {
382 HttpFields httpFields = request.getConnection().getRequestFields();
383
384 // Do SSL first
385 if (getForwardedCipherSuiteHeader()!=null)
386 {
387 String cipher_suite=httpFields.getStringField(getForwardedCipherSuiteHeader());
388 if (cipher_suite!=null)
389 request.setAttribute("javax.servlet.request.cipher_suite",cipher_suite);
390 }
391 if (getForwardedSslSessionIdHeader()!=null)
392 {
393 String ssl_session_id=httpFields.getStringField(getForwardedSslSessionIdHeader());
394 if(ssl_session_id!=null)
395 {
396 request.setAttribute("javax.servlet.request.ssl_session_id", ssl_session_id);
397 request.setScheme(HttpSchemes.HTTPS);
398 }
399 }
400
401 // Retrieving headers from the request
402 String forwardedHost = getLeftMostFieldValue(httpFields,getForwardedHostHeader());
403 String forwardedServer = getLeftMostFieldValue(httpFields,getForwardedServerHeader());
404 String forwardedFor = getLeftMostFieldValue(httpFields,getForwardedForHeader());
405 String forwardedProto = getLeftMostFieldValue(httpFields,getForwardedProtoHeader());
406
407 if (_hostHeader != null)
408 {
409 // Update host header
410 httpFields.put(HttpHeaders.HOST_BUFFER,_hostHeader);
411 request.setServerName(null);
412 request.setServerPort(-1);
413 request.getServerName();
414 }
415 else if (forwardedHost != null)
416 {
417 // Update host header
418 httpFields.put(HttpHeaders.HOST_BUFFER,forwardedHost);
419 request.setServerName(null);
420 request.setServerPort(-1);
421 request.getServerName();
422 }
423 else if (forwardedServer != null)
424 {
425 // Use provided server name
426 request.setServerName(forwardedServer);
427 }
428
429 if (forwardedFor != null)
430 {
431 request.setRemoteAddr(forwardedFor);
432 InetAddress inetAddress = null;
433
434 if (_useDNS)
435 {
436 try
437 {
438 inetAddress = InetAddress.getByName(forwardedFor);
439 }
440 catch (UnknownHostException e)
441 {
442 LOG.trace("",e);
443 }
444 }
445
446 request.setRemoteHost(inetAddress == null?forwardedFor:inetAddress.getHostName());
447 }
448
449 if (forwardedProto != null)
450 {
451 request.setScheme(forwardedProto);
452 }
453 }
454
455 /* ------------------------------------------------------------ */
456 protected String getLeftMostFieldValue(HttpFields fields, String header)
457 {
458 if (header == null)
459 return null;
460
461 String headerValue = fields.getStringField(header);
462
463 if (headerValue == null)
464 return null;
465
466 int commaIndex = headerValue.indexOf(',');
467
468 if (commaIndex == -1)
469 {
470 // Single value
471 return headerValue;
472 }
473
474 // The left-most value is the farthest downstream client
475 return headerValue.substring(0,commaIndex);
476 }
477
478 /* ------------------------------------------------------------ */
479 public void persist(EndPoint endpoint) throws IOException
480 {
481 }
482
483 /* ------------------------------------------------------------ */
484 /*
485 * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
486 */
487 public int getConfidentialPort()
488 {
489 return _confidentialPort;
490 }
491
492 /* ------------------------------------------------------------ */
493 /* ------------------------------------------------------------ */
494 /*
495 * @see org.eclipse.jetty.server.Connector#getConfidentialScheme()
496 */
497 public String getConfidentialScheme()
498 {
499 return _confidentialScheme;
500 }
501
502 /* ------------------------------------------------------------ */
503 /*
504 * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server .Request)
505 */
506 public boolean isIntegral(Request request)
507 {
508 return false;
509 }
510
511 /* ------------------------------------------------------------ */
512 /*
513 * @see org.eclipse.jetty.server.Connector#getConfidentialPort()
514 */
515 public int getIntegralPort()
516 {
517 return _integralPort;
518 }
519
520 /* ------------------------------------------------------------ */
521 /*
522 * @see org.eclipse.jetty.server.Connector#getIntegralScheme()
523 */
524 public String getIntegralScheme()
525 {
526 return _integralScheme;
527 }
528
529 /* ------------------------------------------------------------ */
530 /*
531 * @see org.eclipse.jetty.server.Connector#isConfidential(org.eclipse.jetty.server.Request)
532 */
533 public boolean isConfidential(Request request)
534 {
535 return _forwarded && request.getScheme().equalsIgnoreCase(HttpSchemes.HTTPS);
536 }
537
538 /* ------------------------------------------------------------ */
539 /**
540 * @param confidentialPort
541 * The confidentialPort to set.
542 */
543 public void setConfidentialPort(int confidentialPort)
544 {
545 _confidentialPort = confidentialPort;
546 }
547
548 /* ------------------------------------------------------------ */
549 /**
550 * @param confidentialScheme
551 * The confidentialScheme to set.
552 */
553 public void setConfidentialScheme(String confidentialScheme)
554 {
555 _confidentialScheme = confidentialScheme;
556 }
557
558 /* ------------------------------------------------------------ */
559 /**
560 * @param integralPort
561 * The integralPort to set.
562 */
563 public void setIntegralPort(int integralPort)
564 {
565 _integralPort = integralPort;
566 }
567
568 /* ------------------------------------------------------------ */
569 /**
570 * @param integralScheme
571 * The integralScheme to set.
572 */
573 public void setIntegralScheme(String integralScheme)
574 {
575 _integralScheme = integralScheme;
576 }
577
578 /* ------------------------------------------------------------ */
579 protected abstract void accept(int acceptorID) throws IOException, InterruptedException;
580
581 /* ------------------------------------------------------------ */
582 public void stopAccept(int acceptorID) throws Exception
583 {
584 }
585
586 /* ------------------------------------------------------------ */
587 public boolean getResolveNames()
588 {
589 return _useDNS;
590 }
591
592 /* ------------------------------------------------------------ */
593 public void setResolveNames(boolean resolve)
594 {
595 _useDNS = resolve;
596 }
597
598 /* ------------------------------------------------------------ */
599 /**
600 * Is reverse proxy handling on?
601 *
602 * @return true if this connector is checking the x-forwarded-for/host/server headers
603 */
604 public boolean isForwarded()
605 {
606 return _forwarded;
607 }
608
609 /* ------------------------------------------------------------ */
610 /**
611 * 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,
612 * host, server and client ip.
613 *
614 * @param check
615 * true if this connector is checking the x-forwarded-for/host/server headers
616 * @see #setForwardedForHeader(String)
617 * @see #setForwardedHostHeader(String)
618 * @see #setForwardedProtoHeader(String)
619 * @see #setForwardedServerHeader(String)
620 */
621 public void setForwarded(boolean check)
622 {
623 if (check)
624 LOG.debug("{} is forwarded",this);
625 _forwarded = check;
626 }
627
628 /* ------------------------------------------------------------ */
629 public String getHostHeader()
630 {
631 return _hostHeader;
632 }
633
634 /* ------------------------------------------------------------ */
635 /**
636 * Set a forced valued for the host header to control what is returned by {@link ServletRequest#getServerName()} and {@link ServletRequest#getServerPort()}.
637 * This value is only used if {@link #isForwarded()} is true.
638 *
639 * @param hostHeader
640 * The value of the host header to force.
641 */
642 public void setHostHeader(String hostHeader)
643 {
644 _hostHeader = hostHeader;
645 }
646
647 /* ------------------------------------------------------------ */
648 /*
649 *
650 * @see #setForwarded(boolean)
651 */
652 public String getForwardedHostHeader()
653 {
654 return _forwardedHostHeader;
655 }
656
657 /* ------------------------------------------------------------ */
658 /**
659 * @param forwardedHostHeader
660 * The header name for forwarded hosts (default x-forwarded-host)
661 * @see #setForwarded(boolean)
662 */
663 public void setForwardedHostHeader(String forwardedHostHeader)
664 {
665 _forwardedHostHeader = forwardedHostHeader;
666 }
667
668 /* ------------------------------------------------------------ */
669 /**
670 * @return the header name for forwarded server.
671 * @see #setForwarded(boolean)
672 */
673 public String getForwardedServerHeader()
674 {
675 return _forwardedServerHeader;
676 }
677
678 /* ------------------------------------------------------------ */
679 /**
680 * @param forwardedServerHeader
681 * The header name for forwarded server (default x-forwarded-server)
682 * @see #setForwarded(boolean)
683 */
684 public void setForwardedServerHeader(String forwardedServerHeader)
685 {
686 _forwardedServerHeader = forwardedServerHeader;
687 }
688
689 /* ------------------------------------------------------------ */
690 /**
691 * @see #setForwarded(boolean)
692 */
693 public String getForwardedForHeader()
694 {
695 return _forwardedForHeader;
696 }
697
698 /* ------------------------------------------------------------ */
699 /**
700 * @param forwardedRemoteAddressHeader
701 * The header name for forwarded for (default x-forwarded-for)
702 * @see #setForwarded(boolean)
703 */
704 public void setForwardedForHeader(String forwardedRemoteAddressHeader)
705 {
706 _forwardedForHeader = forwardedRemoteAddressHeader;
707 }
708
709 /* ------------------------------------------------------------ */
710 /**
711 * Get the forwardedProtoHeader.
712 *
713 * @return the forwardedProtoHeader (default X-Forwarded-For)
714 * @see #setForwarded(boolean)
715 */
716 public String getForwardedProtoHeader()
717 {
718 return _forwardedProtoHeader;
719 }
720
721 /* ------------------------------------------------------------ */
722 /**
723 * Set the forwardedProtoHeader.
724 *
725 * @param forwardedProtoHeader
726 * the forwardedProtoHeader to set (default X-Forwarded-For)
727 * @see #setForwarded(boolean)
728 */
729 public void setForwardedProtoHeader(String forwardedProtoHeader)
730 {
731 _forwardedProtoHeader = forwardedProtoHeader;
732 }
733
734 /* ------------------------------------------------------------ */
735 /**
736 * @return The header name holding a forwarded cipher suite (default null)
737 */
738 public String getForwardedCipherSuiteHeader()
739 {
740 return _forwardedCipherSuiteHeader;
741 }
742
743 /* ------------------------------------------------------------ */
744 /**
745 * @param forwardedCipherSuite
746 * The header name holding a forwarded cipher suite (default null)
747 */
748 public void setForwardedCipherSuiteHeader(String forwardedCipherSuite)
749 {
750 _forwardedCipherSuiteHeader = forwardedCipherSuite;
751 }
752
753 /* ------------------------------------------------------------ */
754 /**
755 * @return The header name holding a forwarded SSL Session ID (default null)
756 */
757 public String getForwardedSslSessionIdHeader()
758 {
759 return _forwardedSslSessionIdHeader;
760 }
761
762 /* ------------------------------------------------------------ */
763 /**
764 * @param forwardedSslSessionId
765 * The header name holding a forwarded SSL Session ID (default null)
766 */
767 public void setForwardedSslSessionIdHeader(String forwardedSslSessionId)
768 {
769 _forwardedSslSessionIdHeader = forwardedSslSessionId;
770 }
771
772 public int getRequestBufferSize()
773 {
774 return _buffers.getRequestBufferSize();
775 }
776
777 public void setRequestBufferSize(int requestBufferSize)
778 {
779 _buffers.setRequestBufferSize(requestBufferSize);
780 }
781
782 public int getRequestHeaderSize()
783 {
784 return _buffers.getRequestHeaderSize();
785 }
786
787 public void setRequestHeaderSize(int requestHeaderSize)
788 {
789 _buffers.setRequestHeaderSize(requestHeaderSize);
790 }
791
792 public int getResponseBufferSize()
793 {
794 return _buffers.getResponseBufferSize();
795 }
796
797 public void setResponseBufferSize(int responseBufferSize)
798 {
799 _buffers.setResponseBufferSize(responseBufferSize);
800 }
801
802 public int getResponseHeaderSize()
803 {
804 return _buffers.getResponseHeaderSize();
805 }
806
807 public void setResponseHeaderSize(int responseHeaderSize)
808 {
809 _buffers.setResponseHeaderSize(responseHeaderSize);
810 }
811
812 public Type getRequestBufferType()
813 {
814 return _buffers.getRequestBufferType();
815 }
816
817 public Type getRequestHeaderType()
818 {
819 return _buffers.getRequestHeaderType();
820 }
821
822 public Type getResponseBufferType()
823 {
824 return _buffers.getResponseBufferType();
825 }
826
827 public Type getResponseHeaderType()
828 {
829 return _buffers.getResponseHeaderType();
830 }
831
832 public void setRequestBuffers(Buffers requestBuffers)
833 {
834 _buffers.setRequestBuffers(requestBuffers);
835 }
836
837 public void setResponseBuffers(Buffers responseBuffers)
838 {
839 _buffers.setResponseBuffers(responseBuffers);
840 }
841
842 public Buffers getRequestBuffers()
843 {
844 return _buffers.getRequestBuffers();
845 }
846
847 public Buffers getResponseBuffers()
848 {
849 return _buffers.getResponseBuffers();
850 }
851
852 public int getMaxBuffers()
853 {
854 return _buffers.getMaxBuffers();
855 }
856
857 /* ------------------------------------------------------------ */
858 @Override
859 public String toString()
860 {
861 return String.format("%s@%s:%d",
862 getClass().getSimpleName(),
863 getHost()==null?"0.0.0.0":getHost(),
864 getLocalPort()<=0?getPort():getLocalPort());
865 }
866
867 /* ------------------------------------------------------------ */
868 /* ------------------------------------------------------------ */
869 /* ------------------------------------------------------------ */
870 private class Acceptor implements Runnable
871 {
872 int _acceptor = 0;
873
874 Acceptor(int id)
875 {
876 _acceptor = id;
877 }
878
879 /* ------------------------------------------------------------ */
880 public void run()
881 {
882 Thread current = Thread.currentThread();
883 String name;
884 synchronized (Connector.this)
885 {
886 if (_acceptorThreads == null)
887 return;
888
889 _acceptorThreads[_acceptor] = current;
890 name = _acceptorThreads[_acceptor].getName();
891 current.setName(name + " Acceptor" + _acceptor + " " + Connector.this);
892 }
893 int old_priority = current.getPriority();
894
895 try
896 {
897 current.setPriority(old_priority - _acceptorPriorityOffset);
898 while (isRunning() && getConnection() != null)
899 {
900 try
901 {
902 accept(_acceptor);
903 }
904 catch (EofException e)
905 {
906 LOG.trace("",e);
907 }
908 catch (IOException e)
909 {
910 LOG.trace("",e);
911 }
912 catch (InterruptedException x)
913 {
914 // Connector has been stopped
915 LOG.trace("",x);
916 }
917 catch (Throwable e)
918 {
919 LOG.warn("",e);
920 }
921 }
922 }
923 finally
924 {
925 current.setPriority(old_priority);
926 current.setName(name);
927
928 synchronized (Connector.this)
929 {
930 if (_acceptorThreads != null)
931 _acceptorThreads[_acceptor] = null;
932 }
933 }
934 }
935 }
936
937 /* ------------------------------------------------------------ */
938 public String getName()
939 {
940 if (_name == null)
941 _name = (getHost() == null?"0.0.0.0":getHost()) + ":" + (getLocalPort() <= 0?getPort():getLocalPort());
942 return _name;
943 }
944
945 /* ------------------------------------------------------------ */
946 public void setName(String name)
947 {
948 _name = name;
949 }
950
951 /* ------------------------------------------------------------ */
952 protected void connectionOpened(Connection connection)
953 {
954 }
955
956 /* ------------------------------------------------------------ */
957 protected void connectionUpgraded(Connection oldConnection, Connection newConnection)
958 {
959 }
960
961 /* ------------------------------------------------------------ */
962 protected void connectionClosed(Connection connection)
963 {
964 connection.onClose();
965 }
966
967 /* ------------------------------------------------------------ */
968 /**
969 * @return the acceptorPriority
970 */
971 public int getAcceptorPriorityOffset()
972 {
973 return _acceptorPriorityOffset;
974 }
975
976 /* ------------------------------------------------------------ */
977 /**
978 * 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
979 * newly active connections or to favour the handling of already dispatched connections.
980 *
981 * @param offset
982 * the amount to alter the priority of the acceptor threads.
983 */
984 public void setAcceptorPriorityOffset(int offset)
985 {
986 _acceptorPriorityOffset = offset;
987 }
988
989 /* ------------------------------------------------------------ */
990 /**
991 * @return True if the the server socket will be opened in SO_REUSEADDR mode.
992 */
993 public boolean getReuseAddress()
994 {
995 return _reuseAddress;
996 }
997
998 /* ------------------------------------------------------------ */
999 /**
1000 * @param reuseAddress
1001 * True if the the server socket will be opened in SO_REUSEADDR mode.
1002 */
1003 public void setReuseAddress(boolean reuseAddress)
1004 {
1005 _reuseAddress = reuseAddress;
1006 }
1007
1008 /* ------------------------------------------------------------ */
1009 public final boolean isLowResources()
1010 {
1011 return _server.isLowOnThreads();
1012 }
1013
1014 /* ------------------------------------------------------------ */
1015 private void updateNotEqual(AtomicLong valueHolder, long compare, long value)
1016 {
1017 long oldValue = valueHolder.get();
1018 while (compare != oldValue)
1019 {
1020 if (valueHolder.compareAndSet(oldValue,value))
1021 break;
1022 oldValue = valueHolder.get();
1023 }
1024 }
1025
1026 // from old interface
1027 public abstract void open() throws IOException;
1028 public abstract void close() throws IOException;
1029 public abstract int getLocalPort();
1030 public abstract Object getConnection();
287 } 1031 }