use of io.undertow.util.ImmediatePooledByteBuffer in project undertow by undertow-io.
the class Http2PingStreamSinkChannel method createFrameHeader.
@Override
protected SendFrameHeader createFrameHeader() {
ByteBuffer buf = ByteBuffer.allocate(17);
Http2ProtocolUtils.putInt(buf, HEADER);
buf.put((byte) (ack ? Http2Channel.PING_FLAG_ACK : 0));
//stream id, must be zero
Http2ProtocolUtils.putInt(buf, 0);
for (int i = 0; i < PING_FRAME_LENGTH; ++i) {
buf.put(data[i]);
}
buf.flip();
return new SendFrameHeader(new ImmediatePooledByteBuffer(buf));
}
use of io.undertow.util.ImmediatePooledByteBuffer in project undertow by undertow-io.
the class Http2RstStreamSinkChannel method createFrameHeader.
@Override
protected SendFrameHeader createFrameHeader() {
ByteBuffer buf = ByteBuffer.allocate(13);
Http2ProtocolUtils.putInt(buf, HEADER_FIRST_LINE);
buf.put((byte) 0);
Http2ProtocolUtils.putInt(buf, streamId);
Http2ProtocolUtils.putInt(buf, errorCode);
buf.flip();
return new SendFrameHeader(new ImmediatePooledByteBuffer(buf));
}
use of io.undertow.util.ImmediatePooledByteBuffer in project undertow by undertow-io.
the class Http2WindowUpdateStreamSinkChannel method createFrameHeader.
@Override
protected SendFrameHeader createFrameHeader() {
ByteBuffer buf = ByteBuffer.allocate(13);
Http2ProtocolUtils.putInt(buf, HEADER_FIRST_LINE);
buf.put((byte) 0);
Http2ProtocolUtils.putInt(buf, streamId);
Http2ProtocolUtils.putInt(buf, deltaWindowSize);
buf.flip();
return new SendFrameHeader(new ImmediatePooledByteBuffer(buf));
}
use of io.undertow.util.ImmediatePooledByteBuffer in project undertow by undertow-io.
the class AjpServerRequestConduit method doRead.
private int doRead(final ByteBuffer dst, long state) throws IOException {
ByteBuffer headerBuffer = this.headerBuffer;
long headerRead = HEADER_LENGTH - headerBuffer.remaining();
long remaining = this.remaining;
if (remaining == 0) {
this.state = STATE_FINISHED;
if (finishListener != null) {
finishListener.handleEvent(this);
}
return -1;
}
long chunkRemaining;
if (headerRead != HEADER_LENGTH) {
int read = next.read(headerBuffer);
if (read == -1) {
this.state = STATE_FINISHED;
if (finishListener != null) {
finishListener.handleEvent(this);
}
throw new ClosedChannelException();
} else if (headerBuffer.hasRemaining()) {
if (headerBuffer.remaining() <= 2) {
//mod_jk can send 12 34 00 00 rather than 12 34 00 02 00 00
//0x12
byte b1 = headerBuffer.get(0);
//0x34
byte b2 = headerBuffer.get(1);
if (b1 != 0x12 || b2 != 0x34) {
throw UndertowMessages.MESSAGES.wrongMagicNumber((b1 & 0xFF) << 8 | (b2 & 0xFF));
}
//the length headers, two more than the string length header
b1 = headerBuffer.get(2);
b2 = headerBuffer.get(3);
int totalSize = ((b1 & 0xFF) << 8) | (b2 & 0xFF);
if (totalSize == 0) {
if (headerBuffer.remaining() < 2) {
byte[] data = new byte[1];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(headerBuffer.get(4));
bb.flip();
Connectors.ungetRequestBytes(exchange, new ImmediatePooledByteBuffer(bb));
}
this.remaining = 0;
this.state = STATE_FINISHED;
if (finishListener != null) {
finishListener.handleEvent(this);
}
return -1;
}
}
return 0;
} else {
headerBuffer.flip();
//0x12
byte b1 = headerBuffer.get();
//0x34
byte b2 = headerBuffer.get();
if (b1 != 0x12 || b2 != 0x34) {
throw UndertowMessages.MESSAGES.wrongMagicNumber((b1 & 0xFF) << 8 | (b2 & 0xFF));
}
//the length headers, two more than the string length header
b1 = headerBuffer.get();
b2 = headerBuffer.get();
int totalSize = ((b1 & 0xFF) << 8) | (b2 & 0xFF);
if (totalSize == 0) {
byte[] data = new byte[2];
ByteBuffer bb = ByteBuffer.wrap(data);
bb.put(headerBuffer);
bb.flip();
Connectors.ungetRequestBytes(exchange, new ImmediatePooledByteBuffer(bb));
this.remaining = 0;
this.state = STATE_FINISHED;
if (finishListener != null) {
finishListener.handleEvent(this);
}
return -1;
}
b1 = headerBuffer.get();
b2 = headerBuffer.get();
chunkRemaining = ((b1 & 0xFF) << 8) | (b2 & 0xFF);
if (chunkRemaining == 0) {
this.remaining = 0;
this.state = STATE_FINISHED;
if (finishListener != null) {
finishListener.handleEvent(this);
}
return -1;
}
}
} else {
chunkRemaining = this.state & STATE_MASK;
}
int limit = dst.limit();
try {
if (dst.remaining() > chunkRemaining) {
dst.limit((int) (dst.position() + chunkRemaining));
}
int read = next.read(dst);
chunkRemaining -= read;
if (remaining != -1) {
remaining -= read;
}
this.totalRead += read;
if (remaining != 0) {
if (chunkRemaining == 0) {
headerBuffer.clear();
this.state = STATE_SEND_REQUIRED;
} else {
this.state = (state & ~STATE_MASK) | chunkRemaining;
}
}
return read;
} finally {
this.remaining = remaining;
dst.limit(limit);
final long maxEntitySize = exchange.getMaxEntitySize();
if (maxEntitySize > 0) {
if (totalRead > maxEntitySize) {
//kill the connection, nothing else can be sent on it
terminateReads();
exchange.setPersistent(false);
throw UndertowMessages.MESSAGES.requestEntityWasTooLarge(maxEntitySize);
}
}
}
}
use of io.undertow.util.ImmediatePooledByteBuffer in project undertow by undertow-io.
the class HttpServerConnection method ungetRequestBytes.
/**
* Pushes back the given data. This should only be used by transfer coding handlers that have read past
* the end of the request when handling pipelined requests
*
* @param unget The buffer to push back
*/
public void ungetRequestBytes(final PooledByteBuffer unget) {
if (getExtraBytes() == null) {
setExtraBytes(unget);
} else {
PooledByteBuffer eb = getExtraBytes();
ByteBuffer buf = eb.getBuffer();
final ByteBuffer ugBuffer = unget.getBuffer();
if (ugBuffer.limit() - ugBuffer.remaining() > buf.remaining()) {
//stuff the existing data after the data we are ungetting
ugBuffer.compact();
ugBuffer.put(buf);
ugBuffer.flip();
eb.close();
setExtraBytes(unget);
} else {
//TODO: this is horrible, but should not happen often
final byte[] data = new byte[ugBuffer.remaining() + buf.remaining()];
int first = ugBuffer.remaining();
ugBuffer.get(data, 0, ugBuffer.remaining());
buf.get(data, first, buf.remaining());
eb.close();
unget.close();
final ByteBuffer newBuffer = ByteBuffer.wrap(data);
setExtraBytes(new ImmediatePooledByteBuffer(newBuffer));
}
}
if (channel.getSourceChannel().isReadResumed()) {
channel.getSourceChannel().wakeupReads();
}
}
Aggregations