Author: fhanik
Date: Wed Jan 14 09:39:07 2009
New Revision: 734454

URL: http://svn.apache.org/viewvc?rev=734454&view=rev
Log:
NIO Fixes

Added:
    
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/NioX509KeyManager.java
Modified:
    tomcat/tc6.0.x/trunk/STATUS.txt
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
    tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
    tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
    tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml

Modified: tomcat/tc6.0.x/trunk/STATUS.txt
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/STATUS.txt?rev=734454&r1=734453&r2=734454&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/STATUS.txt (original)
+++ tomcat/tc6.0.x/trunk/STATUS.txt Wed Jan 14 09:39:07 2009
@@ -133,26 +133,6 @@
          Just did that for trunk (r711934; but it contains also other changes).
          Caution: at the moment there's no @VERSION@ substitution for 
service.bat.
 
-* I have summarized all the NIO fixes into one patch for those who wish to 
test it
-* It includes patch [1]-[6] below and can be found at:
-* http://people.apache.org/~fhanik/tomcat/uber-patch.txt
-
-* [1] Fix send file bug - correctly notify the poller without having to wait 
for it to wake up
-  http://svn.apache.org/viewvc?rev=719129&view=rev
-  +1: fhanik, pero, markt, jim
-  -1: 
-
-* [2] Prevent async close NPE on already closed sockets
-  http://people.apache.org/~fhanik/tomcat/comet-close-2.patch
-  +1: fhanik, markt (need to fix indenting), funkman
-  -1: 
-
-* [3] Add ability to fix the keyAlias in NIO/SSL
-  http://svn.apache.org/viewvc?rev=720587&view=rev
-  http://svn.apache.org/viewvc?rev=720553&view=rev 
-  +1: fhanik, markt, funkman
-  -1:
-
 * [4] Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=45154 (add 
sendfile support to NIO/SSL) - performance improvement
   http://svn.apache.org/viewvc?rev=720724&view=rev
   http://svn.apache.org/viewvc?rev=720728&view=rev 
@@ -165,12 +145,6 @@
   +1: fhanik, funkman
   -1: 
 
-* [6] Fix file descriptor leak during send file behavior in NIO connector
-  http://svn.apache.org/viewvc?rev=729191&view=rev 
-  +1: fhanik, markt, jim, funkman
-  -1: 
-  
-
 * Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=42693
   Fix compilation of recursive tags
   http://svn.apache.org/viewvc?rev=720046&view=rev

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=734454&r1=734453&r2=734454&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java 
Wed Jan 14 09:39:07 2009
@@ -940,7 +940,7 @@
                 sendfileData.keepAlive = keepAlive;
                 SelectionKey key = 
socket.getIOChannel().keyFor(socket.getPoller().getSelector());
                 //do the first write on this thread, might as well
-                openSocket = socket.getPoller().processSendfile(key,ka,true);
+                openSocket = 
socket.getPoller().processSendfile(key,ka,true,true);
                 break;
             }
 
@@ -1227,14 +1227,16 @@
         } else if (actionCode == ActionCode.ACTION_COMET_END) {
             comet = false;
         }  else if (actionCode == ActionCode.ACTION_COMET_CLOSE) {
-            NioEndpoint.KeyAttachment attach = 
(NioEndpoint.KeyAttachment)socket.getAttachment(false);
-            attach.setCometOps(NioEndpoint.OP_CALLBACK);
+            if (socket==null || socket.getAttachment(false)==null) return;
+               NioEndpoint.KeyAttachment attach = 
(NioEndpoint.KeyAttachment)socket.getAttachment(false);
+            attach.setCometOps(NioEndpoint.OP_CALLBACK | attach.getCometOps());
             //notify poller if not on a tomcat thread
             RequestInfo rp = request.getRequestProcessor();
             if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) 
