protected ApplicationBufferHandler bufHandler;
protected Poller poller;
+
+ protected boolean sendFile = false;
public NioChannel(SocketChannel channel, ApplicationBufferHandler bufHandler) throws IOException {
this.sc = channel;
public void reset() throws IOException {
bufHandler.getReadBuffer().clear();
bufHandler.getWriteBuffer().clear();
+ this.sendFile = false;
}
public int getBufferSize() {
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;
+ }
+
}
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;
}
public void setUseSendfile(boolean useSendfile) {
-
this.useSendfile = useSendfile;
}
}
public boolean getUseSendfile() {
- //send file doesn't work with SSL
- return useSendfile && (!isSSLEnabled());
+ return useSendfile;
}
public int getOomParachute() {
} 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
}
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();
}
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);
}
log.error("",t);
cancelledKey(sk, SocketStatus.ERROR, false);
return false;
+ }finally {
+ if (sc!=null) sc.setSendFile(false);
}
return true;
}
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.");
}
}
+ @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