Mercurial Hosting > luan
view src/org/eclipse/jetty/server/Connector.java @ 1070:a44fc6b53757
fix use of HttpGenerator._buffer
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 10 Nov 2016 01:23:37 -0700 |
parents | 2b769da7f67d |
children | ebb0f1343ef6 |
line wrap: on
line source
// // ======================================================================== // Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // and Apache License v2.0 which accompanies this distribution. // // The Eclipse Public License is available at // http://www.eclipse.org/legal/epl-v10.html // // The Apache License v2.0 is available at // http://www.opensource.org/licenses/apache2.0.php // // You may elect to redistribute this code under either of these licenses. // ======================================================================== // package org.eclipse.jetty.server; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; import java.nio.channels.ServerSocketChannel; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.atomic.AtomicLong; import javax.servlet.ServletRequest; import org.eclipse.jetty.io.JBuffer; import org.eclipse.jetty.io.Buffers; import org.eclipse.jetty.io.BufferUtil; import org.eclipse.jetty.io.EndPoint; import org.eclipse.jetty.io.EofException; import org.eclipse.jetty.util.component.AggregateLifeCycle; import org.eclipse.jetty.util.component.Dumpable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Abstract Connector implementation. This abstract implementation of the Connector interface provides: * <ul> * <li>AbstractLifeCycle implementation</li> * <li>Implementations for connector getters and setters</li> * <li>JBuffer management</li> * <li>Socket configuration</li> * <li>Base acceptor thread</li> * <li>Optional reverse proxy headers checking</li> * </ul> */ public abstract class Connector extends AggregateLifeCycle implements Dumpable, Runnable { private static final Logger LOG = LoggerFactory.getLogger(Connector.class); private String _name; public final Server server; private String _host; public final int port; protected final int _maxIdleTime = 200000; protected int _soLingerTime = -1; // from child classes protected transient ServerSocketChannel _acceptChannel; protected Connector(Server server,int port) { this.server = server; this.port = port; server.connectors.add(this); } public final void setHost(String host) { _host = host; } public final String getHost() { return _host; } public final int getMaxIdleTime() { return _maxIdleTime; } /* ------------------------------------------------------------ */ /** * Set the maximum Idle time for a connection, which roughly translates to the {@link Socket#setSoTimeout(int)} call, although with NIO implementations * other mechanisms may be used to implement the timeout. The max idle time is applied: * <ul> * <li>When waiting for a new request to be received on a connection</li> * <li>When reading the headers and content of a request</li> * <li>When writing the headers and content of a response</li> * </ul> * 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 * 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 * 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 * take many 10s of seconds for large content written to a slow device. * <p> * Previously, Jetty supported separate idle timeouts and IO operation timeouts, however the expense of changing the value of soTimeout was significant, so * these timeouts were merged. With the advent of NIO, it may be possible to again differentiate these values (if there is demand). * * @param maxIdleTime * The maxIdleTime to set. */ public final int getSoLingerTime() { return _soLingerTime; } /* ------------------------------------------------------------ */ /** * @param soLingerTime * The soLingerTime to set or -1 to disable. */ public final void setSoLingerTime(int soLingerTime) { _soLingerTime = soLingerTime; } @Override protected void doStart() throws Exception { super.doStart(); // Start selector thread ThreadPoolExecutor _threadPool = server.threadPool; _threadPool.execute(this); if (server.isLowOnThreads()) LOG.warn("insufficient threads configured for {}",this); LOG.info("Started {}",this); } @Override protected synchronized void doStop() throws Exception { try { if (_acceptChannel != null) _acceptChannel.close(); _acceptChannel=null; } catch (IOException e) { LOG.warn("",e); } super.doStop(); } protected final void configure(Socket socket) throws IOException { socket.setTcpNoDelay(true); if (_soLingerTime >= 0) socket.setSoLinger(true,_soLingerTime / 1000); else socket.setSoLinger(false,0); } public abstract void customize(AbstractHttpConnection con) throws IOException; public boolean isConfidential() { return false; } protected abstract void accept() throws IOException, InterruptedException; @Override public String toString() { return String.format("%s@%s:%d", getClass().getSimpleName(), getHost()==null?"0.0.0.0":getHost(), port); } @Override public void run() { Thread current = Thread.currentThread(); String name = current.getName(); current.setName(name + " Acceptor" + " " + Connector.this); try { while (isRunning() && _acceptChannel != null) { try { accept(); } catch (EofException e) { LOG.trace("",e); } catch (IOException e) { LOG.trace("",e); } catch (InterruptedException x) { // Connector has been stopped LOG.trace("",x); } catch (Throwable e) { LOG.warn("",e); } } } finally { current.setName(name); } } public final String getName() { if (_name == null) _name = (getHost() == null?"0.0.0.0":getHost()) + ":" + port; return _name; } // from HttpBuffersImpl protected int _requestHeaderSize = 6*1024; protected int _requestBufferSize = 16*1024; private final int _responseHeaderSize = 6*1024; private final int _responseBufferSize = 32*1024; public final Buffers getRequestBuffers() { return new MyBuffers(_requestHeaderSize,_requestBufferSize); } public final Buffers getResponseBuffers() { return new MyBuffers(_responseHeaderSize,_responseBufferSize); } // my own buffers protected JBuffer newBuffer(int size) { return BufferUtil.newDirectBuffer(size); } private class MyBuffers implements Buffers { private final int headerSize; private final int bufferSize; MyBuffers(int headerSize,int bufferSize) { this.headerSize = headerSize; this.bufferSize = bufferSize; } @Override public JBuffer getHeader() { return BufferUtil.newBuffer(headerSize); } @Override public JBuffer getBuffer() { return newBuffer(bufferSize); } @Override public JBuffer getBuffer(int size) { return newBuffer(size); } } }