use of java.nio.ByteBuffer in project jetty.project by eclipse.
the class HttpReceiver method responseContent.
/**
* Method to be invoked when response HTTP content is available.
* <p>
* This method takes case of decoding the content, if necessary, and notifying {@link org.eclipse.jetty.client.api.Response.ContentListener}s.
*
* @param exchange the HTTP exchange
* @param buffer the response HTTP content buffer
* @param callback the callback
* @return whether the processing should continue
*/
protected boolean responseContent(HttpExchange exchange, ByteBuffer buffer, final Callback callback) {
out: while (true) {
ResponseState current = responseState.get();
switch(current) {
case HEADERS:
case CONTENT:
{
if (updateResponseState(current, ResponseState.TRANSIENT))
break out;
break;
}
default:
{
callback.failed(new IllegalStateException("Invalid response state " + current));
return false;
}
}
}
HttpResponse response = exchange.getResponse();
if (LOG.isDebugEnabled())
LOG.debug("Response content {}{}{}", response, System.lineSeparator(), BufferUtil.toDetailString(buffer));
ResponseNotifier notifier = getHttpDestination().getResponseNotifier();
List<Response.ResponseListener> listeners = exchange.getConversation().getResponseListeners();
ContentDecoder decoder = this.decoder;
if (decoder == null) {
notifier.notifyContent(listeners, response, buffer, callback);
} else {
try {
List<ByteBuffer> decodeds = new ArrayList<>(2);
while (buffer.hasRemaining()) {
ByteBuffer decoded = decoder.decode(buffer);
if (!decoded.hasRemaining())
continue;
decodeds.add(decoded);
if (LOG.isDebugEnabled())
LOG.debug("Response content decoded ({}) {}{}{}", decoder, response, System.lineSeparator(), BufferUtil.toDetailString(decoded));
}
if (decodeds.isEmpty()) {
callback.succeeded();
} else {
int size = decodeds.size();
CountingCallback counter = new CountingCallback(callback, size);
for (int i = 0; i < size; ++i) notifier.notifyContent(listeners, response, decodeds.get(i), counter);
}
} catch (Throwable x) {
callback.failed(x);
}
}
if (updateResponseState(ResponseState.TRANSIENT, ResponseState.CONTENT))
return true;
terminateResponse(exchange);
return false;
}
use of java.nio.ByteBuffer in project jetty.project by eclipse.
the class ALPNNegotiationTest method testAbruptCloseDuringHandshake.
@Test
public void testAbruptCloseDuringHandshake() throws Exception {
InetSocketAddress address = prepare();
SslContextFactory sslContextFactory = newSslContextFactory();
sslContextFactory.start();
SSLEngine sslEngine = sslContextFactory.newSSLEngine(address);
sslEngine.setUseClientMode(true);
ALPN.put(sslEngine, new ALPN.ClientProvider() {
@Override
public void unsupported() {
}
@Override
public List<String> protocols() {
return Arrays.asList("h2");
}
@Override
public void selected(String s) {
}
});
sslEngine.beginHandshake();
ByteBuffer encrypted = ByteBuffer.allocate(sslEngine.getSession().getPacketBufferSize());
sslEngine.wrap(BufferUtil.EMPTY_BUFFER, encrypted);
encrypted.flip();
try (SocketChannel channel = SocketChannel.open(address)) {
// Send ClientHello, immediately followed by FIN (no TLS Close Alert)
channel.write(encrypted);
channel.shutdownOutput();
// Read ServerHello from server
encrypted.clear();
int read = channel.read(encrypted);
encrypted.flip();
Assert.assertTrue(read > 0);
ByteBuffer decrypted = ByteBuffer.allocate(sslEngine.getSession().getApplicationBufferSize());
sslEngine.unwrap(encrypted, decrypted);
// It may happen that the read() above read both the ServerHello and the TLS Close Alert.
if (!encrypted.hasRemaining()) {
// Now if we can read more, we should read the TLS Close Alert and then the TCP FIN.
encrypted.clear();
read = channel.read(encrypted);
Assert.assertTrue(read > 0);
encrypted.flip();
}
Assert.assertEquals(21, encrypted.get());
encrypted.clear();
Assert.assertEquals(-1, channel.read(encrypted));
}
}
use of java.nio.ByteBuffer in project jetty.project by eclipse.
the class GZIPContentDecoder method decode.
/** Inflate compressed data from a buffer.
*
* @param compressed Buffer containing compressed data.
* @return Buffer containing inflated data.
*/
public ByteBuffer decode(ByteBuffer compressed) {
decodeChunks(compressed);
if (BufferUtil.isEmpty(_inflated) || _state == State.CRC || _state == State.ISIZE)
return BufferUtil.EMPTY_BUFFER;
ByteBuffer result = _inflated;
_inflated = null;
return result;
}
use of java.nio.ByteBuffer in project jetty.project by eclipse.
the class GZIPContentDecoderTest method testSmallBlockWithGZIPChunkedAtEnd.
@Test
public void testSmallBlockWithGZIPChunkedAtEnd() throws Exception {
String data = "0";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream output = new GZIPOutputStream(baos);
output.write(data.getBytes(StandardCharsets.UTF_8));
output.close();
byte[] bytes = baos.toByteArray();
// The trailer is 8 bytes, chunk the last 9 bytes
byte[] bytes1 = new byte[bytes.length - 9];
System.arraycopy(bytes, 0, bytes1, 0, bytes1.length);
byte[] bytes2 = new byte[bytes.length - bytes1.length];
System.arraycopy(bytes, bytes1.length, bytes2, 0, bytes2.length);
GZIPContentDecoder decoder = new GZIPContentDecoder(pool, 2048);
ByteBuffer decoded = decoder.decode(ByteBuffer.wrap(bytes1));
assertEquals(data, StandardCharsets.UTF_8.decode(decoded).toString());
assertFalse(decoder.isFinished());
decoder.release(decoded);
decoded = decoder.decode(ByteBuffer.wrap(bytes2));
assertEquals(0, decoded.remaining());
assertTrue(decoder.isFinished());
decoder.release(decoded);
}
use of java.nio.ByteBuffer in project jetty.project by eclipse.
the class HttpFieldsTest method testCachedPut.
@Test
public void testCachedPut() throws Exception {
HttpFields header = new HttpFields();
header.put("Connection", "Keep-Alive");
header.put("tRansfer-EncOding", "CHUNKED");
header.put("CONTENT-ENCODING", "gZIP");
ByteBuffer buffer = BufferUtil.allocate(1024);
BufferUtil.flipToFill(buffer);
HttpGenerator.putTo(header, buffer);
BufferUtil.flipToFlush(buffer, 0);
String out = BufferUtil.toString(buffer).toLowerCase(Locale.ENGLISH);
Assert.assertThat(out, Matchers.containsString((HttpHeader.CONNECTION + ": " + HttpHeaderValue.KEEP_ALIVE).toLowerCase(Locale.ENGLISH)));
Assert.assertThat(out, Matchers.containsString((HttpHeader.TRANSFER_ENCODING + ": " + HttpHeaderValue.CHUNKED).toLowerCase(Locale.ENGLISH)));
Assert.assertThat(out, Matchers.containsString((HttpHeader.CONTENT_ENCODING + ": " + HttpHeaderValue.GZIP).toLowerCase(Locale.ENGLISH)));
}
Aggregations