//async handling
                 socket.getPoller().cometInterest(socket);
         } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) {
             if (param==null) return;
+            if (socket==null || socket.getAttachment(false)==null) return;
             NioEndpoint.KeyAttachment attach = 
(NioEndpoint.KeyAttachment)socket.getAttachment(false);
             long timeout = ((Long)param).longValue();
             //if we are not piggy backing on a worker thread, set the timeout

Modified: 
tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=734454&r1=734453&r2=734454&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java 
Wed Jan 14 09:39:07 2009
@@ -545,6 +545,10 @@
     public void setKeystore(String s) { setKeystoreFile(s);}
     public String getKeystore(){ return getKeystoreFile();}
     
+    public String getKeyAlias() { return ep.getKeyAlias();}
+    public void setKeyAlias(String s ) { ep.setKeyAlias(s);}
+
+    
     public String getAlgorithm() { return ep.getAlgorithm();}
     public void setAlgorithm(String s ) { ep.setAlgorithm(s);}
     

Modified: tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=734454&r1=734453&r2=734454&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java 
(original)
+++ tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Wed 
Jan 14 09:39:07 2009
@@ -44,17 +44,21 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
+
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLSessionContext;
 import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509KeyManager;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.IntrospectionUtils;
 import org.apache.tomcat.util.net.JIoEndpoint.Worker;
 import org.apache.tomcat.util.net.SecureNioChannel.ApplicationBufferHandler;
+import org.apache.tomcat.util.net.jsse.NioX509KeyManager;
 import org.apache.tomcat.util.res.StringManager;
 
 /**
@@ -572,6 +576,11 @@
     }
     public void setKeystore(String s ) { setKeystoreFile(s);}
     public String getKeystore() { return getKeystoreFile();}
+
+    String keyAlias = null;
+    public String getKeyAlias() { return keyAlias;}
+    public void setKeyAlias(String s ) { keyAlias = s;}
+    
     
     protected String algorithm = "SunX509";
     public String getAlgorithm() { return algorithm;}
@@ -785,8 +794,7 @@
             ks.load(new FileInputStream(getKeystoreFile()), passphrase);
             KeyStore ts = null;
             if (getTruststoreFile()==null) {
-                ts = KeyStore.getInstance(getKeystoreType());
-                ts.load(new FileInputStream(getKeystoreFile()), passphrase);
+                //no op, same as for BIO connector
             }else {
                 ts = KeyStore.getInstance(ttype);
                 ts.load(new FileInputStream(getTruststoreFile()), tpassphrase);
@@ -799,7 +807,7 @@
             tmf.init(ts);
 
             sslContext = SSLContext.getInstance(getSslProtocol());
-            sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), 
null);
+            sslContext.init(wrap(kmf.getKeyManagers()), 
tmf.getTrustManagers(), null);
             SSLSessionContext sessionContext =
                 sslContext.getServerSessionContext();
             if (sessionContext != null) {
@@ -813,6 +821,19 @@
         initialized = true;
 
     }
+    
+    public KeyManager[] wrap(KeyManager[] managers) {
+        if (managers==null) return null;
+        KeyManager[] result = new KeyManager[managers.length];
+        for (int i=0; i<result.length; i++) {
+            if (managers[i] instanceof X509KeyManager && getKeyAlias()!=null) {
+                result[i] = new 
NioX509KeyManager((X509KeyManager)managers[i],getKeyAlias());
+            } else {
+                result[i] = managers[i];
+            }
+        }
+        return result;
+    }
 
 
     /**
@@ -1317,6 +1338,7 @@
                             int ops = key.interestOps() | interestOps;
                             att.interestOps(ops);
                             key.interestOps(ops);
+                            att.setCometOps(ops);
                         } else {
                             cancel = true;
                         }
@@ -1459,11 +1481,13 @@
                     }                    
                 }
                 
+                key.attach(null);
                 if (ka!=null) handler.release(ka.getChannel());
                 if (key.isValid()) key.cancel();
                 if (key.channel().isOpen()) try {key.channel().close();}catch 
(Exception ignore){}
-                try {ka.channel.close(true);}catch (Exception ignore){}
-                key.attach(null);
+                try {if (ka!=null) ka.channel.close(true);}catch (Exception 
ignore){}
+                try {if (ka!=null && ka.getSendfileData()!=null && 
ka.getSendfileData().fchannel!=null && ka.getSendfileData().fchannel.isOpen()) 
ka.getSendfileData().fchannel.close();}catch (Exception ignore){}
+                if (ka!=null) ka.reset();
             } catch (Throwable e) {
                 if ( log.isDebugEnabled() ) log.error("",e);
                 // Ignore
@@ -1575,7 +1599,7 @@
                     NioChannel channel = attachment.getChannel();
                     if (sk.isReadable() || sk.isWritable() ) {
                         if ( attachment.getSendfileData() != null ) {
-                            processSendfile(sk,attachment,true);
+                            processSendfile(sk,attachment,true, false);
                         } else if ( attachment.getComet() ) {
                             //check if thread is available
                             if ( isWorkerAvailable() ) {
@@ -1620,7 +1644,7 @@
             return result;
         }
         
-        public boolean processSendfile(SelectionKey sk, KeyAttachment 
attachment, boolean reg) {
+        public boolean processSendfile(SelectionKey sk, KeyAttachment 
attachment, boolean reg, boolean event) {
             try {
                 //unreg(sk,attachment);//only do this if we do process send 
file on a separate thread
                 SendfileData sd = attachment.getSendfileData();
@@ -1643,11 +1667,18 @@
                         log.debug("Send file complete for:"+sd.fileName);
                     }
                     attachment.setSendfileData(null);
+                    try {sd.fchannel.close();}catch(Exception ignore){}
                     if ( sd.keepAlive ) {
-                        if (log.isDebugEnabled()) {
-                            log.debug("Connection is keep alive, registering 
back for OP_READ");
+                        if (reg) {
+                            if (log.isDebugEnabled()) {
+                                log.debug("Connection is keep alive, 
registering back for OP_READ");
+                            }
+                            if (event) {
+                                
this.add(attachment.getChannel(),SelectionKey.OP_READ);
+                            } else {
+                                reg(sk,attachment,SelectionKey.OP_READ);
+                            }
                         }
-                        if (reg) reg(sk,attachment,SelectionKey.OP_READ);
                     } else {
                         if (log.isDebugEnabled()) {
                             log.debug("Send file connection is being closed");
@@ -1658,11 +1689,14 @@
                     if (log.isDebugEnabled()) {
                         log.debug("OP_WRITE for sendilfe:"+sd.fileName);
                     }
-
-                    reg(sk,attachment,SelectionKey.OP_WRITE);
+                    if (event) {
+                        add(attachment.getChannel(),SelectionKey.OP_WRITE);
+                    } else {
+                        reg(sk,attachment,SelectionKey.OP_WRITE);
+                    }
                 }
             }catch ( IOException x ) {
-                if ( log.isDebugEnabled() ) log.warn("Unable to complete 
sendfile request:", x);
+                if ( log.isDebugEnabled() ) log.debug("Unable to complete 
sendfile request:", x);
                 cancelledKey(sk,SocketStatus.ERROR,false);
                 return false;
             }catch ( Throwable t ) {
@@ -1681,7 +1715,7 @@
         protected void reg(SelectionKey sk, KeyAttachment attachment, int 
intops) {
             sk.interestOps(intops); 
             attachment.interestOps(intops);
-            attachment.setCometOps(intops);
+            //attachment.setCometOps(intops);
         }
 
         protected void timeout(int keyCount, boolean hasEvents) {

Added: 
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/NioX509KeyManager.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/NioX509KeyManager.java?rev=734454&view=auto
==============================================================================
--- 
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/NioX509KeyManager.java
 (added)
+++ 
tomcat/tc6.0.x/trunk/java/org/apache/tomcat/util/net/jsse/NioX509KeyManager.java
 Wed Jan 14 09:39:07 2009
@@ -0,0 +1,86 @@
+/*
+ *  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.util.net.jsse;
+
+import java.net.Socket;
+import java.security.Principal;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
+
+public class NioX509KeyManager extends X509ExtendedKeyManager {
+
+    private X509KeyManager delegate;
+    private String serverKeyAlias;
+
+    /**
+     * Constructor.
+     *
+     * @param mgr The X509KeyManager used as a delegate
+     * @param serverKeyAlias The alias name of the server's keypair and
+     * supporting certificate chain
+     */
+    public NioX509KeyManager(X509KeyManager mgr, String serverKeyAlias) {
+        this.delegate = mgr;
+        this.serverKeyAlias = serverKeyAlias;
+    }
+
+    public String chooseClientAlias(String[] keyType, Principal[] issuers, 
Socket socket) {
+        return delegate.chooseClientAlias(keyType, issuers, socket);
+    }
+
+    public String chooseServerAlias(String keyType, Principal[] issuers, 
Socket socket) {
+        if (serverKeyAlias!=null) {
+            return serverKeyAlias;
+        } else {
+            return delegate.chooseServerAlias(keyType, issuers, socket);
+        }
+    }
+
+    public X509Certificate[] getCertificateChain(String alias) {
+        return delegate.getCertificateChain(alias);
+    }
+
+    public String[] getClientAliases(String keyType, Principal[] issuers) {
+        return delegate.getClientAliases(keyType, issuers);
+    }
+
+    public PrivateKey getPrivateKey(String alias) {
+        return delegate.getPrivateKey(alias);
+    }
+
+    public String[] getServerAliases(String keyType, Principal[] issuers) {
+        return delegate.getServerAliases(keyType, issuers);
+    }
+
+    @Override
+    public String chooseEngineServerAlias(String keyType, Principal[] issuers, 
SSLEngine engine) {
+        if (serverKeyAlias!=null) {
+            return serverKeyAlias;
+        } else {
+            return super.chooseEngineServerAlias(keyType, issuers, engine);
+        }
+    }
+
+    
+    
+    
+}

Modified: tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml?rev=734454&r1=734453&r2=734454&view=diff
==============================================================================
--- tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc6.0.x/trunk/webapps/docs/changelog.xml Wed Jan 14 09:39:07 2009
@@ -224,6 +224,18 @@
   <subsection name="Coyote">
     <changelog>
       <update>
+        Fix file descriptor leak during NIO send file behavior. (fhanik)
+      </update>
+      <update>
+        Implement usage of keyAlias attribute for NIO, previously attribute 
was ignored. (fhanik)
+      </update>
+      <update>
+        Prevent server from calling close on an already closed NIO socket. One 
that had timed out. (fhanik)
+      </update>
+      <update>
+        Fix bug with SEND_FILE behavior in NIO. Send file would delay until 
selector timed out, even though socket was ready to be written. (fhanik)
+      </update>
+      <update>
         Fix possible NPE in NioEndpoint.java (fhanik)
       </update>
       <update>



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to