📄 aprendpoint.java
字号:
/**
* SSL engine.
*/
protected boolean SSLEnabled = false;
public boolean isSSLEnabled() { return SSLEnabled; }
public void setSSLEnabled(boolean SSLEnabled) { this.SSLEnabled = SSLEnabled; }
/**
* SSL protocols.
*/
protected String SSLProtocol = "all";
public String getSSLProtocol() { return SSLProtocol; }
public void setSSLProtocol(String SSLProtocol) { this.SSLProtocol = SSLProtocol; }
/**
* SSL password (if a cert is encrypted, and no password has been provided, a callback
* will ask for a password).
*/
protected String SSLPassword = null;
public String getSSLPassword() { return SSLPassword; }
public void setSSLPassword(String SSLPassword) { this.SSLPassword = SSLPassword; }
/**
* SSL cipher suite.
*/
protected String SSLCipherSuite = "ALL";
public String getSSLCipherSuite() { return SSLCipherSuite; }
public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
/**
* SSL certificate file.
*/
protected String SSLCertificateFile = null;
public String getSSLCertificateFile() { return SSLCertificateFile; }
public void setSSLCertificateFile(String SSLCertificateFile) { this.SSLCertificateFile = SSLCertificateFile; }
/**
* SSL certificate key file.
*/
protected String SSLCertificateKeyFile = null;
public String getSSLCertificateKeyFile() { return SSLCertificateKeyFile; }
public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { this.SSLCertificateKeyFile = SSLCertificateKeyFile; }
/**
* SSL certificate chain file.
*/
protected String SSLCertificateChainFile = null;
public String getSSLCertificateChainFile() { return SSLCertificateChainFile; }
public void setSSLCertificateChainFile(String SSLCertificateChainFile) { this.SSLCertificateChainFile = SSLCertificateChainFile; }
/**
* SSL CA certificate path.
*/
protected String SSLCACertificatePath = null;
public String getSSLCACertificatePath() { return SSLCACertificatePath; }
public void setSSLCACertificatePath(String SSLCACertificatePath) { this.SSLCACertificatePath = SSLCACertificatePath; }
/**
* SSL CA certificate file.
*/
protected String SSLCACertificateFile = null;
public String getSSLCACertificateFile() { return SSLCACertificateFile; }
public void setSSLCACertificateFile(String SSLCACertificateFile) { this.SSLCACertificateFile = SSLCACertificateFile; }
/**
* SSL CA revocation path.
*/
protected String SSLCARevocationPath = null;
public String getSSLCARevocationPath() { return SSLCARevocationPath; }
public void setSSLCARevocationPath(String SSLCARevocationPath) { this.SSLCARevocationPath = SSLCARevocationPath; }
/**
* SSL CA revocation file.
*/
protected String SSLCARevocationFile = null;
public String getSSLCARevocationFile() { return SSLCARevocationFile; }
public void setSSLCARevocationFile(String SSLCARevocationFile) { this.SSLCARevocationFile = SSLCARevocationFile; }
/**
* SSL verify client.
*/
protected String SSLVerifyClient = "none";
public String getSSLVerifyClient() { return SSLVerifyClient; }
public void setSSLVerifyClient(String SSLVerifyClient) { this.SSLVerifyClient = SSLVerifyClient; }
/**
* SSL verify depth.
*/
protected int SSLVerifyDepth = 10;
public int getSSLVerifyDepth() { return SSLVerifyDepth; }
public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; }
// --------------------------------------------------------- Public Methods
/**
* Number of keepalive sockets.
*/
public int getKeepAliveCount() {
if (pollers == null) {
return 0;
} else {
int keepAliveCount = 0;
for (int i = 0; i < pollers.length; i++) {
keepAliveCount += pollers[i].getKeepAliveCount();
}
return keepAliveCount;
}
}
/**
* Number of sendfile sockets.
*/
public int getSendfileCount() {
if (sendfiles == null) {
return 0;
} else {
int sendfileCount = 0;
for (int i = 0; i < sendfiles.length; i++) {
sendfileCount += sendfiles[i].getSendfileCount();
}
return sendfileCount;
}
}
/**
* Return the amount of threads that are managed by the pool.
*
* @return the amount of threads that are managed by the pool
*/
public int getCurrentThreadCount() {
return curThreads;
}
/**
* Return the amount of threads currently busy.
*
* @return the amount of threads currently busy
*/
public int getCurrentThreadsBusy() {
return curThreadsBusy;
}
/**
* Return the state of the endpoint.
*
* @return true if the endpoint is running, false otherwise
*/
public boolean isRunning() {
return running;
}
/**
* Return the state of the endpoint.
*
* @return true if the endpoint is paused, false otherwise
*/
public boolean isPaused() {
return paused;
}
// ----------------------------------------------- Public Lifecycle Methods
/**
* Initialize the endpoint.
*/
public void init()
throws Exception {
if (initialized)
return;
// Create the root APR memory pool
rootPool = Pool.create(0);
// Create the pool for the server socket
serverSockPool = Pool.create(rootPool);
// Create the APR address that will be bound
String addressStr = null;
if (address == null) {
addressStr = null;
} else {
addressStr = address.getHostAddress();
}
int family = Socket.APR_INET;
if (Library.APR_HAVE_IPV6 && (addressStr == null || addressStr.indexOf(':') >= 0)) {
family = Socket.APR_UNSPEC;
}
long inetAddress = Address.info(addressStr, family,
port, 0, rootPool);
// Create the APR server socket
serverSock = Socket.create(family, Socket.SOCK_STREAM,
Socket.APR_PROTO_TCP, rootPool);
if (OS.IS_UNIX) {
Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
}
// Deal with the firewalls that tend to drop the inactive sockets
Socket.optSet(serverSock, Socket.APR_SO_KEEPALIVE, 1);
// Bind the server socket
int ret = Socket.bind(serverSock, inetAddress);
if (ret != 0) {
throw new Exception(sm.getString("endpoint.init.bind", "" + ret, Error.strerror(ret)));
}
// Start listening on the server socket
ret = Socket.listen(serverSock, backlog);
if (ret != 0) {
throw new Exception(sm.getString("endpoint.init.listen", "" + ret, Error.strerror(ret)));
}
if (OS.IS_WIN32 || OS.IS_WIN64) {
// On Windows set the reuseaddr flag after the bind/listen
Socket.optSet(serverSock, Socket.APR_SO_REUSEADDR, 1);
}
// Sendfile usage on systems which don't support it cause major problems
if (useSendfile && !Library.APR_HAS_SENDFILE) {
log.warn(sm.getString("endpoint.sendfile.nosupport"));
useSendfile = false;
}
// Initialize thread count defaults for acceptor, poller and sendfile
if (acceptorThreadCount == 0) {
// FIXME: Doesn't seem to work that well with multiple accept threads
acceptorThreadCount = 1;
}
if (pollerThreadCount == 0) {
if ((OS.IS_WIN32 || OS.IS_WIN64) && (pollerSize > 1024)) {
// The maximum per poller to get reasonable performance is 1024
pollerThreadCount = pollerSize / 1024;
// Adjust poller size so that it won't reach the limit
pollerSize = pollerSize - (pollerSize % 1024);
} else {
// No explicit poller size limitation
pollerThreadCount = 1;
}
}
if (sendfileThreadCount == 0) {
if ((OS.IS_WIN32 || OS.IS_WIN64) && (sendfileSize > 1024)) {
// The maximum per poller to get reasonable performance is 1024
sendfileThreadCount = sendfileSize / 1024;
// Adjust poller size so that it won't reach the limit
sendfileSize = sendfileSize - (sendfileSize % 1024);
} else {
// No explicit poller size limitation
// FIXME: Default to one per CPU ?
sendfileThreadCount = 1;
}
}
// Delay accepting of new connections until data is available
// Only Linux kernels 2.4 + have that implemented
// on other platforms this call is noop and will return APR_ENOTIMPL.
Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1);
// Initialize SSL if needed
if (SSLEnabled) {
// SSL protocol
int value = SSL.SSL_PROTOCOL_ALL;
if ("SSLv2".equalsIgnoreCase(SSLProtocol)) {
value = SSL.SSL_PROTOCOL_SSLV2;
} else if ("SSLv3".equalsIgnoreCase(SSLProtocol)) {
value = SSL.SSL_PROTOCOL_SSLV3;
} else if ("TLSv1".equalsIgnoreCase(SSLProtocol)) {
value = SSL.SSL_PROTOCOL_TLSV1;
} else if ("SSLv2+SSLv3".equalsIgnoreCase(SSLProtocol)) {
value = SSL.SSL_PROTOCOL_SSLV2 | SSL.SSL_PROTOCOL_SSLV3;
}
// Create SSL Context
sslContext = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
// List the ciphers that the client is permitted to negotiate
SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
// Load Server key and certificate
SSLContext.setCertificate(sslContext, SSLCertificateFile, SSLCertificateKeyFile, SSLPassword, SSL.SSL_AIDX_RSA);
// Set certificate chain file
SSLContext.setCertificateChainFile(sslContext, SSLCertificateChainFile, false);
// Support Client Certificates
SSLContext.setCACertificate(sslContext, SSLCACertificateFile, SSLCACertificatePath);
// Set revocation
SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
// Client certificate verification
value = SSL.SSL_CVERIFY_NONE;
if ("optional".equalsIgnoreCase(SSLVerifyClient)) {
value = SSL.SSL_CVERIFY_OPTIONAL;
} else if ("require".equalsIgnoreCase(SSLVerifyClient)) {
value = SSL.SSL_CVERIFY_REQUIRE;
} else if ("optionalNoCA".equalsIgnoreCase(SSLVerifyClient)) {
value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
}
SSLContext.setVerify(sslContext, value, SSLVerifyDepth);
// For now, sendfile is not supported with SSL
useSendfile = false;
}
initialized = true;
}
/**
* Start the APR endpoint, creating acceptor, poller and sendfile threads.
*/
public void start()
throws Exception {
// Initialize socket if not done before
if (!initialized) {
init();
}
if (!running) {
running = true;
paused = false;
// Create worker collection
if (executor == null) {
workers = new WorkerStack(maxThreads);
}
// Start acceptor threads
for (int i = 0; i < acceptorThreadCount; i++) {
Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);
acceptorThread.setPriority(threadPriority);
acceptorThread.setDaemon(daemon);
acceptorThread.start();
}
// Start poller threads
pollers = new Poller[pollerThreadCount];
for (int i = 0; i < pollerThreadCount; i++) {
pollers[i] = new Poller(false);
pollers[i].init();
Thread pollerThread = new Thread(pollers[i], getName() + "-Poller-" + i);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
}
// Start comet poller threads
cometPollers = new Poller[pollerThreadCount];
for (int i = 0; i < pollerThreadCount; i++) {
cometPollers[i] = new Poller(true);
cometPollers[i].init();
Thread pollerThread = new Thread(cometPollers[i], getName() + "-CometPoller-" + i);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
}
// Start sendfile threads
if (useSendfile) {
sendfiles = new Sendfile[sendfileThreadCount];
for (int i = 0; i < sendfileThreadCount; i++) {
sendfiles[i] = new Sendfile();
sendfiles[i].init();
Thread sendfileThread = new Thread(sendfiles[i], getName() + "-Sendfile-" + i);
sendfileThread.setPriority(threadPriority);
sendfileThread.setDaemon(true);
sendfileThread.start();
}
}
}
}
/**
* Pause the endpoint, which will make it stop accepting new sockets.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -