First attempt for SSL send file
authorfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 26 Nov 2008 03:39:03 +0000 (03:39 +0000)
committerfhanik <fhanik@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 26 Nov 2008 03:39:03 +0000 (03:39 +0000)
git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@720724 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/coyote/http11/Http11NioProtocol.java
java/org/apache/tomcat/util/net/NioChannel.java
java/org/apache/tomcat/util/net/NioEndpoint.java
java/org/apache/tomcat/util/net/SecureNioChannel.java

index 6315513..b30ceef 100644 (file)
@@ -309,7 +309,6 @@ public class Http11NioProtocol implements ProtocolHandler, MBeanRegistration
     public void setUseSendfile(boolean useSendfile) {
         ep.setUseSendfile(useSendfile);
     }
-
     
     // -------------------- Tcp setup --------------------
 
index ba90442..aba04da 100644 (file)
@@ -47,6 +47,8 @@ public class NioChannel implements ByteChannel{
     protected ApplicationBufferHandler bufHandler;
 
     protected Poller poller;
+    
+    protected boolean sendFile = false;
 
     public NioChannel(SocketChannel channel, ApplicationBufferHandler bufHandler) throws IOException {
         this.sc = channel;
@@ -56,6 +58,7 @@ public class NioChannel implements ByteChannel{
     public void reset() throws IOException {
         bufHandler.getReadBuffer().clear();
         bufHandler.getWriteBuffer().clear();
+        this.sendFile = false;
     }
     
     public int getBufferSize() {
@@ -191,5 +194,22 @@ public class NioChannel implements ByteChannel{
     public String toString() {
         return super.toString()+":"+this.sc.toString();
     }
+    
+    public int getOutboundRemaining() {
+        return 0;
+    }
+    
+    public void flushOutbound() throws IOException {
+        
+    }
+    
+    public boolean isSendFile() {
+        return sendFile;
+    }
+    
+    public void setSendFile(boolean s) {
+        this.sendFile = s;
+    }
+    
 
 }
index ff12518..9423b9c 100644 (file)
@@ -30,6 +30,7 @@ import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.nio.channels.ServerSocketChannel;
 import java.nio.channels.SocketChannel;
+import java.nio.channels.WritableByteChannel;
 import java.security.KeyStore;
 import java.util.Collection;
 import java.util.Iterator;
@@ -644,7 +645,6 @@ public class NioEndpoint {
     }
 
     public void setUseSendfile(boolean useSendfile) {
-
         this.useSendfile = useSendfile;
     }
 
@@ -958,8 +958,7 @@ public class NioEndpoint {
     }
 
     public boolean getUseSendfile() {
-        //send file doesn't work with SSL
-        return useSendfile && (!isSSLEnabled());
+        return useSendfile;
     }
 
     public int getOomParachute() {
@@ -1328,10 +1327,10 @@ public class NioEndpoint {
                     } else {
                         cancel = true;
                     }
-                    if ( cancel ) getPoller0().cancelledKey(key,SocketStatus.ERROR,false);
+                    if ( cancel ) socket.getPoller().cancelledKey(key,SocketStatus.ERROR,false);
                 }catch (CancelledKeyException ckx) {
                     try {
-                        getPoller0().cancelledKey(key,SocketStatus.DISCONNECT,true);
+                        socket.getPoller().cancelledKey(key,SocketStatus.DISCONNECT,true);
                     }catch (Exception ignore) {}
                 }
             }//end if
@@ -1627,6 +1626,7 @@ public class NioEndpoint {
         }
         
         public boolean processSendfile(SelectionKey sk, KeyAttachment attachment, boolean reg, boolean event) {
+            NioChannel sc = null;
             try {
                 //unreg(sk,attachment);//only do this if we do process send file on a separate thread
                 SendfileData sd = attachment.getSendfileData();
@@ -1638,13 +1638,20 @@ public class NioEndpoint {
                     }
                     sd.fchannel = new FileInputStream(f).getChannel();
                 }
-                SocketChannel sc = attachment.getChannel().getIOChannel();
-                long written = sd.fchannel.transferTo(sd.pos,sd.length,sc);
-                if ( written > 0 ) {
-                    sd.pos += written;
-                    sd.length -= written;
+                sc = attachment.getChannel();
+                sc.setSendFile(true);
+                WritableByteChannel wc =(WritableByteChannel) ((sc instanceof SecureNioChannel)?sc:sc.getIOChannel());
+                
+                if (sc.getOutboundRemaining()>0) {
+                    sc.flushOutbound();
+                } else {
+                    long written = sd.fchannel.transferTo(sd.pos,sd.length,wc);
+                    if ( written > 0 ) {
+                        sd.pos += written;
+                        sd.length -= written;
+                    }
                 }
-                if ( sd.length <= 0 ) {
+                if ( sd.length <= 0 && sc.getOutboundRemaining()<=0) {
                     if (log.isDebugEnabled()) {
                         log.debug("Send file complete for:"+sd.fileName);
                     }
@@ -1684,6 +1691,8 @@ public class NioEndpoint {
                 log.error("",t);
                 cancelledKey(sk, SocketStatus.ERROR, false);
                 return false;
+            }finally {
+                if (sc!=null) sc.setSendFile(false);
             }
             return true;
         }
index 8529962..8f25203 100644 (file)
@@ -400,7 +400,7 @@ public class SecureNioChannel extends NioChannel  {
             return written;
         } else {
             //make sure we can handle expand, and that we only use on buffer
-            if ( src != bufHandler.getWriteBuffer() ) throw new IllegalArgumentException("You can only write using the application write buffer provided by the handler.");
+            if ( (!this.isSendFile()) && (src != bufHandler.getWriteBuffer()) ) throw new IllegalArgumentException("You can only write using the application write buffer provided by the handler.");
             //are we closing or closed?
             if ( closing || closed) throw new IOException("Channel is in closing state.");
 
@@ -434,6 +434,17 @@ public class SecureNioChannel extends NioChannel  {
         }
     }
     
+    @Override
+    public int getOutboundRemaining() {
+        return netOutBuffer.remaining();
+    }
+    
+    @Override
+    public void flushOutbound() throws IOException {
+        flush(netOutBuffer);
+    }
+
+    
     /**
      * Callback interface to be able to expand buffers
      * when buffer overflow exceptions happen