comparison src/org/eclipse/jetty/server/AbstractConnector.java @ 864:e21ca9878a10

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