public AprSocketWrapper(Long socket, AprEndpoint endpoint) { super(socket, endpoint); // TODO Make the socketWriteBuffer size configurable and align the // SSL and app buffer size settings with NIO & NIO2. if (endpoint.isSSLEnabled()) { sslOutputBuffer = ByteBuffer.allocateDirect(SSL_OUTPUT_BUFFER_SIZE); sslOutputBuffer.position(SSL_OUTPUT_BUFFER_SIZE); } else { sslOutputBuffer = null; } socketBufferHandler = new SocketBufferHandler(6 * 1500, 6 * 1500, true); }
@Override public boolean isReadyForRead() throws IOException { socketBufferHandler.configureReadBufferForRead(); if (socketBufferHandler.getReadBuffer().remaining() > 0) { return true; } fillReadBuffer(false); boolean isReady = socketBufferHandler.getReadBuffer().position() > 0; return isReady; }
/** * Return input that has been read to the input buffer for re-reading by the * correct component. There are times when a component may read more data * than it needs before it passes control to another component. One example * of this is during HTTP upgrade. If an (arguably misbehaving client) sends * data associated with the upgraded protocol before the HTTP upgrade * completes, the HTTP handler may read it. This method provides a way for * that data to be returned so it can be processed by the correct component. * * @param returnedInput The input to return to the input buffer. */ public void unRead(ByteBuffer returnedInput) { if (returnedInput != null) { socketBufferHandler.configureReadBufferForWrite(); socketBufferHandler.getReadBuffer().put(returnedInput); } }
/** * Write the contents of the socketWriteBuffer to the socket. For blocking * writes either then entire contents of the buffer will be written or an * IOException will be thrown. Partial blocking writes will not occur. * * @param block Should the write be blocking or not? * * @throws IOException If an I/O error such as a timeout occurs during the * write */ protected void doWrite(boolean block) throws IOException { socketBufferHandler.configureWriteBufferForRead(); doWrite(block, socketBufferHandler.getWriteBuffer()); }
/** * Separate method so it can be re-used by the socket write buffer to write * data to the network * * @param from The ByteBuffer containing the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeNonBlockingInternal(ByteBuffer from) throws IOException { if (socketBufferHandler.isWriteBufferEmpty()) { writeNonBlockingDirect(from); } else { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); if (!socketBufferHandler.isWriteBufferWritable()) { doWrite(false); if (socketBufferHandler.isWriteBufferWritable()) { writeNonBlockingDirect(from); } } } }
/** * Writes the provided data to the socket write buffer. If the socket write * buffer fills during the write, the content of the socket write buffer is * written to the network using a blocking write. Once that blocking write * is complete, this method starts to fill the socket write buffer again. * Depending on the size of the data to write, there may be multiple writes * to the network. On completion of this method there will always be space * remaining in the socket write buffer. * * @param buf The byte array containing the data to be written * @param off The offset within the byte array of the data to be written * @param len The length of the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeBlocking(byte[] buf, int off, int len) throws IOException { socketBufferHandler.configureWriteBufferForWrite(); int thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); while (socketBufferHandler.getWriteBuffer().remaining() == 0) { len = len - thisTime; off = off + thisTime; doWrite(true); socketBufferHandler.configureWriteBufferForWrite(); thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); } }
getSocket().getBufHandler().configureWriteBufferForWrite(); ByteBuffer buffer = getSocket().getBufHandler().getWriteBuffer(); int nRead = -1; try { getSocket().getBufHandler().configureWriteBufferForRead(); Nio2Endpoint.startInline(); getSocket().write(buffer, toNio2Timeout(getWriteTimeout()), TimeUnit.MILLISECONDS,
if (nonBlockingWriteBuffer.isEmpty() && socketBufferHandler.isWriteBufferWritable()) { socketBufferHandler.configureWriteBufferForWrite(); int thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); len = len - thisTime; while (!socketBufferHandler.isWriteBufferWritable()) { off = off + thisTime; doWrite(false); if (len > 0 && socketBufferHandler.isWriteBufferWritable()) { socketBufferHandler.configureWriteBufferForWrite(); thisTime = transfer(buf, off, len, socketBufferHandler.getWriteBuffer()); } else {
if (!getBufHandler().isReadBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appInputNotEmpty")); if (!getBufHandler().isWriteBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appOutputNotEmpty")); netInBuffer.position(0); netInBuffer.limit(0); getBufHandler().reset();
if (dst == getBufHandler().getReadBuffer()) { .expand(sslEngine.getSession().getApplicationBufferSize()); dst = getBufHandler().getReadBuffer(); } else if (dst == getAppReadBufHandler().getByteBuffer()) { getAppReadBufHandler()
Nio2Endpoint.startInline(); long nBytes = 0; if (!socketBufferHandler.isReadBufferEmpty()) { socketBufferHandler.configureReadBufferForRead(); for (int i = 0; i < length && !socketBufferHandler.isReadBufferEmpty(); i++) { nBytes += transfer(socketBufferHandler.getReadBuffer(), dsts[offset + i]);
public void expand(int newSize) { configureReadBufferForWrite(); readBuffer = ByteBufferUtils.expand(readBuffer, newSize); configureWriteBufferForWrite(); writeBuffer = ByteBufferUtils.expand(writeBuffer, newSize); }
if (!getBufHandler().isReadBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appInputNotEmpty")); if (!getBufHandler().isWriteBufferEmpty()) throw new IOException(sm.getString("channel.nio.ssl.appOutputNotEmpty")); handshakeComplete = false; boolean isReadable = false;
void init(SocketWrapperBase<?> socketWrapper) { wrapper = socketWrapper; wrapper.setAppReadBufHandler(this); int bufLength = headerBufferSize + wrapper.getSocketBufferHandler().getReadBuffer().capacity(); if (byteBuffer == null || byteBuffer.capacity() < bufLength) { byteBuffer = ByteBuffer.allocate(bufLength); byteBuffer.position(0).limit(0); } }
Http2AsyncParser(String connectionId, Input input, Output output, SocketWrapperBase<?> socketWrapper, Http2AsyncUpgradeHandler upgradeHandler) { super(connectionId, input, output); this.socketWrapper = socketWrapper; socketWrapper.getSocketBufferHandler().expand(input.getMaxFrameSize()); this.upgradeHandler = upgradeHandler; header = ByteBuffer.allocate(9); framePaylod = ByteBuffer.allocate(input.getMaxFrameSize()); }
/** * Free the channel memory */ public void free() { bufHandler.free(); }
@Override public boolean isReadyForRead() throws IOException { synchronized (readCompletionHandler) { if (!readPending.tryAcquire()) { readInterest = true; return false; } if (!socketBufferHandler.isReadBufferEmpty()) { readPending.release(); return true; } int nRead = fillReadBuffer(false); boolean isReady = nRead > 0; if (!isReady) { readInterest = true; } return isReady; } }
if (socketBufferHandler.isWriteBufferEmpty()) { } else { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); if (!socketBufferHandler.isWriteBufferWritable()) { doWrite(true); writeBlockingDirect(from);
/** * Writes directly to the network, bypassing the socket write buffer. * * @param from The ByteBuffer containing the data to be written * * @throws IOException If an IO error occurs during the write */ protected void writeBlockingDirect(ByteBuffer from) throws IOException { // The socket write buffer capacity is socket.appWriteBufSize // TODO This only matters when using TLS. For non-TLS connections it // should be possible to write the ByteBuffer in a single write int limit = socketBufferHandler.getWriteBuffer().capacity(); int fromLimit = from.limit(); while (from.remaining() >= limit) { from.limit(from.position() + limit); doWrite(true, from); from.limit(fromLimit); } if (from.remaining() > 0) { socketBufferHandler.configureWriteBufferForWrite(); transfer(from, socketBufferHandler.getWriteBuffer()); } }
ByteBuffer buffer = getSocket().getBufHandler().getWriteBuffer(); if (!buffer.hasRemaining()) { if (attachment.length <= 0) { getSocket().getBufHandler().configureWriteBufferForWrite(); int nRead = -1; try { getSocket().getBufHandler().configureWriteBufferForRead(); if (attachment.length < buffer.remaining()) { buffer.limit(buffer.limit() - buffer.remaining() + (int) attachment.length);