You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2012/03/13 13:41:58 UTC
svn commit: r1300102 - in /tomcat/trunk/java/org/apache: coyote/spdy/
tomcat/jni/ tomcat/jni/socket/ tomcat/spdy/
Author: markt
Date: Tue Mar 13 12:41:57 2012
New Revision: 1300102
URL: http://svn.apache.org/viewvc?rev=1300102&view=rev
Log:
Code clean-up:
- one missing license header
- lots of trailing whitespace
- some unused imports
- an unnecessary cast
- some unnecessary code
Still need to fix the import checks
Modified:
tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java
tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java
tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java
tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java
tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java
Modified: tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java (original)
+++ tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java Tue Mar 13 12:41:57 2012
@@ -17,18 +17,12 @@
package org.apache.coyote.spdy;
import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
import org.apache.coyote.Adapter;
import org.apache.coyote.http11.Http11AprProtocol;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
-import org.apache.tomcat.jni.Error;
import org.apache.tomcat.jni.SSLExt;
-import org.apache.tomcat.jni.Status;
-import org.apache.tomcat.jni.socket.AprSocketContext;
-import org.apache.tomcat.spdy.CompressDeflater6;
import org.apache.tomcat.spdy.SpdyConnection;
import org.apache.tomcat.spdy.SpdyContext;
import org.apache.tomcat.spdy.SpdyContextJni;
@@ -113,7 +107,7 @@ public class SpdyAprNpnHandler implement
Http11AprProtocol proto, AbstractEndpoint endpoint) {
SocketWrapper<Long> socketW = socketO;
- long socket = ((Long) socketW.getSocket()).longValue();
+ long socket = socketW.getSocket().longValue();
try {
spdyContext.onAccept(socket);
@@ -125,6 +119,4 @@ public class SpdyAprNpnHandler implement
public void onClose(SocketWrapper<Long> socketWrapper) {
}
-
-
}
Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java Tue Mar 13 12:41:57 2012
@@ -92,9 +92,9 @@ public final class SSLExt {
* Return the last openssl error
*/
public static native String sslErrReasonErrorString();
-
+
public static native long sslCtxSetMode(long ctx, long mode);
-
+
/* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success
* when just a single record has been written): */
public static final int SSL_MODE_ENABLE_PARTIAL_WRITE = 0x1;
Modified: tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java Tue Mar 13 12:41:57 2012
@@ -37,21 +37,21 @@ import org.apache.tomcat.jni.socket.AprS
import org.apache.tomcat.jni.socket.AprSocketContext.BlockingPollHandler;
/**
- * Native socket, using JNI + APR + openssl.
- *
+ * Native socket, using JNI + APR + openssl.
+ *
* The socket is non-blocking - you can register either a blocking or non
* blocking callback.
- *
- * There is no explicit method to register/unregister poll interest -
+ *
+ * There is no explicit method to register/unregister poll interest -
* it is done automatically, when read/write methods return 0.
- *
+ *
* To keep the socket polling you must read all the available data, until
* read() returns 0. If you want to pause - don't read all input. To resume -
* read again until it returns 0.
- *
- * Same for write - when write() returns 0 the socket is registered for
- * write interest.
- *
+ *
+ * Same for write - when write() returns 0 the socket is registered for
+ * write interest.
+ *
* You can also use the blocking read/write methods.
*/
public class AprSocket implements Runnable {
@@ -62,13 +62,13 @@ public class AprSocket implements Runnab
static int CONNECTING = 1;
static int CONNECTED = 0x2;
-
+
// Current ( real ) poll status
static int POLLIN_ACTIVE = 0x4;
static int POLLOUT_ACTIVE = 0x8;
-
+
static int POLL = 0x10;
-
+
static int SSL_ATTACHED = 0x40;
// Requested poll status. Set by read/write when needed.
@@ -89,19 +89,19 @@ public class AprSocket implements Runnab
// only one - to save per/socket memory - context has similar callbacks.
BlockingPollHandler handler;
- // Set while it's associated with a poller - it'll stay associated after
+ // Set while it's associated with a poller - it'll stay associated after
// connect until close. Destroy will happen in the poller.
// POLL bit indicates if the socket is actually polling.
AprPoller poller;
-
- // Bit field indicating the status and socket should only be accessed with
+
+ // Bit field indicating the status and socket should only be accessed with
// socketLock protection
private int status;
-
+
long socket;
//long to = 10000;
-
+
// Persistent info about the peer ( SSL, etc )
private HostInfo hostInfo;
@@ -118,14 +118,14 @@ public class AprSocket implements Runnab
}
public String toString() {
- return (context.isServer() ? "AprSrv-" : "AprCli-") +
+ return (context.isServer() ? "AprSrv-" : "AprCli-") +
Long.toHexString(socket) + " " + Integer.toHexString(status);
}
public void setHandler(BlockingPollHandler l) {
handler = l;
}
-
+
private void setNonBlocking() {
if (socket != 0 && context.running) {
Socket.optSet(socket, Socket.APR_SO_NONBLOCK, 1);
@@ -145,7 +145,7 @@ public class AprSocket implements Runnab
public BlockingPollHandler getHandler() {
return handler;
}
-
+
public AprSocketContext getContext() {
return context;
}
@@ -154,7 +154,7 @@ public class AprSocket implements Runnab
hostInfo = hi;
return this;
}
-
+
/**
*/
public void connect() throws IOException {
@@ -184,21 +184,21 @@ public class AprSocket implements Runnab
setStatus(CONNECTED);
clearStatus(CONNECTING);
-
+
notifyConnected(false);
}
-
+
public HostInfo getHost() {
return hostInfo;
}
/**
- * Write.
- *
- * For both blocking and non-blocking, it'll return the number of bytes
+ * Write.
+ *
+ * For both blocking and non-blocking, it'll return the number of bytes
* written - it'll attempt to send as much as possible, but if the buffers
- * are full it'll return 0.
- *
+ * are full it'll return 0.
+ *
* @param data
* @param off
* @param len
@@ -213,7 +213,7 @@ public class AprSocket implements Runnab
if (rc < 0) {
throw new IOException("Write error " + rc);
} else if (rc == 0) {
- // need poll out - do we need to update polling ?
+ // need poll out - do we need to update polling ?
context.findPollerAndAdd(this);
} else {
return rc;
@@ -237,20 +237,20 @@ public class AprSocket implements Runnab
if (rc < 0) {
throw new IOException("Write error " + rc);
} else if (rc == 0) {
- // need poll out - do we need to update polling ?
+ // need poll out - do we need to update polling ?
synchronized (this) {
context.findPollerAndAdd(this);
}
}
return rc;
}
-
+
private int writeInternal(byte[] data, int off, int len) throws IOException {
int rt = 0;
int sent = 0;
synchronized(this) {
- if ((status & CLOSED) != 0
- || socket == 0
+ if ((status & CLOSED) != 0
+ || socket == 0
|| !context.running) {
throw new IOException("Closed");
}
@@ -258,7 +258,7 @@ public class AprSocket implements Runnab
throw new IOException("Write from 2 threads not allowed");
}
status |= WRITING;
-
+
while (len > 0) {
sent = Socket.send(socket, data, off, len);
if (sent <= 0) {
@@ -318,12 +318,12 @@ public class AprSocket implements Runnab
if (context.rawDataHandler != null) {
context.rawData(this, true, data, off, read, len, false);
}
-
+
if (read > 0) {
return read;
}
- if (read == 0 || read == -Status.TIMEUP || read == -Status.ETIMEDOUT
+ if (read == 0 || read == -Status.TIMEUP || read == -Status.ETIMEDOUT
|| read == -Status.EAGAIN) {
read = 0;
setStatus(POLLIN);
@@ -343,8 +343,8 @@ public class AprSocket implements Runnab
public int readNB(byte[] data, int off, int len) throws IOException {
int read;
synchronized(this) {
- if ((status & CLOSED) != 0
- || socket == 0
+ if ((status & CLOSED) != 0
+ || socket == 0
|| !context.running) {
return -1;
}
@@ -352,19 +352,19 @@ public class AprSocket implements Runnab
throw new IOException("Read from 2 threads not allowed");
}
status |= READING;
-
+
read = Socket.recv(socket, data, off, len);
status &= ~READING;
}
return processReadResult(data, off, len, read);
}
-
+
/*
No support for shutdownOutput: SSL is quite tricky.
Use close() instead - no read/write will be allowed after.
-
+
*/
-
+
public void close() throws IOException {
synchronized (this) {
if ((status & CLOSED) != 0 || socket == 0) {
@@ -373,7 +373,7 @@ public class AprSocket implements Runnab
status |= CLOSED;
status &= ~POLLIN;
status &= ~POLLOUT;
- }
+ }
if (context.rawDataHandler != null) {
context.rawDataHandler.rawData(this, false, null, 0, 0, 0, true);
}
@@ -404,41 +404,41 @@ public class AprSocket implements Runnab
if ((status & (WRITING | READING)) != 0) {
return; // not closed
}
-
+
if (context.rawDataHandler != null) {
context.rawDataHandler.rawData(this, false, null, -1, -1, -1, true);
}
if (context.debug) {
log.info("closing: context.open=" + context.open.get() + " " + this);
}
-
+
context.open.decrementAndGet();
-
+
if (socket != 0 && (status & CLOSED) == 0) {
Socket.close(socket);
status |= CLOSED;
}
-
+
if (handler != null) {
if (isBlocking()) {
context.getExecutor().execute(this);
} else {
- handler.closed(this);
+ handler.closed(this);
}
}
-
+
context.destroySocket(this);
}
}
-
-
+
+
/**
* Close input and output, potentially sending RST, than close the socket.
- *
- * The proper way to close when gracefully done is by calling writeEnd() and
- * reading all remaining input until -1 (EOF) is received.
- *
+ *
+ * The proper way to close when gracefully done is by calling writeEnd() and
+ * reading all remaining input until -1 (EOF) is received.
+ *
* If EOF is received, the proper way to close is send whatever is remaining and
* call writeEnd();
*/
@@ -450,7 +450,7 @@ public class AprSocket implements Runnab
e.printStackTrace();
}
}
-
+
/**
*/
@@ -470,7 +470,7 @@ public class AprSocket implements Runnab
} catch (Exception e) {
throw new IOException(e);
}
- } else {
+ } else {
throw new IOException("Socket is closed");
}
}
@@ -631,7 +631,7 @@ public class AprSocket implements Runnab
}
throw new IOException("Socket closed");
}
-
+
public boolean isBlocking() {
return ! (handler instanceof AprSocketContext.NonBlockingPollHandler);
}
@@ -643,7 +643,7 @@ public class AprSocket implements Runnab
void notifyError(Throwable err, boolean needsThread) {
if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
if (err != null) {
- ((AprSocketContext.NonBlockingPollHandler) handler).error(this, err);
+ ((AprSocketContext.NonBlockingPollHandler) handler).error(this, err);
}
} else {
// poller destroyed, etc
@@ -682,16 +682,16 @@ public class AprSocket implements Runnab
private void notifyConnected(boolean server) throws IOException {
// Will set the handler on the channel for accepted
context.onSocket(this);
-
+
if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
((AprSocketContext.NonBlockingPollHandler) handler).connected(this);
-
+
((AprSocketContext.NonBlockingPollHandler) handler).process(this, true, true, false);
- // Now register for polling - unless process() set suspendRead and
+ // Now register for polling - unless process() set suspendRead and
// doesn't need out notifications
updatePolling();
} else {
- if (server) {
+ if (server) {
// client will block in connect().
// Server: call process();
notifyIO();
@@ -726,7 +726,7 @@ public class AprSocket implements Runnab
context.open.incrementAndGet();
if (context.debug) {
- log.info("Accept: " + context.open.get() + " " + this + " " +
+ log.info("Accept: " + context.open.get() + " " + this + " " +
getRemotePort());
}
if (context.tcpNoDelay) {
@@ -739,7 +739,7 @@ public class AprSocket implements Runnab
blockingStartTLS();
}
setNonBlocking(); // call again, to set the bits ( connect was blocking )
-
+
notifyConnected(true);
return;
} catch (Throwable t) {
@@ -748,7 +748,7 @@ public class AprSocket implements Runnab
notifyError(t, false);
return;
}
- }
+ }
if (checkPreConnect(CONNECTING)) {
// Non-blocking connect - will call 'afterConnection' at the end.
try {
@@ -756,7 +756,7 @@ public class AprSocket implements Runnab
} catch (IOException t) {
reset(); // also sets status ERROR
if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
- ((AprSocketContext.NonBlockingPollHandler) handler).process(this, false, false, true);
+ ((AprSocketContext.NonBlockingPollHandler) handler).process(this, false, false, true);
}
notifyError(t, false);
}
@@ -776,12 +776,12 @@ public class AprSocket implements Runnab
/**
* This is a blocking call ! ( can be made non-blocking, but too complex )
- *
+ *
* Will be called automatically after connect() or accept if 'secure' is
* true.
- *
+ *
* Can be called manually to upgrade the channel
- * @throws IOException
+ * @throws IOException
*/
public void blockingStartTLS() throws IOException {
synchronized(this) {
@@ -793,15 +793,15 @@ public class AprSocket implements Runnab
}
status |= SSL_ATTACHED;
}
-
+
try {
if (context.debug) {
log.info(this + " StartSSL");
}
-
+
AprSocketContext aprCon = (AprSocketContext) context;
SSLSocket.attach(aprCon.getSslCtx(), socket);
-
+
if (context.debugSSL) {
SSLExt.debug(socket);
}
@@ -814,17 +814,17 @@ public class AprSocket implements Runnab
hostInfo.sessDer.length);
}
}
- SSLExt.sslSetMode(socket, SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
+ SSLExt.sslSetMode(socket, SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
SSLExt.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
+
int rc = SSLSocket.handshake(socket);
-
- // At this point we have the session ID, remote certs, etc
+
+ // At this point we have the session ID, remote certs, etc
// we can lookup host info
if (hostInfo == null) {
hostInfo = new HostInfo();
}
-
+
if (rc != Status.APR_SUCCESS) {
throw new IOException(this + " Handshake failed " + rc + " "
+ Error.strerror(rc) + " SSLL "
@@ -856,8 +856,8 @@ public class AprSocket implements Runnab
}
}
}
-
- // TODO: if the ticket, session id or session changed - callback to
+
+ // TODO: if the ticket, session id or session changed - callback to
// save the session again
try {
hostInfo.sessDer = SSLExt.getSessionData(socket);
@@ -867,13 +867,13 @@ public class AprSocket implements Runnab
} catch (Exception e) {
throw new IOException(e);
}
-
+
hostInfo.npn = new byte[32];
hostInfo.npnLen = SSLExt.getNPN(socket, hostInfo.npn);
-
+
// If custom verification is used - should check the certificates
if (context.tlsCertVerifier != null) {
- context.tlsCertVerifier.handshakeDone(this);
+ context.tlsCertVerifier.handshakeDone(this);
}
}
@@ -883,7 +883,7 @@ public class AprSocket implements Runnab
return 0;
}
// Implicit:
- //Poll.APR_POLLNVAL | Poll.APR_POLLHUP | Poll.APR_POLLERR |
+ //Poll.APR_POLLNVAL | Poll.APR_POLLHUP | Poll.APR_POLLERR |
int res = 0;
if ((status & POLLIN) != 0) {
res = Poll.APR_POLLIN;
@@ -894,10 +894,10 @@ public class AprSocket implements Runnab
return res;
}
}
-
+
boolean checkBitAndSocket(int bit) {
synchronized (this) {
- return ((status & bit) != 0 && socket != 0 &&
+ return ((status & bit) != 0 && socket != 0 &&
(status & CLOSED) == 0 && context.running);
}
}
@@ -921,6 +921,6 @@ public class AprSocket implements Runnab
return old != 0;
}
}
-
-
+
+
}
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java Tue Mar 13 12:41:57 2012
@@ -50,33 +50,33 @@ import org.apache.tomcat.jni.Socket;
import org.apache.tomcat.jni.Status;
public class AprSocketContext {
- /**
+ /**
* Called when a chunk of data is sent or received. This is very low
- * level, used mostly for debugging or stats.
+ * level, used mostly for debugging or stats.
*/
public static interface RawDataHandler {
- public void rawData(AprSocket ch, boolean input, byte[] data, int pos,
+ public void rawData(AprSocket ch, boolean input, byte[] data, int pos,
int len, int requested, boolean closed);
}
/**
* Called in SSL mode after the handshake is completed.
- *
+ *
* @see AprSocketContext.customVerification()
*/
public static interface TlsCertVerifier {
public void handshakeDone(AprSocket ch);
}
-
+
/**
- * Delegates loading of persistent info about a host - public certs,
+ * Delegates loading of persistent info about a host - public certs,
* tickets, config, persistent info etc.
*/
public static interface HostInfoLoader {
- public HostInfo getHostInfo(String name, int port, boolean ssl);
+ public HostInfo getHostInfo(String name, int port, boolean ssl);
}
-
- /**
+
+ /**
* Reads/writes of this size or lower are using Get/SetByteArrayRegion.
* Larger reads use Get/ReelaseByteArrayElements.
* Larger writes use malloc/free + GetByteArrayRagion.
@@ -84,57 +84,57 @@ public class AprSocketContext {
static final int TCN_BUFFER_SZ = 8192;
static Logger log = Logger.getLogger("AprSocketCtx");
-
- // If interrupt() or thread-safe poll update are not supported - the
- // poll updates will happen after the poll() timeout.
- // The poll timeout with interrupt/thread safe updates can be much higher/
+
+ // If interrupt() or thread-safe poll update are not supported - the
+ // poll updates will happen after the poll() timeout.
+ // The poll timeout with interrupt/thread safe updates can be much higher/
static int FALLBACK_POLL_TIME = 2000;
static int MAX_POLL_SIZE = 60;
-
+
// It seems to send the ticket, get server helo / ChangeCipherSpec, but than
// SSL3_GET_RECORD:decryption failed or bad record mac in s3_pkt.c:480:
// Either bug in openssl, or some combination of ciphers - needs more debugging.
// ( this can save a roundtrip and CPU on TLS handshake )
boolean USE_TICKETS = false;
-
+
boolean useFinalizer = true;
final AprSocket END = new AprSocket(this);
-
+
static AtomicInteger contextNumber = new AtomicInteger();
int contextId;
-
+
AtomicInteger threadNumber = new AtomicInteger();
/**
- * For now - single acceptor thread per connector.
+ * For now - single acceptor thread per connector.
*/
AcceptorThread acceptor;
AcceptorDispatchThread acceptorDispatch;
-
+
// APR/JNI is thread safe
boolean threadSafe = true;
-
- /**
- * Pollers.
+
+ /**
+ * Pollers.
*/
List<AprPoller> pollers = new ArrayList<AprPoller>();
static int pollerCnt = 0;
-
+
// Set on all accepted or connected sockets.
// TODO: add the other properties
boolean tcpNoDelay = true;
-
+
protected boolean running = true;
-
+
protected boolean sslMode;
// onSocket() will be called in accept thread.
// If false: use executor ( but that may choke the acceptor thread )
protected boolean nonBlockingAccept = false;
-
+
BlockingQueue<AprSocket> acceptedQueue = new LinkedBlockingQueue<AprSocket>();
-
+
/**
* Root APR memory pool.
*/
@@ -147,43 +147,43 @@ public class AprSocketContext {
TlsCertVerifier tlsCertVerifier;
- //
+ //
int connectTimeout = 20000;
int defaultTimeout = 100000;
-
+
int keepAliveTimeout = 20000;
-
+
AtomicInteger open = new AtomicInteger();
-
+
/**
- * Poll interval, in microseconds. If the platform doesn't support
- * poll interrupt - it'll take this time to stop the poller.
- *
+ * Poll interval, in microseconds. If the platform doesn't support
+ * poll interrupt - it'll take this time to stop the poller.
+ *
*/
- protected int pollTime = 5 * 1000000;
-
+ protected int pollTime = 5 * 1000000;
+
HostInfoLoader hostInfoLoader;
RawDataHandler rawDataHandler = null;
-
+
// TODO: do we need this here ?
protected Map<String, HostInfo> hosts = new HashMap<String, HostInfo>();
String[] enabledCiphers;
-
+
String certFile;
String keyFile;
-
+
byte[] spdyNPN;
-
+
byte[] ticketKey;
-
+
// For resolving DNS ( i.e. connect ), callbacks
private ExecutorService threadPool;
// Separate executor for connect/handshakes
ExecutorService connectExecutor;
-
+
boolean debug = false;
boolean debugSSL = false;
boolean debugPoll = false;
@@ -196,21 +196,21 @@ public class AprSocketContext {
int sslProtocol = SSL.SSL_PROTOCOL_TLSV1 | SSL.SSL_PROTOCOL_SSLV3;
- /**
+ /**
* Max time spent in a callback ( will be longer for blocking )
*/
AtomicLong maxHandlerTime = new AtomicLong();
AtomicLong totalHandlerTime = new AtomicLong();
AtomicLong handlerCount = new AtomicLong();
- /**
+ /**
* Total connections handled ( accepted or connected ).
*/
AtomicInteger connectionsCount = new AtomicInteger();
-
+
public AprSocketContext() {
- connectExecutor =new ThreadPoolExecutor(0, 64, 5, TimeUnit.SECONDS,
+ connectExecutor =new ThreadPoolExecutor(0, 64, 5, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(), new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r,
@@ -222,37 +222,37 @@ public class AprSocketContext {
});
contextId = contextNumber.incrementAndGet();
}
-
+
/**
* Poller thread count.
*/
protected int pollerThreadCount = 4;
public void setPollerThreadCount(int pollerThreadCount) { this.pollerThreadCount = pollerThreadCount; }
public int getPollerThreadCount() { return pollerThreadCount; }
-
+
// to test the limits - default should be lower
int maxConnections = 64 * 1024;
public void setMaxconnections(int maxCon) {
this.maxConnections = maxCon;
}
-
+
public void setBacklog(int backlog) { if (backlog > 0) this.backlog = backlog; }
public int getBacklog() { return backlog; }
-
+
/**
* Defer accept.
*/
public void setDeferAccept(boolean deferAccept) { this.deferAccept = deferAccept; }
public boolean getDeferAccept() { return deferAccept; }
-
+
/**
- * For client:
- * - ClientHello will include the npn extension ( the ID == 0x3374)
+ * For client:
+ * - ClientHello will include the npn extension ( the ID == 0x3374)
* - if ServerHello includes a list of protocols - select one
* - send it after ChangeCipherSpec and before Finish
- *
+ *
* For server:
- * - if ClientHello includes the npn extension
+ * - if ClientHello includes the npn extension
* -- will send this string as list of supported protocols in ServerHello
* - read the selection before Finish.
* @param npn
@@ -265,13 +265,13 @@ public class AprSocketContext {
npnB[0] = (byte) data.length;
npnB[npnB.length - 1] = 0;
spdyNPN = npnB;
-
+
}
-
+
public void setNpn(byte[] data) {
spdyNPN = data;
}
-
+
public void setHostLoader(HostInfoLoader handler) {
this.hostInfoLoader = handler;
}
@@ -279,13 +279,13 @@ public class AprSocketContext {
public boolean isServer() {
return acceptor != null;
}
-
+
protected Executor getExecutor() {
if (threadPool == null) {
threadPool = Executors.newCachedThreadPool(new ThreadFactory( ) {
@Override
public Thread newThread(Runnable r) {
- Thread t = new Thread(r, "AprThread-" + contextId + "-" +
+ Thread t = new Thread(r, "AprThread-" + contextId + "-" +
threadNumber.incrementAndGet());
t.setDaemon(true);
return t;
@@ -294,7 +294,7 @@ public class AprSocketContext {
}
return threadPool;
}
-
+
/**
* All accepted/connected sockets will start handshake automatically.
*/
@@ -306,7 +306,7 @@ public class AprSocketContext {
public void setTcpNoDelay(boolean b) {
tcpNoDelay = b;
}
-
+
public void setSslProtocol(String protocol) {
protocol = protocol.trim();
if ("SSLv2".equalsIgnoreCase(protocol)) {
@@ -317,26 +317,26 @@ public class AprSocketContext {
sslProtocol = SSL.SSL_PROTOCOL_TLSV1;
} else if ("all".equalsIgnoreCase(protocol)) {
sslProtocol = SSL.SSL_PROTOCOL_ALL;
- }
+ }
}
-
+
public void setTicketKey(byte[] key48Bytes) {
if(key48Bytes.length != 48) {
throw new RuntimeException("Key must be 48 bytes");
}
this.ticketKey = key48Bytes;
}
-
+
public void customVerification(TlsCertVerifier verifier) {
tlsCertVerifier = verifier;
}
-
+
public void setEnabledCiphers(String[] enabled) {
enabledCiphers = enabled;
}
// TODO: should have a separate method for switching to tls later.
- /**
+ /**
* Set certificate, will also enable TLS mode.
*/
public AprSocketContext setKeys(String certPemFile, String keyDerFile)
@@ -347,14 +347,14 @@ public class AprSocketContext {
keyFile = keyDerFile;
return this;
}
-
+
/**
* SSL cipher suite.
*/
protected String SSLCipherSuite = "ALL";
public String getSSLCipherSuite() { return SSLCipherSuite; }
public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
-
+
/**
* Override or use hostInfoLoader to implement persistent/memcache storage.
*/
@@ -373,7 +373,7 @@ public class AprSocketContext {
return pi;
}
- protected void rawData(AprSocket ch, boolean inp, byte[] data, int pos,
+ protected void rawData(AprSocket ch, boolean inp, byte[] data, int pos,
int len, int requested, boolean closed) {
if (rawDataHandler != null) {
rawDataHandler.rawData(ch, inp, data, pos, len, requested, closed);
@@ -392,15 +392,15 @@ public class AprSocketContext {
acceptorDispatch.setName("AprAcceptorDispatch-" + port);
acceptorDispatch.start();
}
-
+
acceptor = new AcceptorThread(port);
acceptor.prepare();
acceptor.setName("AprAcceptor-" + port);
acceptor.start();
-
-
+
+
}
-
+
/**
* Get a socket for connectiong to host:port.
*/
@@ -408,12 +408,12 @@ public class AprSocketContext {
HostInfo hi = getHostInfo(host, port, ssl);
return socket(hi);
}
-
+
public AprSocket socket(HostInfo hi) throws IOException {
AprSocket sock = newSocket(this);
sock.setHost(hi);
return sock;
- }
+ }
public AprSocket socket(long socket) throws IOException {
AprSocket sock = newSocket(this);
@@ -434,7 +434,7 @@ public class AprSocketContext {
}
}
}
-
+
protected void connectBlocking(AprSocket apr) throws IOException {
try {
if (!running) {
@@ -445,50 +445,50 @@ public class AprSocketContext {
long clientSockP;
synchronized (pollers) {
long socketpool = Pool.create(getRootPool());
-
+
int family = Socket.APR_INET;
clientSockP = Socket.create(family,
Socket.SOCK_STREAM,
Socket.APR_PROTO_TCP, socketpool); // or rootPool ?
}
- Socket.timeoutSet(clientSockP, connectTimeout * 1000);
+ Socket.timeoutSet(clientSockP, connectTimeout * 1000);
if (OS.IS_UNIX) {
Socket.optSet(clientSockP, Socket.APR_SO_REUSEADDR, 1);
}
-
+
Socket.optSet(clientSockP, Socket.APR_SO_KEEPALIVE, 1);
-
- // Blocking
+
+ // Blocking
// TODO: use socket pool
// TODO: cache it ( and TTL ) in hi
long inetAddress = Address.info(hi.host, Socket.APR_INET,
hi.port, 0, rootPool);
- // this may take a long time - stop/destroy must wait
+ // this may take a long time - stop/destroy must wait
// at least connect timeout
int rc = Socket.connect(clientSockP, inetAddress);
-
+
if (rc != 0) {
synchronized (pollers) {
Socket.close(clientSockP);
- Socket.destroy(clientSockP);
+ Socket.destroy(clientSockP);
}
/////Pool.destroy(socketpool);
throw new IOException("Socket.connect(): " + rc + " " + Error.strerror(rc) + " " + connectTimeout);
}
if (!running) {
- throw new IOException("Stopped");
+ throw new IOException("Stopped");
}
-
+
connectionsCount.incrementAndGet();
if (tcpNoDelay) {
Socket.optSet(clientSockP, Socket.APR_TCP_NODELAY, 1);
}
- Socket.timeoutSet(clientSockP, defaultTimeout * 1000);
-
+ Socket.timeoutSet(clientSockP, defaultTimeout * 1000);
+
apr.socket = clientSockP;
-
+
apr.afterConnect();
} catch (IOException e) {
apr.reset();
@@ -519,7 +519,7 @@ public class AprSocketContext {
}
}
}
-
+
public void stop() throws IOException {
synchronized (pollers) {
@@ -528,7 +528,7 @@ public class AprSocketContext {
}
running = false;
}
-
+
if (rootPool != 0) {
if (acceptor != null) {
try {
@@ -537,7 +537,7 @@ public class AprSocketContext {
} catch (InterruptedException e) {
e.printStackTrace();
}
- }
+ }
if (acceptorDispatch != null) {
acceptedQueue.add(END);
try {
@@ -549,9 +549,9 @@ public class AprSocketContext {
if (threadPool != null) {
threadPool.shutdownNow();
}
-
+
log.info("Stopping pollers " + contextId);
-
+
while (true) {
AprPoller a;
synchronized (pollers) {
@@ -570,7 +570,7 @@ public class AprSocketContext {
}
}
}
-
+
// Called when the last poller has been destroyed.
void destroy() {
@@ -578,28 +578,28 @@ public class AprSocketContext {
if (pollers.size() != 0) {
return;
}
-
+
if (rootPool == 0) {
return;
}
System.err.println("DESTROY " + rootPool);
//Pool.destroy(rootPool);
- //rootPool = 0;
+ //rootPool = 0;
}
}
-
+
static IOException noApr;
static {
-
+
try {
Library.initialize(null);
- SSL.initialize(null);
+ SSL.initialize(null);
} catch (Exception e) {
noApr = new IOException("APR not present", e);
}
-
+
}
-
+
private long getRootPool() throws IOException {
if (rootPool == 0) {
if (noApr != null) {
@@ -618,40 +618,40 @@ public class AprSocketContext {
}
return rootPool;
}
-
+
long getSslCtx() throws Exception {
if (sslCtx == 0) {
synchronized (AprSocketContext.class) {
-
+
boolean serverMode = acceptor != null;
- sslCtx = SSLContext.make(getRootPool(),
+ sslCtx = SSLContext.make(getRootPool(),
sslProtocol,
serverMode ? SSL.SSL_MODE_SERVER : SSL.SSL_MODE_CLIENT);
-
- // SSL.SSL_OP_NO_SSLv3
+
+ // SSL.SSL_OP_NO_SSLv3
int opts = SSL.SSL_OP_NO_SSLv2 |
SSL.SSL_OP_SINGLE_DH_USE;
-
+
if (!USE_TICKETS || serverMode && ticketKey == null) {
opts |= SSL.SSL_OP_NO_TICKET;
}
-
+
SSLContext.setOptions(sslCtx, opts);
// Set revocation
// SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
-
+
// Client certificate verification - maybe make it option
try {
SSLContext.setCipherSuite(sslCtx, SSLCipherSuite);
-
-
+
+
if (serverMode) {
if (ticketKey != null) {
//SSLExt.setTicketKeys(sslCtx, ticketKey, ticketKey.length);
}
if (certFile != null) {
- boolean rc = SSLContext.setCertificate(sslCtx,
+ boolean rc = SSLContext.setCertificate(sslCtx,
certFile,
keyFile, null, SSL.SSL_AIDX_DSA);
if (!rc) {
@@ -659,23 +659,23 @@ public class AprSocketContext {
}
}
SSLContext.setVerify(sslCtx, SSL.SSL_CVERIFY_NONE, 10);
-
+
if (spdyNPN != null) {
SSLExt.setNPN(sslCtx, spdyNPN, spdyNPN.length);
}
} else {
if (tlsCertVerifier != null) {
- // NONE ?
- SSLContext.setVerify(sslCtx,
- SSL.SSL_CVERIFY_NONE, 10);
+ // NONE ?
+ SSLContext.setVerify(sslCtx,
+ SSL.SSL_CVERIFY_NONE, 10);
} else {
- SSLContext.setCACertificate(sslCtx,
- "/etc/ssl/certs/ca-certificates.crt",
+ SSLContext.setCACertificate(sslCtx,
+ "/etc/ssl/certs/ca-certificates.crt",
"/etc/ssl/certs");
- SSLContext.setVerify(sslCtx,
+ SSLContext.setVerify(sslCtx,
SSL.SSL_CVERIFY_REQUIRE, 10);
}
-
+
if (spdyNPN != null) {
SSLExt.setNPN(sslCtx, spdyNPN, spdyNPN.length);
}
@@ -685,17 +685,17 @@ public class AprSocketContext {
} catch (Exception e) {
throw new IOException(e);
}
-
- long mode =
+
+ long mode =
SSLExt.sslCtxSetMode(sslCtx, SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
SSLExt.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
-
+
// TODO: try release buffers
- }
+ }
}
return sslCtx;
}
-
+
void findPollerAndAdd(AprSocket ch) throws IOException {
if (ch.poller != null) {
ch.poller.requestUpdate(ch);
@@ -703,7 +703,7 @@ public class AprSocketContext {
}
assignPoller(ch);
}
-
+
void assignPoller(AprSocket ch) throws IOException {
AprPoller target = null;
synchronized (pollers) {
@@ -725,9 +725,9 @@ public class AprSocketContext {
}
if (target != null && target.add(ch)) {
return;
- }
-
- // can't be added - add a new poller
+ }
+
+ // can't be added - add a new poller
synchronized (pollers) {
AprPoller poller = allocatePoller();
poller.add(ch);
@@ -740,7 +740,7 @@ public class AprSocketContext {
* after handshake.
*/
protected void onSocket(AprSocket s) throws IOException {
-
+
}
class AcceptorThread extends Thread {
@@ -751,12 +751,12 @@ public class AprSocketContext {
final String addressStr = null;
long inetAddress;
-
+
AcceptorThread(int port) {
this.port = port;
setDaemon(true);
}
-
+
void prepare() throws IOException {
try {
// Create the pool for the server socket
@@ -779,13 +779,13 @@ public class AprSocketContext {
// Bind the server socket
int ret = Socket.bind(serverSock, inetAddress);
if (ret != 0) {
- throw new IOException("Socket.bind " + ret + " " +
+ throw new IOException("Socket.bind " + ret + " " +
Error.strerror(ret) + " port=" + port);
}
// Start listening on the server socket
ret = Socket.listen(serverSock, backlog );
if (ret != 0) {
- throw new IOException("endpoint.init.listen"
+ throw new IOException("endpoint.init.listen"
+ ret + " " + Error.strerror(ret));
}
if (OS.IS_WIN32 || OS.IS_WIN64) {
@@ -810,7 +810,7 @@ public class AprSocketContext {
throw new IOException(t);
}
}
-
+
void unblock() {
try {
// Easiest ( maybe safest ) way to interrupt accept
@@ -821,7 +821,7 @@ public class AprSocketContext {
// ignore - the acceptor may have shut down by itself.
}
}
-
+
@Override
public void run() {
while (running) {
@@ -829,7 +829,7 @@ public class AprSocketContext {
// each socket has a pool.
final AprSocket ch = newSocket(AprSocketContext.this);
ch.setStatus(AprSocket.ACCEPTED);
-
+
ch.socket = Socket.accept(serverSock);
if (!running) {
break;
@@ -838,7 +838,7 @@ public class AprSocketContext {
if (connectionsCount.get() % 1000 == 0) {
System.err.println("Accepted: " + connectionsCount.get());
}
-
+
if (nonBlockingAccept && !sslMode) {
ch.setStatus(AprSocket.CONNECTED);
// TODO: SSL really needs a thread.
@@ -855,11 +855,11 @@ public class AprSocketContext {
}
class AcceptorDispatchThread extends Thread {
-
+
AcceptorDispatchThread(int port) {
setDaemon(true);
}
-
+
public void run() {
while(running) {
try {
@@ -873,17 +873,17 @@ public class AprSocketContext {
}
}
}
-
+
/**
* Create the poller. With some versions of APR, the maximum poller size will
* be 62 (recompiling APR is necessary to remove this limitation).
- * @throws IOException
+ * @throws IOException
*/
AprPoller allocatePoller() throws IOException {
long pool = Pool.create(getRootPool());
int size = maxConnections / pollerThreadCount;
int timeout = keepAliveTimeout;
-
+
long serverPollset = allocatePoller(size, pool, timeout);
if (serverPollset == 0 && size > 1024) {
@@ -896,7 +896,7 @@ public class AprSocketContext {
size = 62;
serverPollset = allocatePoller(size, pool, timeout);
}
-
+
AprPoller res = new AprPoller();
res.pool = pool;
res.serverPollset = serverPollset;
@@ -912,11 +912,11 @@ public class AprSocketContext {
}
return res;
}
-
+
// Removed the 'thread safe' updates for now, to simplify the code
// last test shows a small improvement, can switch later.
static boolean sizeLogged = false;
-
+
protected long allocatePoller(int size, long pool, int timeout) {
int flag = threadSafe ? Poll.APR_POLLSET_THREADSAFE: 0;
for (int i = 0; i < 2; i++) {
@@ -943,7 +943,7 @@ public class AprSocketContext {
log.severe("Unexpected ENOTIMPL with flag==0");
return 0;
}
-
+
class AprPoller extends Thread {
public int id;
@@ -960,16 +960,16 @@ public class AprSocketContext {
// Should be replaced with socket data.
// used only to lookup by socket
Map<Long, AprSocket> channels = new HashMap<Long, AprSocket>();
-
+
// Active + pending, must be < desc.length / 2
// The channel will also have poller=this when active or pending
// How many sockets have poller == this
protected AtomicInteger keepAliveCount = new AtomicInteger();
// Tracks desc, how many sockets are actively polled
protected AtomicInteger polledCount = new AtomicInteger();
-
+
protected AtomicInteger pollCount = new AtomicInteger();
-
+
private List<AprSocket> updates = new ArrayList<AprSocket>();
public void run() {
@@ -983,17 +983,17 @@ public class AprSocketContext {
while (running) {
try {
updates();
-
-
+
+
lastCallbackTime = t0 - lastPoll;
-
+
// Pool for the specified interval. Remove signaled sockets
synchronized (this) {
inPoll.set(true);
}
// if updates are added after updates and poll - interrupt will have still
// work
-
+
int rv = Poll.poll(serverPollset, pollTime, desc, true);
synchronized (this) {
inPoll.set(false);
@@ -1001,14 +1001,14 @@ public class AprSocketContext {
break;
}
}
-
- pollCount.incrementAndGet();
+
+ pollCount.incrementAndGet();
lastPoll = System.currentTimeMillis();
lastPollTime = lastPoll - t0;
-
+
if (rv > 0) {
if (debugPoll) {
- log.info(" Poll() id=" + id + " rv=" + rv + " keepAliveCount=" + keepAliveCount +
+ log.info(" Poll() id=" + id + " rv=" + rv + " keepAliveCount=" + keepAliveCount +
" polled = " + polledCount.get()
+ " time=" + lastPollTime);
}
@@ -1017,7 +1017,7 @@ public class AprSocketContext {
long sock = desc[pollIdx * 2 + 1];
AprSocket ch;
boolean blocking = false;
-
+
synchronized (channels) {
ch = channels.get(sock);
if (ch != null) {
@@ -1030,42 +1030,42 @@ public class AprSocketContext {
}
// was removed from polling
ch.clearStatus(AprSocket.POLL);
-
+
// We just removed it ( see last param to poll()).
// Check for failed sockets and hand this socket off to a worker
long mask = desc[pollIdx * 2];
-
+
boolean hup = ((mask & Poll.APR_POLLHUP) == Poll.APR_POLLHUP);
boolean err = ((mask & Poll.APR_POLLERR) == Poll.APR_POLLERR);
boolean nval = ((mask & Poll.APR_POLLNVAL) != 0);
if (err || nval) {
System.err.println("ERR " + err + " NVAL " + nval);
}
-
+
boolean out = (mask & Poll.APR_POLLOUT) == Poll.APR_POLLOUT;
boolean in = (mask & Poll.APR_POLLIN) == Poll.APR_POLLIN;
if (debugPoll) {
- log.info(" Poll channel: " + Long.toHexString(mask) +
+ log.info(" Poll channel: " + Long.toHexString(mask) +
(out ? " OUT" :"") +
(in ? " IN": "") +
(err ? " ERR" : "") +
" Ch: " + ch);
}
-
+
// will be set again in process(), if all read/write is done
ch.clearStatus(AprSocket.POLLOUT);
ch.clearStatus(AprSocket.POLLIN);
-
+
// try to send if needed
if (blocking) {
synchronized (ch) {
- ch.notifyAll();
+ ch.notifyAll();
}
getExecutor().execute(ch);
} else {
((AprSocketContext.NonBlockingPollHandler) ch.handler).process(ch, in, out, false);
-
- // Update polling for the channel (in IO thread, safe)
+
+ // Update polling for the channel (in IO thread, safe)
updateIOThread(ch);
}
}
@@ -1074,7 +1074,7 @@ public class AprSocketContext {
if (errn == Status.TIMEUP) {
// to or interrupt
// if (debugPoll) {
-// log.info(" Poll() timeup" + " keepAliveCount=" + keepAliveCount +
+// log.info(" Poll() timeup" + " keepAliveCount=" + keepAliveCount +
// " polled = " + polledCount.get()
// + " time=" + lastPollTime);
// }
@@ -1082,7 +1082,7 @@ public class AprSocketContext {
// interrupt - no need to log
} else {
if (debugPoll) {
- log.info(" Poll() rv=" + rv + " keepAliveCount=" + keepAliveCount +
+ log.info(" Poll() rv=" + rv + " keepAliveCount=" + keepAliveCount +
" polled = " + polledCount.get()
+ " time=" + lastPollTime);
}
@@ -1096,13 +1096,13 @@ public class AprSocketContext {
destroyPoller(); // will close all sockets
}
continue;
- }
+ }
}
// TODO: timeouts
} catch (Throwable t) {
log.log(Level.SEVERE, "endpoint.poll.error", t);
}
-
+
}
if (!running) {
destroyPoller();
@@ -1116,9 +1116,9 @@ public class AprSocketContext {
synchronized (pollers) {
pollers.remove(this);
}
- log.info("Poller stopped after cnt=" +
- pollCount.get() +
- " sockets=" + channels.size() +
+ log.info("Poller stopped after cnt=" +
+ pollCount.get() +
+ " sockets=" + channels.size() +
" lastPoll=" + lastPoll);
// Close all sockets
@@ -1146,9 +1146,9 @@ public class AprSocketContext {
}
}
- /**
+ /**
* Called only in poller thread, only used if not thread safe
- * @throws IOException
+ * @throws IOException
*/
protected void updates() throws IOException {
synchronized (this) {
@@ -1158,7 +1158,7 @@ public class AprSocketContext {
updates.clear();
}
}
-
+
void interruptPoll() {
try {
int rc = Status.APR_SUCCESS;
@@ -1180,17 +1180,17 @@ public class AprSocketContext {
}
}
-
+
int remaining() {
synchronized (channels) {
return (desc.length - channels.size() * 2);
- }
+ }
}
-
-
- /**
- * Called from any thread, return true if we could add it
+
+
+ /**
+ * Called from any thread, return true if we could add it
* to pending.
*/
boolean add(AprSocket ch) throws IOException {
@@ -1223,7 +1223,7 @@ public class AprSocketContext {
updateIOThread(ch);
} else {
synchronized (this) {
- updates.add(ch);
+ updates.add(ch);
interruptPoll();
}
if (debugPoll) {
@@ -1240,7 +1240,7 @@ public class AprSocketContext {
// poll.
//synchronized (ch)
boolean polling = ch.checkPreConnect(AprSocket.POLL);
-
+
int requested = ch.requestedPolling();
if (requested == 0) {
if (polling) {
@@ -1252,7 +1252,7 @@ public class AprSocketContext {
channels.remove(ch.socket);
}
keepAliveCount.decrementAndGet();
- ch.reset();
+ ch.reset();
}
} else {
if (polling) {
@@ -1262,12 +1262,12 @@ public class AprSocketContext {
pollAdd(ch, requested);
}
if (debugPoll) {
- log.info("Poll: updated=" + id + " " + ch);
+ log.info("Poll: updated=" + id + " " + ch);
}
}
-
- /**
- * Called only from IO thread
+
+ /**
+ * Called only from IO thread
*/
private void pollAdd(AprSocket up, int req) throws IOException {
boolean failed = false;
@@ -1286,11 +1286,11 @@ public class AprSocketContext {
}
if (failed) {
up.reset();
- throw new IOException("poll add error " + rv + " " + up + " " + Error.strerror((int)rv));
+ throw new IOException("poll add error " + rv + " " + up + " " + Error.strerror((int)rv));
}
}
- /**
+ /**
* Called only from IO thread. Remove from Poll and channels,
* set POLL bit to false.
*/
@@ -1301,64 +1301,64 @@ public class AprSocketContext {
rv = Poll.remove(serverPollset, up.socket);
}
up.clearStatus(AprSocket.POLL);
-
+
if (rv != Status.APR_SUCCESS) {
log.severe("poll remove error " + Error.strerror((int)rv) + " " + up);
} else {
polledCount.decrementAndGet();
}
}
-
-
+
+
public boolean isPollerThread() {
return Thread.currentThread() == this;
}
-
+
}
-
+
/**
* Callback for poll events, will be invoked in a thread pool.
- *
+ *
*/
public static interface BlockingPollHandler {
-
+
/**
* Called when the socket has been polled for in, out or closed.
- *
- *
+ *
+ *
*/
public void process(AprSocket ch, boolean in, boolean out, boolean close);
-
-
+
+
/**
- * Called just before the socket is destroyed
+ * Called just before the socket is destroyed
*/
public void closed(AprSocket ch);
}
-
+
/**
- * Additional callbacks for non-blocking.
- * This can be much faster - but it's harder to code, should be used only
- * for low-level protocol implementation, proxies, etc.
- *
+ * Additional callbacks for non-blocking.
+ * This can be much faster - but it's harder to code, should be used only
+ * for low-level protocol implementation, proxies, etc.
+ *
* The model is restricted in many ways to avoid complexity and bugs:
- *
+ *
* - read can only happen in the IO thread associated with the poller
* - user doesn't control poll interest - it is set automatically based
* on read/write results
* - it is only possible to suspend read, for TCP flow control - also
* only from the IO thread. Resume can happen from any thread.
- * - it is also possible to call write() from any thread
+ * - it is also possible to call write() from any thread
*/
public static interface NonBlockingPollHandler extends BlockingPollHandler {
-
- /**
+
+ /**
* Called after connection is established, in a thread pool.
* Process will be called next.
*/
public void connected(AprSocket ch);
-
- /**
+
+ /**
* Before close, if an exception happens.
*/
public void error(AprSocket ch, Throwable t);
Modified: tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java Tue Mar 13 12:41:57 2012
@@ -19,27 +19,29 @@ package org.apache.tomcat.jni.socket;
import java.io.Serializable;
/**
- * Information about the remote host. Persisting this in memcache or similar
+ * Information about the remote host. Persisting this in memcache or similar
* storage can improve performance on future TLS connections by skipping roundtrips
* and reducing CPU use in handshake.
- *
+ *
* This class is used in both server and client mode.
- *
+ *
* AprSocketContextLitener.getPeer(name) can be used to read from an external storage.
- *
+ *
* TODO: also save the SPDY persistent settings here.
* TODO: fix tickets, don't seem to work anymore.
*/
public class HostInfo implements Serializable {
-
+
+ private static final long serialVersionUID = 1L;
+
public String host;
-
+
public int port;
-
+
public boolean secure;
-
+
/**
- * Raw cert data (x.509 format).
+ * Raw cert data (x.509 format).
* This is retrieved when a full handshake happens - if session reuse or tickets
* are used you'll not receive the certs again.
*/
@@ -47,7 +49,7 @@ public class HostInfo implements Seriali
public byte[] ticket;
public int ticketLen;
-
+
public String sessionId;
/**
@@ -60,7 +62,7 @@ public class HostInfo implements Seriali
*/
byte[] npn;
int npnLen;
-
+
public HostInfo() {
}
@@ -69,15 +71,14 @@ public class HostInfo implements Seriali
this.port = port;
this.secure = secure;
}
-
+
public String getNpn() {
- return new String(npn, 0, npnLen);
+ return new String(npn, 0, npnLen);
}
public void setNpn(String npn) {
if (npn == null) {
npnLen = 0;
- npn = null;
}
}
}
\ No newline at end of file
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java Tue Mar 13 12:41:57 2012
@@ -146,20 +146,20 @@ public abstract class SpdyConnection { /
this.spdyContext = spdyContext;
outCondition = framerLock.newCondition();
}
-
+
public String toString() {
return "SpdyCon open=" + channels.size();
}
-
+
public void dump(PrintWriter out) {
- out.println("SpdyConnection open=" + channels.size() +
+ out.println("SpdyConnection open=" + channels.size() +
" outQ:" + outQueue.size());
for (SpdyStream str: channels.values()) {
str.dump(out);
}
-
+
out.println();
-
+
}
/**
@@ -215,7 +215,7 @@ public abstract class SpdyConnection { /
draining = false;
}
}
-
+
/**
* Non blocking if the socket is not blocking.
*/
@@ -233,7 +233,7 @@ public abstract class SpdyConnection { /
return false;
}
if (goAway < out.streamId) {
-
+
}
SpdyFrame oframe = out;
try {
@@ -297,7 +297,7 @@ public abstract class SpdyConnection { /
out.off += wr;
toWrite -= wr;
}
- }
+ }
// Frame was sent
framerLock.lock();
try {
@@ -305,9 +305,9 @@ public abstract class SpdyConnection { /
} finally {
framerLock.unlock();
}
-
+
synchronized (channels) {
- if (out.stream != null &&
+ if (out.stream != null &&
out.stream.finRcvd && out.stream.finSent) {
channels.remove(out.streamId);
}
@@ -354,7 +354,7 @@ public abstract class SpdyConnection { /
// We can't assing a stream ID until it is sent - priorities
// we can't compress either - it's stateful.
oframe.stream = proc;
-
+
framerLock.lock();
try {
outQueue.add(oframe);
@@ -448,7 +448,7 @@ public abstract class SpdyConnection { /
}
// TODO: if data, split it in 2 frames
- // grow the buffer if needed.
+ // grow the buffer if needed.
if (inFrame.data.length < inFrame.endData) {
byte[] tmp = new byte[inFrame.endData];
System.arraycopy(inFrame.data, 0, tmp, 0, inFrame.endReadData);
@@ -557,7 +557,7 @@ public abstract class SpdyConnection { /
/**
* Process a SPDY connection. Called in a separate thread.
- *
+ *
* @return
* @throws IOException
*/
@@ -577,7 +577,7 @@ public abstract class SpdyConnection { /
case TYPE_GOAWAY: {
int lastStream = inFrame.readInt();
log.info("GOAWAY last=" + lastStream);
-
+
// Server will shut down - but will keep processing the current requests,
// up to lastStream. If we sent any new ones - they need to be canceled.
abort("GO_AWAY", lastStream);
@@ -601,7 +601,7 @@ public abstract class SpdyConnection { /
return CLOSE;
}
sch.onCtlFrame(inFrame);
-
+
synchronized(channels) {
channels.remove(inFrame.streamId);
}
@@ -663,7 +663,7 @@ public abstract class SpdyConnection { /
// Data frame
SpdyStream sch;
synchronized (channels) {
- sch = channels.get(inFrame.streamId);
+ sch = channels.get(inFrame.streamId);
}
if (sch == null) {
abort("Missing channel");
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java Tue Mar 13 12:41:57 2012
@@ -66,18 +66,18 @@ public class SpdyContext {
/**
* Set the max frame size.
- *
+ *
* Larger data packets will be split in multiple frames.
- *
- * ( the code is currently accepting larger control frames - it's not
+ *
+ * ( the code is currently accepting larger control frames - it's not
* clear if we should just reject them, many servers limit header size -
* the http connector also has a 8k limit - getMaxHttpHeaderSize )
*/
- public void setFrameSize(int frameSize) {
+ public void setFrameSize(int frameSize) {
defaultFrameSize = frameSize;
}
-
- /**
+
+ /**
* Override for server side to return a custom stream.
*/
public SpdyStream getStream(SpdyConnection framer) {
@@ -120,11 +120,11 @@ public class SpdyContext {
public void releaseConnection(SpdyConnection con) {
}
-
+
public void listen(final int port, String cert, String key) throws IOException {
throw new IOException("Not implemented");
- }
-
+ }
+
/**
* Close all pending connections and free resources.
*/
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java Tue Mar 13 12:41:57 2012
@@ -1,4 +1,18 @@
/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
*/
package org.apache.tomcat.spdy;
@@ -12,9 +26,9 @@ import org.apache.tomcat.jni.socket.AprS
public class SpdyContextJni extends SpdyContext {
AprSocketContext con;
-
+
//AprSocketContext socketCtx;
-
+
public SpdyContextJni() {
con = new AprSocketContext();
//if (insecureCerts) {
@@ -26,11 +40,11 @@ public class SpdyContextJni extends Spdy
//}
con.setNpn("spdy/2");
}
-
+
@Override
public SpdyConnection getConnection(String host, int port) throws IOException {
SpdyConnectionAprSocket spdy = new SpdyConnectionAprSocket(this);
-
+
AprSocket ch = con.socket(host, port, tls);
spdy.setSocket(ch);
@@ -38,7 +52,7 @@ public class SpdyContextJni extends Spdy
ch.connect();
ch.setHandler(new SpdySocketHandler(spdy));
-
+
// need to consume the input to receive more read events
int rc = spdy.processInput();
if (rc == SpdyConnection.CLOSE) {
@@ -48,50 +62,50 @@ public class SpdyContextJni extends Spdy
return spdy;
}
-
+
public void onAccept(long socket) throws IOException {
SpdyConnectionAprSocket spdy = new SpdyConnectionAprSocket(SpdyContextJni.this);
AprSocket s = con.socket(socket);
spdy.setSocket(s);
-
+
SpdySocketHandler handler = new SpdySocketHandler(spdy);
- s.setHandler(handler);
+ s.setHandler(handler);
handler.process(s, true, true, false);
}
-
+
public void listen(final int port, String cert, String key) throws IOException {
con = new AprSocketContext() {
protected void onSocket(AprSocket s) throws IOException {
SpdyConnectionAprSocket spdy = new SpdyConnectionAprSocket(SpdyContextJni.this);
spdy.setSocket(s);
-
+
SpdySocketHandler handler = new SpdySocketHandler(spdy);
s.setHandler(handler);
}
};
-
+
con.setNpn(SpdyContext.SPDY_NPN_OUT);
con.setKeys(cert, key);
-
+
con.listen(port);
}
public void stop() throws IOException {
con.stop();
}
-
+
public AprSocketContext getAprContext() {
return con;
- }
-
+ }
+
// NB
class SpdySocketHandler implements NonBlockingPollHandler {
SpdyConnection con;
-
+
SpdySocketHandler(SpdyConnection con) {
this.con = con;
}
-
+
@Override
public void closed(AprSocket ch) {
// not used ( polling not implemented yet )
@@ -119,9 +133,9 @@ public class SpdyContextJni extends Spdy
@Override
public void error(AprSocket ch, Throwable t) {
}
-
+
}
-
+
public static class SpdyConnectionAprSocket extends SpdyConnection {
AprSocket socket;
@@ -141,7 +155,7 @@ public class SpdyContextJni extends Spdy
public void close() throws IOException {
socket.close();
}
-
+
@Override
public int write(byte[] data, int off, int len) throws IOException {
if (socket == null) {
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java Tue Mar 13 12:41:57 2012
@@ -20,7 +20,6 @@ import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
-import java.util.concurrent.Semaphore;
/**
* Spdy context for 'proxy' or test mode spdy - no NPN, no SSL, no compression.
@@ -99,20 +98,22 @@ public class SpdyContextProxy extends Sp
}
}
}
-
-
+
+
boolean running = true;
ServerSocket serverSocket;
-
+
+ @Override
public void stop() throws IOException {
running = false;
serverSocket.close();
}
-
+
/**
* For small servers/testing: run in server mode.
* Need to override onSynStream() to implement the logic.
*/
+ @Override
public void listen(final int port, String cert, String key) throws IOException {
getExecutor().execute(new Runnable() {
@Override
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java Tue Mar 13 12:41:57 2012
@@ -26,8 +26,8 @@ public class SpdyFrame {
public static byte[] HTTP11 = "HTTP/1.1".getBytes();
public static byte[] OK200 = "200 OK".getBytes();
-
-
+
+
// This is a bit more complicated, to avoid multiple reads/writes.
// We'll read as much as possible - possible past frame end. This may
// cost an extra copy - or even more complexity for dealing with slices
@@ -43,8 +43,8 @@ public class SpdyFrame {
/**
* end of data in the buffer.
*/
- public int endData;
-
+ public int endData;
+
// Processed data from the frame
boolean c; // for control
@@ -240,7 +240,7 @@ public class SpdyFrame {
nvCount++;
headerValue(buf, soff, len);
}
-
+
public void addHeader(String name, String value) {
byte[] nameB = name.getBytes();
headerName(nameB, 0, nameB.length);
@@ -258,7 +258,7 @@ public class SpdyFrame {
headerName(nameB, 0, nameB.length);
headerValue(valueB, 0, valueB.length);
}
-
+
public void getHeaders(Map<String, String> resHeaders) {
for (int i = 0; i < nvCount; i++) {
int len = read16();
@@ -270,7 +270,7 @@ public class SpdyFrame {
resHeaders.put(n, v);
}
}
-
+
// TODO: instead of that, use byte[][]
void makeSpace(int len) {
Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java?rev=1300102&r1=1300101&r2=1300102&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java Tue Mar 13 12:41:57 2012
@@ -54,18 +54,18 @@ public class SpdyStream {
protected boolean finSent;
protected boolean finRcvd;
-
+
/**
* Dummy data frame to insert on reset / go away
*/
static SpdyFrame END_FRAME;
-
+
static {
END_FRAME = new SpdyFrame(16);
END_FRAME.endData = 0;
END_FRAME.off = 0;
- END_FRAME.c = false;
- END_FRAME.flags =SpdyConnection.FLAG_HALF_CLOSE;
+ END_FRAME.c = false;
+ END_FRAME.flags =SpdyConnection.FLAG_HALF_CLOSE;
}
public SpdyStream(SpdyConnection spdy) {
@@ -117,30 +117,30 @@ public class SpdyStream {
inData.add(frame);
if (frame.isHalfClose()) {
finRcvd = true;
- }
+ }
}
}
- /**
+ /**
* Called on GOAWAY or reset.
*/
public void onReset() {
finRcvd = true;
finSent = true;
-
+
// To unblock
inData.add(END_FRAME);
}
-
+
/**
* True if the channel both received and sent FIN frames.
- *
+ *
* This is tracked by the processor, to avoid extra storage in framer.
*/
public boolean isFinished() {
return finSent && finRcvd;
}
-
+
/**
* Waits and return the next data frame.
*/
@@ -152,7 +152,7 @@ public class SpdyStream {
}
}
}
-
+
/**
* Waits and return the next frame. First frame will be the control frame
*/
@@ -162,7 +162,7 @@ public class SpdyStream {
synchronized (this) {
if (inData.size() == 0 && finRcvd) {
return null;
- }
+ }
}
in = inData.poll(to, TimeUnit.MILLISECONDS);
if (in == END_FRAME) {
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org
Re: svn commit: r1300102 - in /tomcat/trunk/java/org/apache:
coyote/spdy/ tomcat/jni/ tomcat/jni/socket/ tomcat/spdy/
Posted by Costin Manolache <co...@gmail.com>.
Thanks - what do you use for edit, I have Eclipse with few custom settings
for style
( quite old ). Sorry about spaces / etc -
On Tue, Mar 13, 2012 at 5:41 AM, <ma...@apache.org> wrote:
> Author: markt
> Date: Tue Mar 13 12:41:57 2012
> New Revision: 1300102
>
> URL: http://svn.apache.org/viewvc?rev=1300102&view=rev
> Log:
> Code clean-up:
> - one missing license header
> - lots of trailing whitespace
> - some unused imports
> - an unnecessary cast
> - some unnecessary code
>
> Still need to fix the import checks
>
> Modified:
> tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java
> tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java
> tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java
> tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
> tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java
> tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java
>
> Modified: tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java
> (original)
> +++ tomcat/trunk/java/org/apache/coyote/spdy/SpdyAprNpnHandler.java Tue
> Mar 13 12:41:57 2012
> @@ -17,18 +17,12 @@
> package org.apache.coyote.spdy;
>
> import java.io.IOException;
> -import java.util.HashMap;
> -import java.util.Map;
>
> import org.apache.coyote.Adapter;
> import org.apache.coyote.http11.Http11AprProtocol;
> import org.apache.juli.logging.Log;
> import org.apache.juli.logging.LogFactory;
> -import org.apache.tomcat.jni.Error;
> import org.apache.tomcat.jni.SSLExt;
> -import org.apache.tomcat.jni.Status;
> -import org.apache.tomcat.jni.socket.AprSocketContext;
> -import org.apache.tomcat.spdy.CompressDeflater6;
> import org.apache.tomcat.spdy.SpdyConnection;
> import org.apache.tomcat.spdy.SpdyContext;
> import org.apache.tomcat.spdy.SpdyContextJni;
> @@ -113,7 +107,7 @@ public class SpdyAprNpnHandler implement
> Http11AprProtocol proto, AbstractEndpoint endpoint) {
>
> SocketWrapper<Long> socketW = socketO;
> - long socket = ((Long) socketW.getSocket()).longValue();
> + long socket = socketW.getSocket().longValue();
>
> try {
> spdyContext.onAccept(socket);
> @@ -125,6 +119,4 @@ public class SpdyAprNpnHandler implement
>
> public void onClose(SocketWrapper<Long> socketWrapper) {
> }
> -
> -
> }
>
> Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/jni/SSLExt.java Tue Mar 13
> 12:41:57 2012
> @@ -92,9 +92,9 @@ public final class SSLExt {
> * Return the last openssl error
> */
> public static native String sslErrReasonErrorString();
> -
> +
> public static native long sslCtxSetMode(long ctx, long mode);
> -
> +
> /* Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report
> success
> * when just a single record has been written): */
> public static final int SSL_MODE_ENABLE_PARTIAL_WRITE = 0x1;
>
> Modified: tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java
> (original)
> +++ tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocket.java Tue Mar
> 13 12:41:57 2012
> @@ -37,21 +37,21 @@ import org.apache.tomcat.jni.socket.AprS
> import org.apache.tomcat.jni.socket.AprSocketContext.BlockingPollHandler;
>
> /**
> - * Native socket, using JNI + APR + openssl.
> - *
> + * Native socket, using JNI + APR + openssl.
> + *
> * The socket is non-blocking - you can register either a blocking or non
> * blocking callback.
> - *
> - * There is no explicit method to register/unregister poll interest -
> + *
> + * There is no explicit method to register/unregister poll interest -
> * it is done automatically, when read/write methods return 0.
> - *
> + *
> * To keep the socket polling you must read all the available data, until
> * read() returns 0. If you want to pause - don't read all input. To
> resume -
> * read again until it returns 0.
> - *
> - * Same for write - when write() returns 0 the socket is registered for
> - * write interest.
> - *
> + *
> + * Same for write - when write() returns 0 the socket is registered for
> + * write interest.
> + *
> * You can also use the blocking read/write methods.
> */
> public class AprSocket implements Runnable {
> @@ -62,13 +62,13 @@ public class AprSocket implements Runnab
>
> static int CONNECTING = 1;
> static int CONNECTED = 0x2;
> -
> +
> // Current ( real ) poll status
> static int POLLIN_ACTIVE = 0x4;
> static int POLLOUT_ACTIVE = 0x8;
> -
> +
> static int POLL = 0x10;
> -
> +
> static int SSL_ATTACHED = 0x40;
>
> // Requested poll status. Set by read/write when needed.
> @@ -89,19 +89,19 @@ public class AprSocket implements Runnab
> // only one - to save per/socket memory - context has similar
> callbacks.
> BlockingPollHandler handler;
>
> - // Set while it's associated with a poller - it'll stay associated
> after
> + // Set while it's associated with a poller - it'll stay associated
> after
> // connect until close. Destroy will happen in the poller.
> // POLL bit indicates if the socket is actually polling.
> AprPoller poller;
> -
> - // Bit field indicating the status and socket should only be accessed
> with
> +
> + // Bit field indicating the status and socket should only be accessed
> with
> // socketLock protection
> private int status;
> -
> +
> long socket;
>
> //long to = 10000;
> -
> +
> // Persistent info about the peer ( SSL, etc )
> private HostInfo hostInfo;
>
> @@ -118,14 +118,14 @@ public class AprSocket implements Runnab
> }
>
> public String toString() {
> - return (context.isServer() ? "AprSrv-" : "AprCli-") +
> + return (context.isServer() ? "AprSrv-" : "AprCli-") +
> Long.toHexString(socket) + " " +
> Integer.toHexString(status);
> }
>
> public void setHandler(BlockingPollHandler l) {
> handler = l;
> }
> -
> +
> private void setNonBlocking() {
> if (socket != 0 && context.running) {
> Socket.optSet(socket, Socket.APR_SO_NONBLOCK, 1);
> @@ -145,7 +145,7 @@ public class AprSocket implements Runnab
> public BlockingPollHandler getHandler() {
> return handler;
> }
> -
> +
> public AprSocketContext getContext() {
> return context;
> }
> @@ -154,7 +154,7 @@ public class AprSocket implements Runnab
> hostInfo = hi;
> return this;
> }
> -
> +
> /**
> */
> public void connect() throws IOException {
> @@ -184,21 +184,21 @@ public class AprSocket implements Runnab
>
> setStatus(CONNECTED);
> clearStatus(CONNECTING);
> -
> +
> notifyConnected(false);
> }
> -
> +
> public HostInfo getHost() {
> return hostInfo;
> }
>
> /**
> - * Write.
> - *
> - * For both blocking and non-blocking, it'll return the number of
> bytes
> + * Write.
> + *
> + * For both blocking and non-blocking, it'll return the number of
> bytes
> * written - it'll attempt to send as much as possible, but if the
> buffers
> - * are full it'll return 0.
> - *
> + * are full it'll return 0.
> + *
> * @param data
> * @param off
> * @param len
> @@ -213,7 +213,7 @@ public class AprSocket implements Runnab
> if (rc < 0) {
> throw new IOException("Write error " + rc);
> } else if (rc == 0) {
> - // need poll out - do we need to update polling ?
> + // need poll out - do we need to update polling ?
> context.findPollerAndAdd(this);
> } else {
> return rc;
> @@ -237,20 +237,20 @@ public class AprSocket implements Runnab
> if (rc < 0) {
> throw new IOException("Write error " + rc);
> } else if (rc == 0) {
> - // need poll out - do we need to update polling ?
> + // need poll out - do we need to update polling ?
> synchronized (this) {
> context.findPollerAndAdd(this);
> }
> }
> return rc;
> }
> -
> +
> private int writeInternal(byte[] data, int off, int len) throws
> IOException {
> int rt = 0;
> int sent = 0;
> synchronized(this) {
> - if ((status & CLOSED) != 0
> - || socket == 0
> + if ((status & CLOSED) != 0
> + || socket == 0
> || !context.running) {
> throw new IOException("Closed");
> }
> @@ -258,7 +258,7 @@ public class AprSocket implements Runnab
> throw new IOException("Write from 2 threads not allowed");
> }
> status |= WRITING;
> -
> +
> while (len > 0) {
> sent = Socket.send(socket, data, off, len);
> if (sent <= 0) {
> @@ -318,12 +318,12 @@ public class AprSocket implements Runnab
> if (context.rawDataHandler != null) {
> context.rawData(this, true, data, off, read, len, false);
> }
> -
> +
> if (read > 0) {
> return read;
> }
>
> - if (read == 0 || read == -Status.TIMEUP || read ==
> -Status.ETIMEDOUT
> + if (read == 0 || read == -Status.TIMEUP || read ==
> -Status.ETIMEDOUT
> || read == -Status.EAGAIN) {
> read = 0;
> setStatus(POLLIN);
> @@ -343,8 +343,8 @@ public class AprSocket implements Runnab
> public int readNB(byte[] data, int off, int len) throws IOException {
> int read;
> synchronized(this) {
> - if ((status & CLOSED) != 0
> - || socket == 0
> + if ((status & CLOSED) != 0
> + || socket == 0
> || !context.running) {
> return -1;
> }
> @@ -352,19 +352,19 @@ public class AprSocket implements Runnab
> throw new IOException("Read from 2 threads not allowed");
> }
> status |= READING;
> -
> +
> read = Socket.recv(socket, data, off, len);
> status &= ~READING;
> }
> return processReadResult(data, off, len, read);
> }
> -
> +
> /*
> No support for shutdownOutput: SSL is quite tricky.
> Use close() instead - no read/write will be allowed after.
> -
> +
> */
> -
> +
> public void close() throws IOException {
> synchronized (this) {
> if ((status & CLOSED) != 0 || socket == 0) {
> @@ -373,7 +373,7 @@ public class AprSocket implements Runnab
> status |= CLOSED;
> status &= ~POLLIN;
> status &= ~POLLOUT;
> - }
> + }
> if (context.rawDataHandler != null) {
> context.rawDataHandler.rawData(this, false, null, 0, 0, 0,
> true);
> }
> @@ -404,41 +404,41 @@ public class AprSocket implements Runnab
> if ((status & (WRITING | READING)) != 0) {
> return; // not closed
> }
> -
> +
> if (context.rawDataHandler != null) {
> context.rawDataHandler.rawData(this, false, null, -1, -1,
> -1, true);
> }
> if (context.debug) {
> log.info("closing: context.open=" + context.open.get() +
> " " + this);
> }
> -
> +
> context.open.decrementAndGet();
> -
> +
> if (socket != 0 && (status & CLOSED) == 0) {
> Socket.close(socket);
> status |= CLOSED;
> }
> -
> +
> if (handler != null) {
> if (isBlocking()) {
> context.getExecutor().execute(this);
> } else {
> - handler.closed(this);
> + handler.closed(this);
> }
> }
> -
> +
> context.destroySocket(this);
> }
> }
>
> -
> -
> +
> +
> /**
> * Close input and output, potentially sending RST, than close the
> socket.
> - *
> - * The proper way to close when gracefully done is by calling
> writeEnd() and
> - * reading all remaining input until -1 (EOF) is received.
> - *
> + *
> + * The proper way to close when gracefully done is by calling
> writeEnd() and
> + * reading all remaining input until -1 (EOF) is received.
> + *
> * If EOF is received, the proper way to close is send whatever is
> remaining and
> * call writeEnd();
> */
> @@ -450,7 +450,7 @@ public class AprSocket implements Runnab
> e.printStackTrace();
> }
> }
> -
> +
>
> /**
> */
> @@ -470,7 +470,7 @@ public class AprSocket implements Runnab
> } catch (Exception e) {
> throw new IOException(e);
> }
> - } else {
> + } else {
> throw new IOException("Socket is closed");
> }
> }
> @@ -631,7 +631,7 @@ public class AprSocket implements Runnab
> }
> throw new IOException("Socket closed");
> }
> -
> +
> public boolean isBlocking() {
> return ! (handler instanceof
> AprSocketContext.NonBlockingPollHandler);
> }
> @@ -643,7 +643,7 @@ public class AprSocket implements Runnab
> void notifyError(Throwable err, boolean needsThread) {
> if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
> if (err != null) {
> - ((AprSocketContext.NonBlockingPollHandler)
> handler).error(this, err);
> + ((AprSocketContext.NonBlockingPollHandler)
> handler).error(this, err);
> }
> } else {
> // poller destroyed, etc
> @@ -682,16 +682,16 @@ public class AprSocket implements Runnab
> private void notifyConnected(boolean server) throws IOException {
> // Will set the handler on the channel for accepted
> context.onSocket(this);
> -
> +
> if (handler instanceof AprSocketContext.NonBlockingPollHandler) {
> ((AprSocketContext.NonBlockingPollHandler)
> handler).connected(this);
> -
> +
> ((AprSocketContext.NonBlockingPollHandler)
> handler).process(this, true, true, false);
> - // Now register for polling - unless process() set
> suspendRead and
> + // Now register for polling - unless process() set
> suspendRead and
> // doesn't need out notifications
> updatePolling();
> } else {
> - if (server) {
> + if (server) {
> // client will block in connect().
> // Server: call process();
> notifyIO();
> @@ -726,7 +726,7 @@ public class AprSocket implements Runnab
> context.open.incrementAndGet();
>
> if (context.debug) {
> - log.info("Accept: " + context.open.get() + " " +
> this + " " +
> + log.info("Accept: " + context.open.get() + " " +
> this + " " +
> getRemotePort());
> }
> if (context.tcpNoDelay) {
> @@ -739,7 +739,7 @@ public class AprSocket implements Runnab
> blockingStartTLS();
> }
> setNonBlocking(); // call again, to set the bits (
> connect was blocking )
> -
> +
> notifyConnected(true);
> return;
> } catch (Throwable t) {
> @@ -748,7 +748,7 @@ public class AprSocket implements Runnab
> notifyError(t, false);
> return;
> }
> - }
> + }
> if (checkPreConnect(CONNECTING)) {
> // Non-blocking connect - will call 'afterConnection' at
> the end.
> try {
> @@ -756,7 +756,7 @@ public class AprSocket implements Runnab
> } catch (IOException t) {
> reset(); // also sets status ERROR
> if (handler instanceof
> AprSocketContext.NonBlockingPollHandler) {
> - ((AprSocketContext.NonBlockingPollHandler)
> handler).process(this, false, false, true);
> + ((AprSocketContext.NonBlockingPollHandler)
> handler).process(this, false, false, true);
> }
> notifyError(t, false);
> }
> @@ -776,12 +776,12 @@ public class AprSocket implements Runnab
>
> /**
> * This is a blocking call ! ( can be made non-blocking, but too
> complex )
> - *
> + *
> * Will be called automatically after connect() or accept if 'secure'
> is
> * true.
> - *
> + *
> * Can be called manually to upgrade the channel
> - * @throws IOException
> + * @throws IOException
> */
> public void blockingStartTLS() throws IOException {
> synchronized(this) {
> @@ -793,15 +793,15 @@ public class AprSocket implements Runnab
> }
> status |= SSL_ATTACHED;
> }
> -
> +
> try {
> if (context.debug) {
> log.info(this + " StartSSL");
> }
> -
> +
> AprSocketContext aprCon = (AprSocketContext) context;
> SSLSocket.attach(aprCon.getSslCtx(), socket);
> -
> +
> if (context.debugSSL) {
> SSLExt.debug(socket);
> }
> @@ -814,17 +814,17 @@ public class AprSocket implements Runnab
> hostInfo.sessDer.length);
> }
> }
> - SSLExt.sslSetMode(socket,
> SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
> + SSLExt.sslSetMode(socket,
> SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
> SSLExt.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
> -
> +
> int rc = SSLSocket.handshake(socket);
> -
> - // At this point we have the session ID, remote certs, etc
> +
> + // At this point we have the session ID, remote certs, etc
> // we can lookup host info
> if (hostInfo == null) {
> hostInfo = new HostInfo();
> }
> -
> +
> if (rc != Status.APR_SUCCESS) {
> throw new IOException(this + " Handshake failed " + rc + "
> "
> + Error.strerror(rc) + " SSLL "
> @@ -856,8 +856,8 @@ public class AprSocket implements Runnab
> }
> }
> }
> -
> - // TODO: if the ticket, session id or session changed - callback
> to
> +
> + // TODO: if the ticket, session id or session changed - callback
> to
> // save the session again
> try {
> hostInfo.sessDer = SSLExt.getSessionData(socket);
> @@ -867,13 +867,13 @@ public class AprSocket implements Runnab
> } catch (Exception e) {
> throw new IOException(e);
> }
> -
> +
> hostInfo.npn = new byte[32];
> hostInfo.npnLen = SSLExt.getNPN(socket, hostInfo.npn);
> -
> +
> // If custom verification is used - should check the certificates
> if (context.tlsCertVerifier != null) {
> - context.tlsCertVerifier.handshakeDone(this);
> + context.tlsCertVerifier.handshakeDone(this);
> }
> }
>
> @@ -883,7 +883,7 @@ public class AprSocket implements Runnab
> return 0;
> }
> // Implicit:
> - //Poll.APR_POLLNVAL | Poll.APR_POLLHUP | Poll.APR_POLLERR |
> + //Poll.APR_POLLNVAL | Poll.APR_POLLHUP | Poll.APR_POLLERR |
> int res = 0;
> if ((status & POLLIN) != 0) {
> res = Poll.APR_POLLIN;
> @@ -894,10 +894,10 @@ public class AprSocket implements Runnab
> return res;
> }
> }
> -
> +
> boolean checkBitAndSocket(int bit) {
> synchronized (this) {
> - return ((status & bit) != 0 && socket != 0 &&
> + return ((status & bit) != 0 && socket != 0 &&
> (status & CLOSED) == 0 && context.running);
> }
> }
> @@ -921,6 +921,6 @@ public class AprSocket implements Runnab
> return old != 0;
> }
> }
> -
> -
> +
> +
> }
> \ No newline at end of file
>
> Modified:
> tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
> (original)
> +++ tomcat/trunk/java/org/apache/tomcat/jni/socket/AprSocketContext.java
> Tue Mar 13 12:41:57 2012
> @@ -50,33 +50,33 @@ import org.apache.tomcat.jni.Socket;
> import org.apache.tomcat.jni.Status;
>
> public class AprSocketContext {
> - /**
> + /**
> * Called when a chunk of data is sent or received. This is very low
> - * level, used mostly for debugging or stats.
> + * level, used mostly for debugging or stats.
> */
> public static interface RawDataHandler {
> - public void rawData(AprSocket ch, boolean input, byte[] data, int
> pos,
> + public void rawData(AprSocket ch, boolean input, byte[] data, int
> pos,
> int len, int requested, boolean closed);
> }
>
> /**
> * Called in SSL mode after the handshake is completed.
> - *
> + *
> * @see AprSocketContext.customVerification()
> */
> public static interface TlsCertVerifier {
> public void handshakeDone(AprSocket ch);
> }
> -
> +
> /**
> - * Delegates loading of persistent info about a host - public certs,
> + * Delegates loading of persistent info about a host - public certs,
> * tickets, config, persistent info etc.
> */
> public static interface HostInfoLoader {
> - public HostInfo getHostInfo(String name, int port, boolean ssl);
> + public HostInfo getHostInfo(String name, int port, boolean ssl);
> }
> -
> - /**
> +
> + /**
> * Reads/writes of this size or lower are using Get/SetByteArrayRegion.
> * Larger reads use Get/ReelaseByteArrayElements.
> * Larger writes use malloc/free + GetByteArrayRagion.
> @@ -84,57 +84,57 @@ public class AprSocketContext {
> static final int TCN_BUFFER_SZ = 8192;
>
> static Logger log = Logger.getLogger("AprSocketCtx");
> -
> - // If interrupt() or thread-safe poll update are not supported - the
> - // poll updates will happen after the poll() timeout.
> - // The poll timeout with interrupt/thread safe updates can be much
> higher/
> +
> + // If interrupt() or thread-safe poll update are not supported - the
> + // poll updates will happen after the poll() timeout.
> + // The poll timeout with interrupt/thread safe updates can be much
> higher/
> static int FALLBACK_POLL_TIME = 2000;
> static int MAX_POLL_SIZE = 60;
> -
> +
> // It seems to send the ticket, get server helo / ChangeCipherSpec,
> but than
> // SSL3_GET_RECORD:decryption failed or bad record mac in s3_pkt.c:480:
> // Either bug in openssl, or some combination of ciphers - needs more
> debugging.
> // ( this can save a roundtrip and CPU on TLS handshake )
> boolean USE_TICKETS = false;
> -
> +
> boolean useFinalizer = true;
>
> final AprSocket END = new AprSocket(this);
> -
> +
> static AtomicInteger contextNumber = new AtomicInteger();
> int contextId;
> -
> +
> AtomicInteger threadNumber = new AtomicInteger();
>
> /**
> - * For now - single acceptor thread per connector.
> + * For now - single acceptor thread per connector.
> */
> AcceptorThread acceptor;
> AcceptorDispatchThread acceptorDispatch;
> -
> +
> // APR/JNI is thread safe
> boolean threadSafe = true;
> -
> - /**
> - * Pollers.
> +
> + /**
> + * Pollers.
> */
> List<AprPoller> pollers = new ArrayList<AprPoller>();
> static int pollerCnt = 0;
> -
> +
> // Set on all accepted or connected sockets.
> // TODO: add the other properties
> boolean tcpNoDelay = true;
> -
> +
> protected boolean running = true;
> -
> +
> protected boolean sslMode;
>
> // onSocket() will be called in accept thread.
> // If false: use executor ( but that may choke the acceptor thread )
> protected boolean nonBlockingAccept = false;
> -
> +
> BlockingQueue<AprSocket> acceptedQueue = new
> LinkedBlockingQueue<AprSocket>();
> -
> +
> /**
> * Root APR memory pool.
> */
> @@ -147,43 +147,43 @@ public class AprSocketContext {
>
> TlsCertVerifier tlsCertVerifier;
>
> - //
> + //
> int connectTimeout = 20000;
> int defaultTimeout = 100000;
> -
> +
> int keepAliveTimeout = 20000;
> -
> +
> AtomicInteger open = new AtomicInteger();
> -
> +
> /**
> - * Poll interval, in microseconds. If the platform doesn't support
> - * poll interrupt - it'll take this time to stop the poller.
> - *
> + * Poll interval, in microseconds. If the platform doesn't support
> + * poll interrupt - it'll take this time to stop the poller.
> + *
> */
> - protected int pollTime = 5 * 1000000;
> -
> + protected int pollTime = 5 * 1000000;
> +
> HostInfoLoader hostInfoLoader;
>
> RawDataHandler rawDataHandler = null;
> -
> +
> // TODO: do we need this here ?
> protected Map<String, HostInfo> hosts = new HashMap<String,
> HostInfo>();
>
> String[] enabledCiphers;
> -
> +
> String certFile;
> String keyFile;
> -
> +
> byte[] spdyNPN;
> -
> +
> byte[] ticketKey;
> -
> +
> // For resolving DNS ( i.e. connect ), callbacks
> private ExecutorService threadPool;
>
> // Separate executor for connect/handshakes
> ExecutorService connectExecutor;
> -
> +
> boolean debug = false;
> boolean debugSSL = false;
> boolean debugPoll = false;
> @@ -196,21 +196,21 @@ public class AprSocketContext {
>
> int sslProtocol = SSL.SSL_PROTOCOL_TLSV1 | SSL.SSL_PROTOCOL_SSLV3;
>
> - /**
> + /**
> * Max time spent in a callback ( will be longer for blocking )
> */
> AtomicLong maxHandlerTime = new AtomicLong();
> AtomicLong totalHandlerTime = new AtomicLong();
> AtomicLong handlerCount = new AtomicLong();
>
> - /**
> + /**
> * Total connections handled ( accepted or connected ).
> */
> AtomicInteger connectionsCount = new AtomicInteger();
> -
> +
>
> public AprSocketContext() {
> - connectExecutor =new ThreadPoolExecutor(0, 64, 5,
> TimeUnit.SECONDS,
> + connectExecutor =new ThreadPoolExecutor(0, 64, 5,
> TimeUnit.SECONDS,
> new LinkedBlockingQueue<Runnable>(), new
> RejectedExecutionHandler() {
> @Override
> public void rejectedExecution(Runnable r,
> @@ -222,37 +222,37 @@ public class AprSocketContext {
> });
> contextId = contextNumber.incrementAndGet();
> }
> -
> +
> /**
> * Poller thread count.
> */
> protected int pollerThreadCount = 4;
> public void setPollerThreadCount(int pollerThreadCount) {
> this.pollerThreadCount = pollerThreadCount; }
> public int getPollerThreadCount() { return pollerThreadCount; }
> -
> +
> // to test the limits - default should be lower
> int maxConnections = 64 * 1024;
> public void setMaxconnections(int maxCon) {
> this.maxConnections = maxCon;
> }
> -
> +
> public void setBacklog(int backlog) { if (backlog > 0) this.backlog =
> backlog; }
> public int getBacklog() { return backlog; }
> -
> +
> /**
> * Defer accept.
> */
> public void setDeferAccept(boolean deferAccept) { this.deferAccept =
> deferAccept; }
> public boolean getDeferAccept() { return deferAccept; }
> -
> +
> /**
> - * For client:
> - * - ClientHello will include the npn extension ( the ID == 0x3374)
> + * For client:
> + * - ClientHello will include the npn extension ( the ID == 0x3374)
> * - if ServerHello includes a list of protocols - select one
> * - send it after ChangeCipherSpec and before Finish
> - *
> + *
> * For server:
> - * - if ClientHello includes the npn extension
> + * - if ClientHello includes the npn extension
> * -- will send this string as list of supported protocols in
> ServerHello
> * - read the selection before Finish.
> * @param npn
> @@ -265,13 +265,13 @@ public class AprSocketContext {
> npnB[0] = (byte) data.length;
> npnB[npnB.length - 1] = 0;
> spdyNPN = npnB;
> -
> +
> }
> -
> +
> public void setNpn(byte[] data) {
> spdyNPN = data;
> }
> -
> +
> public void setHostLoader(HostInfoLoader handler) {
> this.hostInfoLoader = handler;
> }
> @@ -279,13 +279,13 @@ public class AprSocketContext {
> public boolean isServer() {
> return acceptor != null;
> }
> -
> +
> protected Executor getExecutor() {
> if (threadPool == null) {
> threadPool = Executors.newCachedThreadPool(new ThreadFactory(
> ) {
> @Override
> public Thread newThread(Runnable r) {
> - Thread t = new Thread(r, "AprThread-" + contextId +
> "-" +
> + Thread t = new Thread(r, "AprThread-" + contextId +
> "-" +
> threadNumber.incrementAndGet());
> t.setDaemon(true);
> return t;
> @@ -294,7 +294,7 @@ public class AprSocketContext {
> }
> return threadPool;
> }
> -
> +
> /**
> * All accepted/connected sockets will start handshake automatically.
> */
> @@ -306,7 +306,7 @@ public class AprSocketContext {
> public void setTcpNoDelay(boolean b) {
> tcpNoDelay = b;
> }
> -
> +
> public void setSslProtocol(String protocol) {
> protocol = protocol.trim();
> if ("SSLv2".equalsIgnoreCase(protocol)) {
> @@ -317,26 +317,26 @@ public class AprSocketContext {
> sslProtocol = SSL.SSL_PROTOCOL_TLSV1;
> } else if ("all".equalsIgnoreCase(protocol)) {
> sslProtocol = SSL.SSL_PROTOCOL_ALL;
> - }
> + }
> }
> -
> +
> public void setTicketKey(byte[] key48Bytes) {
> if(key48Bytes.length != 48) {
> throw new RuntimeException("Key must be 48 bytes");
> }
> this.ticketKey = key48Bytes;
> }
> -
> +
> public void customVerification(TlsCertVerifier verifier) {
> tlsCertVerifier = verifier;
> }
> -
> +
> public void setEnabledCiphers(String[] enabled) {
> enabledCiphers = enabled;
> }
>
> // TODO: should have a separate method for switching to tls later.
> - /**
> + /**
> * Set certificate, will also enable TLS mode.
> */
> public AprSocketContext setKeys(String certPemFile, String keyDerFile)
> @@ -347,14 +347,14 @@ public class AprSocketContext {
> keyFile = keyDerFile;
> return this;
> }
> -
> +
> /**
> * SSL cipher suite.
> */
> protected String SSLCipherSuite = "ALL";
> public String getSSLCipherSuite() { return SSLCipherSuite; }
> public void setSSLCipherSuite(String SSLCipherSuite) {
> this.SSLCipherSuite = SSLCipherSuite; }
> -
> +
> /**
> * Override or use hostInfoLoader to implement persistent/memcache
> storage.
> */
> @@ -373,7 +373,7 @@ public class AprSocketContext {
> return pi;
> }
>
> - protected void rawData(AprSocket ch, boolean inp, byte[] data, int
> pos,
> + protected void rawData(AprSocket ch, boolean inp, byte[] data, int
> pos,
> int len, int requested, boolean closed) {
> if (rawDataHandler != null) {
> rawDataHandler.rawData(ch, inp, data, pos, len, requested,
> closed);
> @@ -392,15 +392,15 @@ public class AprSocketContext {
> acceptorDispatch.setName("AprAcceptorDispatch-" + port);
> acceptorDispatch.start();
> }
> -
> +
> acceptor = new AcceptorThread(port);
> acceptor.prepare();
> acceptor.setName("AprAcceptor-" + port);
> acceptor.start();
> -
> -
> +
> +
> }
> -
> +
> /**
> * Get a socket for connectiong to host:port.
> */
> @@ -408,12 +408,12 @@ public class AprSocketContext {
> HostInfo hi = getHostInfo(host, port, ssl);
> return socket(hi);
> }
> -
> +
> public AprSocket socket(HostInfo hi) throws IOException {
> AprSocket sock = newSocket(this);
> sock.setHost(hi);
> return sock;
> - }
> + }
>
> public AprSocket socket(long socket) throws IOException {
> AprSocket sock = newSocket(this);
> @@ -434,7 +434,7 @@ public class AprSocketContext {
> }
> }
> }
> -
> +
> protected void connectBlocking(AprSocket apr) throws IOException {
> try {
> if (!running) {
> @@ -445,50 +445,50 @@ public class AprSocketContext {
> long clientSockP;
> synchronized (pollers) {
> long socketpool = Pool.create(getRootPool());
> -
> +
> int family = Socket.APR_INET;
>
> clientSockP = Socket.create(family,
> Socket.SOCK_STREAM,
> Socket.APR_PROTO_TCP, socketpool); // or rootPool ?
> }
> - Socket.timeoutSet(clientSockP, connectTimeout * 1000);
> + Socket.timeoutSet(clientSockP, connectTimeout * 1000);
> if (OS.IS_UNIX) {
> Socket.optSet(clientSockP, Socket.APR_SO_REUSEADDR, 1);
> }
> -
> +
> Socket.optSet(clientSockP, Socket.APR_SO_KEEPALIVE, 1);
> -
> - // Blocking
> +
> + // Blocking
> // TODO: use socket pool
> // TODO: cache it ( and TTL ) in hi
> long inetAddress = Address.info(hi.host, Socket.APR_INET,
> hi.port, 0, rootPool);
> - // this may take a long time - stop/destroy must wait
> + // this may take a long time - stop/destroy must wait
> // at least connect timeout
> int rc = Socket.connect(clientSockP, inetAddress);
> -
> +
> if (rc != 0) {
> synchronized (pollers) {
> Socket.close(clientSockP);
> - Socket.destroy(clientSockP);
> + Socket.destroy(clientSockP);
> }
> /////Pool.destroy(socketpool);
> throw new IOException("Socket.connect(): " + rc + " " +
> Error.strerror(rc) + " " + connectTimeout);
> }
> if (!running) {
> - throw new IOException("Stopped");
> + throw new IOException("Stopped");
> }
> -
> +
> connectionsCount.incrementAndGet();
> if (tcpNoDelay) {
> Socket.optSet(clientSockP, Socket.APR_TCP_NODELAY, 1);
> }
>
> - Socket.timeoutSet(clientSockP, defaultTimeout * 1000);
> -
> + Socket.timeoutSet(clientSockP, defaultTimeout * 1000);
> +
> apr.socket = clientSockP;
> -
> +
> apr.afterConnect();
> } catch (IOException e) {
> apr.reset();
> @@ -519,7 +519,7 @@ public class AprSocketContext {
> }
> }
> }
> -
> +
>
> public void stop() throws IOException {
> synchronized (pollers) {
> @@ -528,7 +528,7 @@ public class AprSocketContext {
> }
> running = false;
> }
> -
> +
> if (rootPool != 0) {
> if (acceptor != null) {
> try {
> @@ -537,7 +537,7 @@ public class AprSocketContext {
> } catch (InterruptedException e) {
> e.printStackTrace();
> }
> - }
> + }
> if (acceptorDispatch != null) {
> acceptedQueue.add(END);
> try {
> @@ -549,9 +549,9 @@ public class AprSocketContext {
> if (threadPool != null) {
> threadPool.shutdownNow();
> }
> -
> +
> log.info("Stopping pollers " + contextId);
> -
> +
> while (true) {
> AprPoller a;
> synchronized (pollers) {
> @@ -570,7 +570,7 @@ public class AprSocketContext {
> }
> }
> }
> -
> +
>
> // Called when the last poller has been destroyed.
> void destroy() {
> @@ -578,28 +578,28 @@ public class AprSocketContext {
> if (pollers.size() != 0) {
> return;
> }
> -
> +
> if (rootPool == 0) {
> return;
> }
> System.err.println("DESTROY " + rootPool);
> //Pool.destroy(rootPool);
> - //rootPool = 0;
> + //rootPool = 0;
> }
> }
> -
> +
> static IOException noApr;
> static {
> -
> +
> try {
> Library.initialize(null);
> - SSL.initialize(null);
> + SSL.initialize(null);
> } catch (Exception e) {
> noApr = new IOException("APR not present", e);
> }
> -
> +
> }
> -
> +
> private long getRootPool() throws IOException {
> if (rootPool == 0) {
> if (noApr != null) {
> @@ -618,40 +618,40 @@ public class AprSocketContext {
> }
> return rootPool;
> }
> -
> +
> long getSslCtx() throws Exception {
> if (sslCtx == 0) {
> synchronized (AprSocketContext.class) {
> -
> +
> boolean serverMode = acceptor != null;
> - sslCtx = SSLContext.make(getRootPool(),
> + sslCtx = SSLContext.make(getRootPool(),
> sslProtocol,
> serverMode ? SSL.SSL_MODE_SERVER :
> SSL.SSL_MODE_CLIENT);
>
> -
> - // SSL.SSL_OP_NO_SSLv3
> +
> + // SSL.SSL_OP_NO_SSLv3
> int opts = SSL.SSL_OP_NO_SSLv2 |
> SSL.SSL_OP_SINGLE_DH_USE;
> -
> +
> if (!USE_TICKETS || serverMode && ticketKey == null) {
> opts |= SSL.SSL_OP_NO_TICKET;
> }
> -
> +
> SSLContext.setOptions(sslCtx, opts);
> // Set revocation
> // SSLContext.setCARevocation(sslContext,
> SSLCARevocationFile, SSLCARevocationPath);
> -
> +
> // Client certificate verification - maybe make it option
> try {
> SSLContext.setCipherSuite(sslCtx, SSLCipherSuite);
> -
> -
> +
> +
> if (serverMode) {
> if (ticketKey != null) {
> //SSLExt.setTicketKeys(sslCtx, ticketKey,
> ticketKey.length);
> }
> if (certFile != null) {
> - boolean rc = SSLContext.setCertificate(sslCtx,
> + boolean rc = SSLContext.setCertificate(sslCtx,
> certFile,
> keyFile, null, SSL.SSL_AIDX_DSA);
> if (!rc) {
> @@ -659,23 +659,23 @@ public class AprSocketContext {
> }
> }
> SSLContext.setVerify(sslCtx, SSL.SSL_CVERIFY_NONE, 10);
> -
> +
> if (spdyNPN != null) {
> SSLExt.setNPN(sslCtx, spdyNPN, spdyNPN.length);
> }
> } else {
> if (tlsCertVerifier != null) {
> - // NONE ?
> - SSLContext.setVerify(sslCtx,
> - SSL.SSL_CVERIFY_NONE, 10);
> + // NONE ?
> + SSLContext.setVerify(sslCtx,
> + SSL.SSL_CVERIFY_NONE, 10);
> } else {
> - SSLContext.setCACertificate(sslCtx,
> - "/etc/ssl/certs/ca-certificates.crt",
> + SSLContext.setCACertificate(sslCtx,
> + "/etc/ssl/certs/ca-certificates.crt",
> "/etc/ssl/certs");
> - SSLContext.setVerify(sslCtx,
> + SSLContext.setVerify(sslCtx,
> SSL.SSL_CVERIFY_REQUIRE, 10);
> }
> -
> +
> if (spdyNPN != null) {
> SSLExt.setNPN(sslCtx, spdyNPN, spdyNPN.length);
> }
> @@ -685,17 +685,17 @@ public class AprSocketContext {
> } catch (Exception e) {
> throw new IOException(e);
> }
> -
> - long mode =
> +
> + long mode =
> SSLExt.sslCtxSetMode(sslCtx,
> SSLExt.SSL_MODE_ENABLE_PARTIAL_WRITE |
> SSLExt.SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
> -
> +
> // TODO: try release buffers
> - }
> + }
> }
> return sslCtx;
> }
> -
> +
> void findPollerAndAdd(AprSocket ch) throws IOException {
> if (ch.poller != null) {
> ch.poller.requestUpdate(ch);
> @@ -703,7 +703,7 @@ public class AprSocketContext {
> }
> assignPoller(ch);
> }
> -
> +
> void assignPoller(AprSocket ch) throws IOException {
> AprPoller target = null;
> synchronized (pollers) {
> @@ -725,9 +725,9 @@ public class AprSocketContext {
> }
> if (target != null && target.add(ch)) {
> return;
> - }
> -
> - // can't be added - add a new poller
> + }
> +
> + // can't be added - add a new poller
> synchronized (pollers) {
> AprPoller poller = allocatePoller();
> poller.add(ch);
> @@ -740,7 +740,7 @@ public class AprSocketContext {
> * after handshake.
> */
> protected void onSocket(AprSocket s) throws IOException {
> -
> +
> }
>
> class AcceptorThread extends Thread {
> @@ -751,12 +751,12 @@ public class AprSocketContext {
> final String addressStr = null;
>
> long inetAddress;
> -
> +
> AcceptorThread(int port) {
> this.port = port;
> setDaemon(true);
> }
> -
> +
> void prepare() throws IOException {
> try {
> // Create the pool for the server socket
> @@ -779,13 +779,13 @@ public class AprSocketContext {
> // Bind the server socket
> int ret = Socket.bind(serverSock, inetAddress);
> if (ret != 0) {
> - throw new IOException("Socket.bind " + ret + " " +
> + throw new IOException("Socket.bind " + ret + " " +
> Error.strerror(ret) + " port=" + port);
> }
> // Start listening on the server socket
> ret = Socket.listen(serverSock, backlog );
> if (ret != 0) {
> - throw new IOException("endpoint.init.listen"
> + throw new IOException("endpoint.init.listen"
> + ret + " " + Error.strerror(ret));
> }
> if (OS.IS_WIN32 || OS.IS_WIN64) {
> @@ -810,7 +810,7 @@ public class AprSocketContext {
> throw new IOException(t);
> }
> }
> -
> +
> void unblock() {
> try {
> // Easiest ( maybe safest ) way to interrupt accept
> @@ -821,7 +821,7 @@ public class AprSocketContext {
> // ignore - the acceptor may have shut down by itself.
> }
> }
> -
> +
> @Override
> public void run() {
> while (running) {
> @@ -829,7 +829,7 @@ public class AprSocketContext {
> // each socket has a pool.
> final AprSocket ch = newSocket(AprSocketContext.this);
> ch.setStatus(AprSocket.ACCEPTED);
> -
> +
> ch.socket = Socket.accept(serverSock);
> if (!running) {
> break;
> @@ -838,7 +838,7 @@ public class AprSocketContext {
> if (connectionsCount.get() % 1000 == 0) {
> System.err.println("Accepted: " +
> connectionsCount.get());
> }
> -
> +
> if (nonBlockingAccept && !sslMode) {
> ch.setStatus(AprSocket.CONNECTED);
> // TODO: SSL really needs a thread.
> @@ -855,11 +855,11 @@ public class AprSocketContext {
> }
>
> class AcceptorDispatchThread extends Thread {
> -
> +
> AcceptorDispatchThread(int port) {
> setDaemon(true);
> }
> -
> +
> public void run() {
> while(running) {
> try {
> @@ -873,17 +873,17 @@ public class AprSocketContext {
> }
> }
> }
> -
> +
> /**
> * Create the poller. With some versions of APR, the maximum poller
> size will
> * be 62 (recompiling APR is necessary to remove this limitation).
> - * @throws IOException
> + * @throws IOException
> */
> AprPoller allocatePoller() throws IOException {
> long pool = Pool.create(getRootPool());
> int size = maxConnections / pollerThreadCount;
> int timeout = keepAliveTimeout;
> -
> +
> long serverPollset = allocatePoller(size, pool, timeout);
>
> if (serverPollset == 0 && size > 1024) {
> @@ -896,7 +896,7 @@ public class AprSocketContext {
> size = 62;
> serverPollset = allocatePoller(size, pool, timeout);
> }
> -
> +
> AprPoller res = new AprPoller();
> res.pool = pool;
> res.serverPollset = serverPollset;
> @@ -912,11 +912,11 @@ public class AprSocketContext {
> }
> return res;
> }
> -
> +
> // Removed the 'thread safe' updates for now, to simplify the code
> // last test shows a small improvement, can switch later.
> static boolean sizeLogged = false;
> -
> +
> protected long allocatePoller(int size, long pool, int timeout) {
> int flag = threadSafe ? Poll.APR_POLLSET_THREADSAFE: 0;
> for (int i = 0; i < 2; i++) {
> @@ -943,7 +943,7 @@ public class AprSocketContext {
> log.severe("Unexpected ENOTIMPL with flag==0");
> return 0;
> }
> -
> +
> class AprPoller extends Thread {
>
> public int id;
> @@ -960,16 +960,16 @@ public class AprSocketContext {
> // Should be replaced with socket data.
> // used only to lookup by socket
> Map<Long, AprSocket> channels = new HashMap<Long, AprSocket>();
> -
> +
> // Active + pending, must be < desc.length / 2
> // The channel will also have poller=this when active or pending
> // How many sockets have poller == this
> protected AtomicInteger keepAliveCount = new AtomicInteger();
> // Tracks desc, how many sockets are actively polled
> protected AtomicInteger polledCount = new AtomicInteger();
> -
> +
> protected AtomicInteger pollCount = new AtomicInteger();
> -
> +
> private List<AprSocket> updates = new ArrayList<AprSocket>();
>
> public void run() {
> @@ -983,17 +983,17 @@ public class AprSocketContext {
> while (running) {
> try {
> updates();
> -
> -
> +
> +
> lastCallbackTime = t0 - lastPoll;
> -
> +
> // Pool for the specified interval. Remove signaled
> sockets
> synchronized (this) {
> inPoll.set(true);
> }
> // if updates are added after updates and poll -
> interrupt will have still
> // work
> -
> +
> int rv = Poll.poll(serverPollset, pollTime, desc,
> true);
> synchronized (this) {
> inPoll.set(false);
> @@ -1001,14 +1001,14 @@ public class AprSocketContext {
> break;
> }
> }
> -
> - pollCount.incrementAndGet();
> +
> + pollCount.incrementAndGet();
> lastPoll = System.currentTimeMillis();
> lastPollTime = lastPoll - t0;
> -
> +
> if (rv > 0) {
> if (debugPoll) {
> - log.info(" Poll() id=" + id + " rv=" + rv +
> " keepAliveCount=" + keepAliveCount +
> + log.info(" Poll() id=" + id + " rv=" + rv +
> " keepAliveCount=" + keepAliveCount +
> " polled = " + polledCount.get()
> + " time=" + lastPollTime);
> }
> @@ -1017,7 +1017,7 @@ public class AprSocketContext {
> long sock = desc[pollIdx * 2 + 1];
> AprSocket ch;
> boolean blocking = false;
> -
> +
> synchronized (channels) {
> ch = channels.get(sock);
> if (ch != null) {
> @@ -1030,42 +1030,42 @@ public class AprSocketContext {
> }
> // was removed from polling
> ch.clearStatus(AprSocket.POLL);
> -
> +
> // We just removed it ( see last param to
> poll()).
> // Check for failed sockets and hand this
> socket off to a worker
> long mask = desc[pollIdx * 2];
> -
> +
> boolean hup = ((mask & Poll.APR_POLLHUP) ==
> Poll.APR_POLLHUP);
> boolean err = ((mask & Poll.APR_POLLERR) ==
> Poll.APR_POLLERR);
> boolean nval = ((mask & Poll.APR_POLLNVAL) !=
> 0);
> if (err || nval) {
> System.err.println("ERR " + err + " NVAL "
> + nval);
> }
> -
> +
> boolean out = (mask & Poll.APR_POLLOUT) ==
> Poll.APR_POLLOUT;
> boolean in = (mask & Poll.APR_POLLIN) ==
> Poll.APR_POLLIN;
> if (debugPoll) {
> - log.info(" Poll channel: " +
> Long.toHexString(mask) +
> + log.info(" Poll channel: " +
> Long.toHexString(mask) +
> (out ? " OUT" :"") +
> (in ? " IN": "") +
> (err ? " ERR" : "") +
> " Ch: " + ch);
> }
> -
> +
> // will be set again in process(), if all
> read/write is done
> ch.clearStatus(AprSocket.POLLOUT);
> ch.clearStatus(AprSocket.POLLIN);
> -
> +
> // try to send if needed
> if (blocking) {
> synchronized (ch) {
> - ch.notifyAll();
> + ch.notifyAll();
> }
> getExecutor().execute(ch);
> } else {
> ((AprSocketContext.NonBlockingPollHandler)
> ch.handler).process(ch, in, out, false);
> -
> - // Update polling for the channel (in IO
> thread, safe)
> +
> + // Update polling for the channel (in IO
> thread, safe)
> updateIOThread(ch);
> }
> }
> @@ -1074,7 +1074,7 @@ public class AprSocketContext {
> if (errn == Status.TIMEUP) {
> // to or interrupt
> // if (debugPoll) {
> -// log.info(" Poll() timeup" + "
> keepAliveCount=" + keepAliveCount +
> +// log.info(" Poll() timeup" + "
> keepAliveCount=" + keepAliveCount +
> // " polled = " + polledCount.get()
> // + " time=" + lastPollTime);
> // }
> @@ -1082,7 +1082,7 @@ public class AprSocketContext {
> // interrupt - no need to log
> } else {
> if (debugPoll) {
> - log.info(" Poll() rv=" + rv + "
> keepAliveCount=" + keepAliveCount +
> + log.info(" Poll() rv=" + rv + "
> keepAliveCount=" + keepAliveCount +
> " polled = " + polledCount.get()
> + " time=" + lastPollTime);
> }
> @@ -1096,13 +1096,13 @@ public class AprSocketContext {
> destroyPoller(); // will close all sockets
> }
> continue;
> - }
> + }
> }
> // TODO: timeouts
> } catch (Throwable t) {
> log.log(Level.SEVERE, "endpoint.poll.error", t);
> }
> -
> +
> }
> if (!running) {
> destroyPoller();
> @@ -1116,9 +1116,9 @@ public class AprSocketContext {
> synchronized (pollers) {
> pollers.remove(this);
> }
> - log.info("Poller stopped after cnt=" +
> - pollCount.get() +
> - " sockets=" + channels.size() +
> + log.info("Poller stopped after cnt=" +
> + pollCount.get() +
> + " sockets=" + channels.size() +
> " lastPoll=" + lastPoll);
>
> // Close all sockets
> @@ -1146,9 +1146,9 @@ public class AprSocketContext {
> }
> }
>
> - /**
> + /**
> * Called only in poller thread, only used if not thread safe
> - * @throws IOException
> + * @throws IOException
> */
> protected void updates() throws IOException {
> synchronized (this) {
> @@ -1158,7 +1158,7 @@ public class AprSocketContext {
> updates.clear();
> }
> }
> -
> +
> void interruptPoll() {
> try {
> int rc = Status.APR_SUCCESS;
> @@ -1180,17 +1180,17 @@ public class AprSocketContext {
> }
> }
>
> -
> +
> int remaining() {
> synchronized (channels) {
> return (desc.length - channels.size() * 2);
> - }
> + }
> }
> -
>
> -
> - /**
> - * Called from any thread, return true if we could add it
> +
> +
> + /**
> + * Called from any thread, return true if we could add it
> * to pending.
> */
> boolean add(AprSocket ch) throws IOException {
> @@ -1223,7 +1223,7 @@ public class AprSocketContext {
> updateIOThread(ch);
> } else {
> synchronized (this) {
> - updates.add(ch);
> + updates.add(ch);
> interruptPoll();
> }
> if (debugPoll) {
> @@ -1240,7 +1240,7 @@ public class AprSocketContext {
> // poll.
> //synchronized (ch)
> boolean polling = ch.checkPreConnect(AprSocket.POLL);
> -
> +
> int requested = ch.requestedPolling();
> if (requested == 0) {
> if (polling) {
> @@ -1252,7 +1252,7 @@ public class AprSocketContext {
> channels.remove(ch.socket);
> }
> keepAliveCount.decrementAndGet();
> - ch.reset();
> + ch.reset();
> }
> } else {
> if (polling) {
> @@ -1262,12 +1262,12 @@ public class AprSocketContext {
> pollAdd(ch, requested);
> }
> if (debugPoll) {
> - log.info("Poll: updated=" + id + " " + ch);
> + log.info("Poll: updated=" + id + " " + ch);
> }
> }
> -
> - /**
> - * Called only from IO thread
> +
> + /**
> + * Called only from IO thread
> */
> private void pollAdd(AprSocket up, int req) throws IOException {
> boolean failed = false;
> @@ -1286,11 +1286,11 @@ public class AprSocketContext {
> }
> if (failed) {
> up.reset();
> - throw new IOException("poll add error " + rv + " " + up
> + " " + Error.strerror((int)rv));
> + throw new IOException("poll add error " + rv + " " + up
> + " " + Error.strerror((int)rv));
> }
> }
>
> - /**
> + /**
> * Called only from IO thread. Remove from Poll and channels,
> * set POLL bit to false.
> */
> @@ -1301,64 +1301,64 @@ public class AprSocketContext {
> rv = Poll.remove(serverPollset, up.socket);
> }
> up.clearStatus(AprSocket.POLL);
> -
> +
> if (rv != Status.APR_SUCCESS) {
> log.severe("poll remove error " + Error.strerror((int)rv)
> + " " + up);
> } else {
> polledCount.decrementAndGet();
> }
> }
> -
> -
> +
> +
> public boolean isPollerThread() {
> return Thread.currentThread() == this;
> }
> -
> +
> }
> -
> +
> /**
> * Callback for poll events, will be invoked in a thread pool.
> - *
> + *
> */
> public static interface BlockingPollHandler {
> -
> +
> /**
> * Called when the socket has been polled for in, out or closed.
> - *
> - *
> + *
> + *
> */
> public void process(AprSocket ch, boolean in, boolean out, boolean
> close);
> -
> -
> +
> +
> /**
> - * Called just before the socket is destroyed
> + * Called just before the socket is destroyed
> */
> public void closed(AprSocket ch);
> }
> -
> +
> /**
> - * Additional callbacks for non-blocking.
> - * This can be much faster - but it's harder to code, should be used
> only
> - * for low-level protocol implementation, proxies, etc.
> - *
> + * Additional callbacks for non-blocking.
> + * This can be much faster - but it's harder to code, should be used
> only
> + * for low-level protocol implementation, proxies, etc.
> + *
> * The model is restricted in many ways to avoid complexity and bugs:
> - *
> + *
> * - read can only happen in the IO thread associated with the poller
> * - user doesn't control poll interest - it is set automatically
> based
> * on read/write results
> * - it is only possible to suspend read, for TCP flow control - also
> * only from the IO thread. Resume can happen from any thread.
> - * - it is also possible to call write() from any thread
> + * - it is also possible to call write() from any thread
> */
> public static interface NonBlockingPollHandler extends
> BlockingPollHandler {
> -
> - /**
> +
> + /**
> * Called after connection is established, in a thread pool.
> * Process will be called next.
> */
> public void connected(AprSocket ch);
> -
> - /**
> +
> + /**
> * Before close, if an exception happens.
> */
> public void error(AprSocket ch, Throwable t);
>
> Modified: tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/jni/socket/HostInfo.java Tue Mar
> 13 12:41:57 2012
> @@ -19,27 +19,29 @@ package org.apache.tomcat.jni.socket;
> import java.io.Serializable;
>
> /**
> - * Information about the remote host. Persisting this in memcache or
> similar
> + * Information about the remote host. Persisting this in memcache or
> similar
> * storage can improve performance on future TLS connections by skipping
> roundtrips
> * and reducing CPU use in handshake.
> - *
> + *
> * This class is used in both server and client mode.
> - *
> + *
> * AprSocketContextLitener.getPeer(name) can be used to read from an
> external storage.
> - *
> + *
> * TODO: also save the SPDY persistent settings here.
> * TODO: fix tickets, don't seem to work anymore.
> */
> public class HostInfo implements Serializable {
> -
> +
> + private static final long serialVersionUID = 1L;
> +
> public String host;
> -
> +
> public int port;
> -
> +
> public boolean secure;
> -
> +
> /**
> - * Raw cert data (x.509 format).
> + * Raw cert data (x.509 format).
> * This is retrieved when a full handshake happens - if session reuse
> or tickets
> * are used you'll not receive the certs again.
> */
> @@ -47,7 +49,7 @@ public class HostInfo implements Seriali
>
> public byte[] ticket;
> public int ticketLen;
> -
> +
> public String sessionId;
>
> /**
> @@ -60,7 +62,7 @@ public class HostInfo implements Seriali
> */
> byte[] npn;
> int npnLen;
> -
> +
> public HostInfo() {
> }
>
> @@ -69,15 +71,14 @@ public class HostInfo implements Seriali
> this.port = port;
> this.secure = secure;
> }
> -
> +
> public String getNpn() {
> - return new String(npn, 0, npnLen);
> + return new String(npn, 0, npnLen);
> }
>
> public void setNpn(String npn) {
> if (npn == null) {
> npnLen = 0;
> - npn = null;
> }
> }
> }
> \ No newline at end of file
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyConnection.java Tue Mar
> 13 12:41:57 2012
> @@ -146,20 +146,20 @@ public abstract class SpdyConnection { /
> this.spdyContext = spdyContext;
> outCondition = framerLock.newCondition();
> }
> -
> +
> public String toString() {
> return "SpdyCon open=" + channels.size();
> }
> -
> +
> public void dump(PrintWriter out) {
> - out.println("SpdyConnection open=" + channels.size() +
> + out.println("SpdyConnection open=" + channels.size() +
> " outQ:" + outQueue.size());
> for (SpdyStream str: channels.values()) {
> str.dump(out);
> }
> -
> +
> out.println();
> -
> +
> }
>
> /**
> @@ -215,7 +215,7 @@ public abstract class SpdyConnection { /
> draining = false;
> }
> }
> -
> +
> /**
> * Non blocking if the socket is not blocking.
> */
> @@ -233,7 +233,7 @@ public abstract class SpdyConnection { /
> return false;
> }
> if (goAway < out.streamId) {
> -
> +
> }
> SpdyFrame oframe = out;
> try {
> @@ -297,7 +297,7 @@ public abstract class SpdyConnection { /
> out.off += wr;
> toWrite -= wr;
> }
> - }
> + }
> // Frame was sent
> framerLock.lock();
> try {
> @@ -305,9 +305,9 @@ public abstract class SpdyConnection { /
> } finally {
> framerLock.unlock();
> }
> -
> +
> synchronized (channels) {
> - if (out.stream != null &&
> + if (out.stream != null &&
> out.stream.finRcvd && out.stream.finSent) {
> channels.remove(out.streamId);
> }
> @@ -354,7 +354,7 @@ public abstract class SpdyConnection { /
> // We can't assing a stream ID until it is sent - priorities
> // we can't compress either - it's stateful.
> oframe.stream = proc;
> -
> +
> framerLock.lock();
> try {
> outQueue.add(oframe);
> @@ -448,7 +448,7 @@ public abstract class SpdyConnection { /
> }
>
> // TODO: if data, split it in 2 frames
> - // grow the buffer if needed.
> + // grow the buffer if needed.
> if (inFrame.data.length < inFrame.endData) {
> byte[] tmp = new byte[inFrame.endData];
> System.arraycopy(inFrame.data, 0, tmp, 0,
> inFrame.endReadData);
> @@ -557,7 +557,7 @@ public abstract class SpdyConnection { /
>
> /**
> * Process a SPDY connection. Called in a separate thread.
> - *
> + *
> * @return
> * @throws IOException
> */
> @@ -577,7 +577,7 @@ public abstract class SpdyConnection { /
> case TYPE_GOAWAY: {
> int lastStream = inFrame.readInt();
> log.info("GOAWAY last=" + lastStream);
> -
> +
> // Server will shut down - but will keep processing the
> current requests,
> // up to lastStream. If we sent any new ones - they need
> to be canceled.
> abort("GO_AWAY", lastStream);
> @@ -601,7 +601,7 @@ public abstract class SpdyConnection { /
> return CLOSE;
> }
> sch.onCtlFrame(inFrame);
> -
> +
> synchronized(channels) {
> channels.remove(inFrame.streamId);
> }
> @@ -663,7 +663,7 @@ public abstract class SpdyConnection { /
> // Data frame
> SpdyStream sch;
> synchronized (channels) {
> - sch = channels.get(inFrame.streamId);
> + sch = channels.get(inFrame.streamId);
> }
> if (sch == null) {
> abort("Missing channel");
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContext.java Tue Mar 13
> 12:41:57 2012
> @@ -66,18 +66,18 @@ public class SpdyContext {
>
> /**
> * Set the max frame size.
> - *
> + *
> * Larger data packets will be split in multiple frames.
> - *
> - * ( the code is currently accepting larger control frames - it's not
> + *
> + * ( the code is currently accepting larger control frames - it's not
> * clear if we should just reject them, many servers limit header size
> -
> * the http connector also has a 8k limit - getMaxHttpHeaderSize )
> */
> - public void setFrameSize(int frameSize) {
> + public void setFrameSize(int frameSize) {
> defaultFrameSize = frameSize;
> }
> -
> - /**
> +
> + /**
> * Override for server side to return a custom stream.
> */
> public SpdyStream getStream(SpdyConnection framer) {
> @@ -120,11 +120,11 @@ public class SpdyContext {
>
> public void releaseConnection(SpdyConnection con) {
> }
> -
> +
> public void listen(final int port, String cert, String key) throws
> IOException {
> throw new IOException("Not implemented");
> - }
> -
> + }
> +
> /**
> * Close all pending connections and free resources.
> */
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextJni.java Tue Mar
> 13 12:41:57 2012
> @@ -1,4 +1,18 @@
> /*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements. See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License. You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
> implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> */
> package org.apache.tomcat.spdy;
>
> @@ -12,9 +26,9 @@ import org.apache.tomcat.jni.socket.AprS
>
> public class SpdyContextJni extends SpdyContext {
> AprSocketContext con;
> -
> +
> //AprSocketContext socketCtx;
> -
> +
> public SpdyContextJni() {
> con = new AprSocketContext();
> //if (insecureCerts) {
> @@ -26,11 +40,11 @@ public class SpdyContextJni extends Spdy
> //}
> con.setNpn("spdy/2");
> }
> -
> +
> @Override
> public SpdyConnection getConnection(String host, int port) throws
> IOException {
> SpdyConnectionAprSocket spdy = new SpdyConnectionAprSocket(this);
> -
> +
> AprSocket ch = con.socket(host, port, tls);
>
> spdy.setSocket(ch);
> @@ -38,7 +52,7 @@ public class SpdyContextJni extends Spdy
> ch.connect();
>
> ch.setHandler(new SpdySocketHandler(spdy));
> -
> +
> // need to consume the input to receive more read events
> int rc = spdy.processInput();
> if (rc == SpdyConnection.CLOSE) {
> @@ -48,50 +62,50 @@ public class SpdyContextJni extends Spdy
>
> return spdy;
> }
> -
> +
> public void onAccept(long socket) throws IOException {
> SpdyConnectionAprSocket spdy = new
> SpdyConnectionAprSocket(SpdyContextJni.this);
> AprSocket s = con.socket(socket);
> spdy.setSocket(s);
> -
> +
> SpdySocketHandler handler = new SpdySocketHandler(spdy);
> - s.setHandler(handler);
> + s.setHandler(handler);
> handler.process(s, true, true, false);
> }
> -
> +
> public void listen(final int port, String cert, String key) throws
> IOException {
> con = new AprSocketContext() {
> protected void onSocket(AprSocket s) throws IOException {
> SpdyConnectionAprSocket spdy = new
> SpdyConnectionAprSocket(SpdyContextJni.this);
> spdy.setSocket(s);
> -
> +
> SpdySocketHandler handler = new SpdySocketHandler(spdy);
> s.setHandler(handler);
> }
> };
> -
> +
> con.setNpn(SpdyContext.SPDY_NPN_OUT);
> con.setKeys(cert, key);
> -
> +
> con.listen(port);
> }
>
> public void stop() throws IOException {
> con.stop();
> }
> -
> +
> public AprSocketContext getAprContext() {
> return con;
> - }
> -
> + }
> +
> // NB
> class SpdySocketHandler implements NonBlockingPollHandler {
> SpdyConnection con;
> -
> +
> SpdySocketHandler(SpdyConnection con) {
> this.con = con;
> }
> -
> +
> @Override
> public void closed(AprSocket ch) {
> // not used ( polling not implemented yet )
> @@ -119,9 +133,9 @@ public class SpdyContextJni extends Spdy
> @Override
> public void error(AprSocket ch, Throwable t) {
> }
> -
> +
> }
> -
> +
> public static class SpdyConnectionAprSocket extends SpdyConnection {
> AprSocket socket;
>
> @@ -141,7 +155,7 @@ public class SpdyContextJni extends Spdy
> public void close() throws IOException {
> socket.close();
> }
> -
> +
> @Override
> public int write(byte[] data, int off, int len) throws IOException
> {
> if (socket == null) {
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java
> (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyContextProxy.java Tue Mar
> 13 12:41:57 2012
> @@ -20,7 +20,6 @@ import java.io.IOException;
> import java.net.ServerSocket;
> import java.net.Socket;
> import java.net.SocketTimeoutException;
> -import java.util.concurrent.Semaphore;
>
> /**
> * Spdy context for 'proxy' or test mode spdy - no NPN, no SSL, no
> compression.
> @@ -99,20 +98,22 @@ public class SpdyContextProxy extends Sp
> }
> }
> }
> -
> -
> +
> +
> boolean running = true;
> ServerSocket serverSocket;
> -
> +
> + @Override
> public void stop() throws IOException {
> running = false;
> serverSocket.close();
> }
> -
> +
> /**
> * For small servers/testing: run in server mode.
> * Need to override onSynStream() to implement the logic.
> */
> + @Override
> public void listen(final int port, String cert, String key) throws
> IOException {
> getExecutor().execute(new Runnable() {
> @Override
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyFrame.java Tue Mar 13
> 12:41:57 2012
> @@ -26,8 +26,8 @@ public class SpdyFrame {
> public static byte[] HTTP11 = "HTTP/1.1".getBytes();
>
> public static byte[] OK200 = "200 OK".getBytes();
> -
> -
> +
> +
> // This is a bit more complicated, to avoid multiple reads/writes.
> // We'll read as much as possible - possible past frame end. This may
> // cost an extra copy - or even more complexity for dealing with slices
> @@ -43,8 +43,8 @@ public class SpdyFrame {
> /**
> * end of data in the buffer.
> */
> - public int endData;
> -
> + public int endData;
> +
> // Processed data from the frame
> boolean c; // for control
>
> @@ -240,7 +240,7 @@ public class SpdyFrame {
> nvCount++;
> headerValue(buf, soff, len);
> }
> -
> +
> public void addHeader(String name, String value) {
> byte[] nameB = name.getBytes();
> headerName(nameB, 0, nameB.length);
> @@ -258,7 +258,7 @@ public class SpdyFrame {
> headerName(nameB, 0, nameB.length);
> headerValue(valueB, 0, valueB.length);
> }
> -
> +
> public void getHeaders(Map<String, String> resHeaders) {
> for (int i = 0; i < nvCount; i++) {
> int len = read16();
> @@ -270,7 +270,7 @@ public class SpdyFrame {
> resHeaders.put(n, v);
> }
> }
> -
> +
>
> // TODO: instead of that, use byte[][]
> void makeSpace(int len) {
>
> Modified: tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java
> URL:
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java?rev=1300102&r1=1300101&r2=1300102&view=diff
>
> ==============================================================================
> --- tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java (original)
> +++ tomcat/trunk/java/org/apache/tomcat/spdy/SpdyStream.java Tue Mar 13
> 12:41:57 2012
> @@ -54,18 +54,18 @@ public class SpdyStream {
> protected boolean finSent;
>
> protected boolean finRcvd;
> -
> +
> /**
> * Dummy data frame to insert on reset / go away
> */
> static SpdyFrame END_FRAME;
> -
> +
> static {
> END_FRAME = new SpdyFrame(16);
> END_FRAME.endData = 0;
> END_FRAME.off = 0;
> - END_FRAME.c = false;
> - END_FRAME.flags =SpdyConnection.FLAG_HALF_CLOSE;
> + END_FRAME.c = false;
> + END_FRAME.flags =SpdyConnection.FLAG_HALF_CLOSE;
> }
>
> public SpdyStream(SpdyConnection spdy) {
> @@ -117,30 +117,30 @@ public class SpdyStream {
> inData.add(frame);
> if (frame.isHalfClose()) {
> finRcvd = true;
> - }
> + }
> }
> }
>
> - /**
> + /**
> * Called on GOAWAY or reset.
> */
> public void onReset() {
> finRcvd = true;
> finSent = true;
> -
> +
> // To unblock
> inData.add(END_FRAME);
> }
> -
> +
> /**
> * True if the channel both received and sent FIN frames.
> - *
> + *
> * This is tracked by the processor, to avoid extra storage in framer.
> */
> public boolean isFinished() {
> return finSent && finRcvd;
> }
> -
> +
> /**
> * Waits and return the next data frame.
> */
> @@ -152,7 +152,7 @@ public class SpdyStream {
> }
> }
> }
> -
> +
> /**
> * Waits and return the next frame. First frame will be the control
> frame
> */
> @@ -162,7 +162,7 @@ public class SpdyStream {
> synchronized (this) {
> if (inData.size() == 0 && finRcvd) {
> return null;
> - }
> + }
> }
> in = inData.poll(to, TimeUnit.MILLISECONDS);
> if (in == END_FRAME) {
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: dev-help@tomcat.apache.org
>
>