Author: markt Date: Sat Nov 24 18:45:42 2012 New Revision: 1413233 URL: http://svn.apache.org/viewvc?rev=1413233&view=rev Log: Refactor ServletOutputStream - BIO untested - NIO untested - APR not implemented
Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletOutputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletOutputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletOutputStream.java Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprProcessor.java Sat Nov 24 18:45:42 2012 @@ -16,8 +16,6 @@ */ package org.apache.coyote.http11.upgrade; -import java.io.IOException; - import javax.servlet.http.ProtocolHandler; import org.apache.tomcat.jni.Socket; @@ -31,36 +29,8 @@ public class UpgradeAprProcessor extends ProtocolHandler httpUpgradeProcessor) { super(httpUpgradeProcessor, new UpgradeAprServletInputStream(wrapper), - new AprUpgradeServletOutputStream(wrapper.getSocket().longValue())); + new UpgradeAprServletOutputStream(wrapper)); Socket.timeoutSet(wrapper.getSocket().longValue(), INFINITE_TIMEOUT); } - - - // ----------------------------------------------------------- Inner classes - - private static class AprUpgradeServletOutputStream - extends UpgradeServletOutputStream { - - private final long socket; - - public AprUpgradeServletOutputStream(long socket) { - this.socket = socket; - } - - @Override - protected void doWrite(int b) throws IOException { - Socket.send(socket, new byte[] {(byte) b}, 0, 1); - } - - @Override - protected void doWrite(byte[] b, int off, int len) throws IOException { - Socket.send(socket, b, off, len); - } - - @Override - protected void doFlush() throws IOException { - // NO-OP - } - } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletInputStream.java Sat Nov 24 18:45:42 2012 @@ -24,6 +24,7 @@ public class UpgradeAprServletInputStrea private final long socket; + public UpgradeAprServletInputStream(SocketWrapper<Long> wrapper) { this.socket = wrapper.getSocket().longValue(); } Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletOutputStream.java?rev=1413233&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletOutputStream.java (added) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeAprServletOutputStream.java Sat Nov 24 18:45:42 2012 @@ -0,0 +1,44 @@ +/* + * 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.coyote.http11.upgrade; + +import java.io.IOException; + +import org.apache.tomcat.util.net.SocketWrapper; + +public class UpgradeAprServletOutputStream extends UpgradeServletOutputStream { + + private final long socket; + + + public UpgradeAprServletOutputStream(SocketWrapper<Long> wrapper) { + this.socket = wrapper.getSocket().longValue(); + } + + + @Override + protected int doWrite(boolean block, byte[] b, int off, int len) + throws IOException { + // TODO Auto-generated method stub + return 0; + } + + @Override + protected void doFlush() throws IOException { + // TODO Auto-generated method stub + } +} Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioProcessor.java Sat Nov 24 18:45:42 2012 @@ -17,7 +17,6 @@ package org.apache.coyote.http11.upgrade; import java.io.IOException; -import java.io.OutputStream; import java.net.Socket; import javax.servlet.http.ProtocolHandler; @@ -31,37 +30,8 @@ public class UpgradeBioProcessor extends public UpgradeBioProcessor(SocketWrapper<Socket> wrapper, ProtocolHandler httpUpgradeProcessor) throws IOException { super(httpUpgradeProcessor, new UpgradeBioServletInputStream(wrapper), - new BioUpgradeServletOutputStream(wrapper)); + new UpgradeBioServletOutputStream(wrapper)); wrapper.getSocket().setSoTimeout(INFINITE_TIMEOUT); } - - - // ----------------------------------------------------------- Inner classes - - private static class BioUpgradeServletOutputStream - extends UpgradeServletOutputStream { - - private final OutputStream os; - - public BioUpgradeServletOutputStream(SocketWrapper<Socket> wrapper) - throws IOException { - os = wrapper.getSocket().getOutputStream(); - } - - @Override - protected void doWrite(int b) throws IOException { - os.write(b); - } - - @Override - protected void doWrite(byte[] b, int off, int len) throws IOException { - os.write(b, off, len); - } - - @Override - protected void doFlush() throws IOException { - os.flush(); - } - } } Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletOutputStream.java?rev=1413233&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletOutputStream.java (added) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeBioServletOutputStream.java Sat Nov 24 18:45:42 2012 @@ -0,0 +1,45 @@ +/* + * 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.coyote.http11.upgrade; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.Socket; + +import org.apache.tomcat.util.net.SocketWrapper; + +public class UpgradeBioServletOutputStream extends UpgradeServletOutputStream { + + private final OutputStream os; + + public UpgradeBioServletOutputStream(SocketWrapper<Socket> wrapper) + throws IOException { + os = wrapper.getSocket().getOutputStream(); + } + + @Override + protected int doWrite(boolean block, byte[] b, int off, int len) + throws IOException { + os.write(b, off, len); + return len; + } + + @Override + protected void doFlush() throws IOException { + os.flush(); + } +} Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioProcessor.java Sat Nov 24 18:45:42 2012 @@ -16,13 +16,9 @@ */ package org.apache.coyote.http11.upgrade; -import java.io.IOException; -import java.nio.channels.Selector; - import javax.servlet.http.ProtocolHandler; import org.apache.tomcat.util.net.NioChannel; -import org.apache.tomcat.util.net.NioEndpoint; import org.apache.tomcat.util.net.NioSelectorPool; import org.apache.tomcat.util.net.SocketWrapper; @@ -34,101 +30,8 @@ public class UpgradeNioProcessor extends ProtocolHandler httpUpgradeProcessor, NioSelectorPool pool) { super(httpUpgradeProcessor, new UpgradeNioServletInputStream(wrapper, pool), - new NioUpgradeServletOutputStream(wrapper, pool)); + new UpgradeNioServletOutputStream(wrapper, pool)); wrapper.setTimeout(INFINITE_TIMEOUT); } - - - // ----------------------------------------------------------- Inner classes - - private static class NioUpgradeServletOutputStream - extends UpgradeServletOutputStream { - - private final NioChannel nioChannel; - private final NioSelectorPool pool; - private final int maxWrite; - - public NioUpgradeServletOutputStream( - SocketWrapper<NioChannel> wrapper, NioSelectorPool pool) { - nioChannel = wrapper.getSocket(); - this.pool = pool; - maxWrite = nioChannel.getBufHandler().getWriteBuffer().capacity(); - } - - @Override - protected void doWrite(int b) throws IOException { - writeToSocket(new byte[] {(byte) b}, 0, 1); - } - - @Override - protected void doWrite(byte[] b, int off, int len) throws IOException { - int written = 0; - while (len - written > maxWrite) { - written += writeToSocket(b, off + written, maxWrite); - } - writeToSocket(b, off + written, len - written); - } - - @Override - protected void doFlush() throws IOException { - NioEndpoint.KeyAttachment att = - (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false); - if (att == null) { - throw new IOException("Key must be cancelled"); - } - long writeTimeout = att.getTimeout(); - Selector selector = null; - try { - selector = pool.get(); - } catch ( IOException x ) { - //ignore - } - try { - do { - if (nioChannel.flush(true, selector, writeTimeout)) { - break; - } - } while (true); - } finally { - if (selector != null) { - pool.put(selector); - } - } - } - - /* - * Adapted from the NioOutputBuffer - */ - private synchronized int writeToSocket(byte[] bytes, int off, int len) - throws IOException { - - nioChannel.getBufHandler().getWriteBuffer().clear(); - nioChannel.getBufHandler().getWriteBuffer().put(bytes, off, len); - nioChannel.getBufHandler().getWriteBuffer().flip(); - - int written = 0; - NioEndpoint.KeyAttachment att = - (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false); - if (att == null) { - throw new IOException("Key must be cancelled"); - } - long writeTimeout = att.getTimeout(); - Selector selector = null; - try { - selector = pool.get(); - } catch ( IOException x ) { - //ignore - } - try { - written = pool.write(nioChannel.getBufHandler().getWriteBuffer(), - nioChannel, selector, writeTimeout, true); - } finally { - if (selector != null) { - pool.put(selector); - } - } - return written; - } - } } Added: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletOutputStream.java?rev=1413233&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletOutputStream.java (added) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeNioServletOutputStream.java Sat Nov 24 18:45:42 2012 @@ -0,0 +1,128 @@ +/* + * 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.coyote.http11.upgrade; + +import java.io.IOException; +import java.nio.channels.Selector; + +import org.apache.tomcat.util.net.NioChannel; +import org.apache.tomcat.util.net.NioEndpoint; +import org.apache.tomcat.util.net.NioSelectorPool; +import org.apache.tomcat.util.net.SocketWrapper; + +public class UpgradeNioServletOutputStream extends UpgradeServletOutputStream { + + private final NioChannel nioChannel; + private final NioSelectorPool pool; + private final int maxWrite; + + + public UpgradeNioServletOutputStream( + SocketWrapper<NioChannel> wrapper, NioSelectorPool pool) { + nioChannel = wrapper.getSocket(); + this.pool = pool; + maxWrite = nioChannel.getBufHandler().getWriteBuffer().capacity(); + } + + + @Override + protected int doWrite(boolean block, byte[] b, int off, int len) + throws IOException { + int leftToWrite = len; + int count = 0; + int offset = off; + + while (leftToWrite > 0) { + int writeThisLoop; + int writtenThisLoop; + + if (leftToWrite > maxWrite) { + writeThisLoop = maxWrite; + } else { + writeThisLoop = leftToWrite; + } + + writtenThisLoop = doWriteInternal(block, b, offset, writeThisLoop); + count += writtenThisLoop; + leftToWrite -= writtenThisLoop; + + if (writtenThisLoop < writeThisLoop) { + break; + } + } + + return count; + } + + private int doWriteInternal (boolean block, byte[] b, int off, int len) + throws IOException { + nioChannel.getBufHandler().getWriteBuffer().clear(); + nioChannel.getBufHandler().getWriteBuffer().put(b, off, len); + nioChannel.getBufHandler().getWriteBuffer().flip(); + + int written = 0; + NioEndpoint.KeyAttachment att = + (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false); + if (att == null) { + throw new IOException("Key must be cancelled"); + } + long writeTimeout = att.getTimeout(); + Selector selector = null; + try { + selector = pool.get(); + } catch ( IOException x ) { + //ignore + } + try { + written = pool.write(nioChannel.getBufHandler().getWriteBuffer(), + nioChannel, selector, writeTimeout, block); + } finally { + if (selector != null) { + pool.put(selector); + } + } + return written; + } + + + @Override + protected void doFlush() throws IOException { + NioEndpoint.KeyAttachment att = + (NioEndpoint.KeyAttachment) nioChannel.getAttachment(false); + if (att == null) { + throw new IOException("Key must be cancelled"); + } + long writeTimeout = att.getTimeout(); + Selector selector = null; + try { + selector = pool.get(); + } catch ( IOException x ) { + //ignore + } + try { + do { + if (nioChannel.flush(true, selector, writeTimeout)) { + break; + } + } while (true); + } finally { + if (selector != null) { + pool.put(selector); + } + } + } +} Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeProcessor.java Sat Nov 24 18:45:42 2012 @@ -21,7 +21,6 @@ import java.util.concurrent.Executor; import javax.servlet.ServletInputStream; import javax.servlet.ServletOutputStream; -import javax.servlet.WriteListener; import javax.servlet.http.ProtocolHandler; import javax.servlet.http.WebConnection; @@ -85,7 +84,7 @@ public abstract class UpgradeProcessor<S if (status == SocketStatus.OPEN_READ) { upgradeServletInputStream.onDataAvailable(); } else if (status == SocketStatus.OPEN_WRITE) { - upgradeServletOutputStream.writeListener.onWritePossible(); + upgradeServletOutputStream.onWritePossible(); } else { // Unexpected state return SocketState.CLOSED; @@ -146,53 +145,4 @@ public abstract class UpgradeProcessor<S public final void setSslSupport(SSLSupport sslSupport) { // NOOP } - - - // ----------------------------------------------------------- Inner classes - - protected abstract static class UpgradeServletOutputStream extends - ServletOutputStream { - - private volatile WriteListener writeListener = null; - - @Override - public boolean canWrite() { - if (writeListener == null) { - throw new IllegalStateException( - sm.getString("upgrade.sos.canWrite.ise")); - } - - // TODO Support non-blocking IO - return false; - } - - @Override - public void setWriteListener(WriteListener listener) { - if (listener == null) { - throw new NullPointerException( - sm.getString("upgrade.sos.writeListener.null")); - } - this.writeListener = listener; - } - - @Override - public void write(int b) throws IOException { - doWrite(b); - } - - @Override - public void write(byte[] b, int off, int len) throws IOException { - doWrite(b, off, len); - } - - @Override - public void flush() throws IOException { - doFlush(); - } - - protected abstract void doWrite(int b) throws IOException; - protected abstract void doWrite(byte[] b, int off, int len) - throws IOException; - protected abstract void doFlush() throws IOException; - } } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletInputStream.java Sat Nov 24 18:45:42 2012 @@ -76,27 +76,19 @@ public abstract class UpgradeServletInpu public int readLine(byte[] b, int off, int len) throws IOException { preReadChecks(); - if (len == 0) { + if (len <= 0) { return 0; } + int count = 0, c; - int r; - int pos = off; - int count = 0; - - while ((r = readInternal()) != -1) { - b[pos++] = (byte) r; - count ++; - if (r == -1 || count == len) { + while ((c = readInternal()) != -1) { + b[off++] = (byte) c; + count++; + if (c == '\n' || count == len) { break; } } - - if (r == -1) { - return -1; - } else { - return count; - } + return count > 0 ? count : -1; } @@ -143,8 +135,8 @@ public abstract class UpgradeServletInpu } + protected abstract boolean doIsReady() throws IOException; + protected abstract int doRead(boolean block, byte[] b, int off, int len) throws IOException; - - protected abstract boolean doIsReady() throws IOException; } Modified: tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java?rev=1413233&r1=1413232&r2=1413233&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/upgrade/UpgradeServletOutputStream.java Sat Nov 24 18:45:42 2012 @@ -24,23 +24,12 @@ import javax.servlet.WriteListener; public abstract class UpgradeServletOutputStream extends ServletOutputStream { // Start in blocking-mode - private volatile Boolean writeable = null; private volatile WriteListener listener = null; private byte[] buffer; @Override public boolean canWrite() { - // If we already know the current state, return it. - if (writeable != null) { - return writeable.booleanValue(); - } - - try { - writeable = Boolean.valueOf(doCanWrite()); - } catch (IOException e) { - listener.onError(e); - } - return writeable.booleanValue(); + return buffer == null; } @Override @@ -50,8 +39,6 @@ public abstract class UpgradeServletOutp throw new IllegalArgumentException(); } this.listener = listener; - // Switching to non-blocking. Don't know if data is available. - writeable = null; } @Override @@ -71,12 +58,10 @@ public abstract class UpgradeServletOutp private void preWriteChecks() { - if (writeable == null || !writeable.booleanValue()) { + if (buffer != null) { // TODO i18n throw new IllegalStateException(); } - // No longer know if data is available - writeable = null; } @@ -106,14 +91,12 @@ public abstract class UpgradeServletOutp throw new RuntimeException(ioe); } if (buffer == null) { - writeable = Boolean.TRUE; listener.onWritePossible(); } } - protected abstract int doWrite(boolean block, byte[] b, int off, int len) throws IOException; - protected abstract boolean doCanWrite() throws IOException; + protected abstract void doFlush() throws IOException; } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org