Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.EOFException;
import java.io.IOException;
import java.nio.ByteBuffer;
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 UpgradeNioProcessor extends UpgradeProcessor {
private final NioChannel nioChannel;
private final NioSelectorPool pool;
private final int maxRead;
private final int maxWrite;
public UpgradeNioProcessor(SocketWrapper wrapper,
UpgradeInbound upgradeInbound, NioSelectorPool pool) {
super(upgradeInbound);
wrapper.setTimeout(upgradeInbound.getReadTimeout());
this.nioChannel = wrapper.getSocket();
this.pool = pool;
this.maxRead = nioChannel.getBufHandler().getReadBuffer().capacity();
this.maxWrite = nioChannel.getBufHandler().getWriteBuffer().capacity();
}
/*
* Output methods
*/
@Override
public void flush() 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);
}
}
}
@Override
public void write(int b) throws IOException {
writeToSocket(new byte[] {(byte) b}, 0, 1);
}
@Override
public void write(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);
}
/*
* Input methods
*/
@Override
public int read() throws IOException {
byte[] bytes = new byte[1];
int result = readSocket(true, bytes, 0, 1);
if (result == -1) {
return -1;
} else {
return bytes[0] & 0xFF;
}
}
@Override
public int read(boolean block, byte[] bytes, int off, int len)
throws IOException {
if (len > maxRead) {
return readSocket(block, bytes, off, maxRead);
} else {
return readSocket(block, bytes, off, len);
}
}
/*
* Adapted from the NioInputBuffer.
*/
private int readSocket(boolean block, byte[] bytes, int offset, int len)
throws IOException {
ByteBuffer readBuffer = nioChannel.getBufHandler().getReadBuffer();
int remaining = readBuffer.remaining();
// Is there enough data in the read buffer to satisfy this request?
if (remaining >= len) {
readBuffer.get(bytes, offset, len);
return len;
}
// Copy what data there is in the read buffer to the byte array
int leftToWrite = len;
int newOffset = offset;
if (remaining > 0) {
readBuffer.get(bytes, offset, remaining);
leftToWrite -= remaining;
newOffset += remaining;
}
// Fill the read buffer as best we can
readBuffer.clear();
int nRead = fillReadBuffer(block);
// Full as much of the remaining byte array as possible with the data
// that was just read
if (nRead > 0) {
readBuffer.flip();
readBuffer.limit(nRead);
if (nRead > leftToWrite) {
readBuffer.get(bytes, newOffset, leftToWrite);
leftToWrite = 0;
} else {
readBuffer.get(bytes, newOffset, nRead);
leftToWrite -= nRead;
}
} else if (nRead == 0) {
readBuffer.flip();
readBuffer.limit(nRead);
} else if (nRead == -1) {
throw new EOFException(sm.getString("nio.eof.error"));
}
return len - leftToWrite;
}
private int fillReadBuffer(boolean block) throws IOException {
int nRead;
if (block) {
Selector selector = null;
try {
selector = pool.get();
} catch ( IOException x ) {
// Ignore
}
try {
NioEndpoint.KeyAttachment att =
(NioEndpoint.KeyAttachment) nioChannel.getAttachment(false);
if (att == null) {
throw new IOException("Key must be cancelled.");
}
nRead = pool.read(nioChannel.getBufHandler().getReadBuffer(),
nioChannel, selector, att.getTimeout());
} catch (EOFException eof) {
nRead = -1;
} finally {
if (selector != null) {
pool.put(selector);
}
}
} else {
nRead = nioChannel.read(nioChannel.getBufHandler().getReadBuffer());
}
return nRead;
}
/*
* 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;
}
}