From 4468001871469a51fea97f1ef6b6822001239b09 Mon Sep 17 00:00:00 2001 From: fhanik Date: Wed, 26 Nov 2008 03:39:03 +0000 Subject: [PATCH] First attempt for SSL send file git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@720724 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/coyote/http11/Http11NioProtocol.java | 1 - java/org/apache/tomcat/util/net/NioChannel.java | 20 ++++++++++++++ java/org/apache/tomcat/util/net/NioEndpoint.java | 31 ++++++++++++++-------- .../apache/tomcat/util/net/SecureNioChannel.java | 13 ++++++++- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/java/org/apache/coyote/http11/Http11NioProtocol.java b/java/org/apache/coyote/http11/Http11NioProtocol.java index 631551364..b30ceef0f 100644 --- a/java/org/apache/coyote/http11/Http11NioProtocol.java +++ b/java/org/apache/coyote/http11/Http11NioProtocol.java @@ -309,7 +309,6 @@ public class Http11NioProtocol implements ProtocolHandler, MBeanRegistration public void setUseSendfile(boolean useSendfile) { ep.setUseSendfile(useSendfile); } - // -------------------- Tcp setup -------------------- diff --git a/java/org/apache/tomcat/util/net/NioChannel.java b/java/org/apache/tomcat/util/net/NioChannel.java index ba90442b6..aba04da39 100644 --- a/java/org/apache/tomcat/util/net/NioChannel.java +++ b/java/org/apache/tomcat/util/net/NioChannel.java @@ -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; + } + } diff --git a/java/org/apache/tomcat/util/net/NioEndpoint.java b/java/org/apache/tomcat/util/net/NioEndpoint.java index ff125185b..9423b9c29 100644 --- a/java/org/apache/tomcat/util/net/NioEndpoint.java +++ b/java/org/apache/tomcat/util/net/NioEndpoint.java @@ -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; } diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java index 852996266..8f252039f 100644 --- a/java/org/apache/tomcat/util/net/SecureNioChannel.java +++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java @@ -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 -- 2.11.0