use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class HttpResponseDecoderBenchmark method setup.
@Setup(Level.Trial)
public void setup() {
final HttpResponseStatus status = status(statusCode);
final Buffer responseBuffer = PREFER_DIRECT_ALLOCATOR.newBuffer(100);
HTTP_1_1.writeTo(responseBuffer);
responseBuffer.writeByte(SP);
status.writeTo(responseBuffer);
responseBuffer.writeShort(CRLF_SHORT);
responseBuffer.writeBytes("content-length: 0".getBytes(US_ASCII));
responseBuffer.writeShort(CRLF_SHORT);
responseBuffer.writeShort(CRLF_SHORT);
responseByteBuf = toByteBuf(responseBuffer.slice());
channel = new EmbeddedChannel(new HttpResponseDecoder(new ArrayDeque<>(), new PollLikePeakArrayDeque<>(), getByteBufAllocator(DEFAULT_ALLOCATOR), DefaultHttpHeadersFactory.INSTANCE, 8192, 8192, false, false, UNSUPPORTED_PROTOCOL_CLOSE_HANDLER));
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class NettyBuffer method equals.
@Override
public boolean equals(Object obj) {
if (obj instanceof Buffer) {
Buffer other = (Buffer) obj;
ByteBuf byteBuf = toByteBufNoThrow(other);
return byteBuf != null ? buffer.equals(byteBuf) : buffer.nioBuffer().equals(other.toNioBuffer());
}
return false;
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class ConnectableBufferOutputStreamTest method multiThreadedProducerConsumer.
@Test
void multiThreadedProducerConsumer() throws Exception {
final Random r = new Random();
// capture seed to have repeatable tests
final long seed = r.nextLong();
r.setSeed(seed);
// 3% of heap or max of 100 MiB
final int dataSize = (int) min(getRuntime().maxMemory() * 0.03, 100 * 1024 * 1024);
LOGGER.info("Test seed = {} – data size = {}", seed, dataSize);
final AtomicReference<Throwable> error = new AtomicReference<>();
final byte[] data = new byte[dataSize];
final byte[] received = new byte[dataSize];
r.nextBytes(data);
final Publisher<Buffer> pub = cbos.connect();
final Thread producerThread = new Thread(() -> {
int writeIndex = 0;
try {
while (writeIndex < dataSize) {
// write at most 25% of remaining bytes
final int length = (int) max(1, r.nextInt(dataSize - (writeIndex - 1)) * 0.25);
LOGGER.debug("Writing {} bytes - writeIndex = {}", length, writeIndex);
cbos.write(data, writeIndex, length);
writeIndex += length;
if (r.nextDouble() < 0.4) {
LOGGER.debug("Flushing - writeIndex = {}", writeIndex);
cbos.flush();
}
}
LOGGER.debug("Closing - writeIndex = {}", writeIndex);
cbos.close();
} catch (Throwable t) {
error.compareAndSet(null, t);
}
});
final Thread consumerThread = new Thread(() -> {
try {
final CountDownLatch consumerDone = new CountDownLatch(1);
toSource(pub).subscribe(new Subscriber<Buffer>() {
@Nullable
private Subscription sub;
private int writeIndex;
@Override
public void onSubscribe(final Subscription s) {
sub = s;
sub.request(1);
}
@Override
public void onNext(final Buffer buffer) {
final int readingBytes = buffer.readableBytes();
LOGGER.debug("Reading {} bytes, writeIndex = {}", readingBytes, writeIndex);
buffer.readBytes(received, writeIndex, readingBytes);
writeIndex += readingBytes;
assert sub != null : "Subscription can not be null in onNext.";
sub.request(1);
}
@Override
public void onError(final Throwable t) {
error.compareAndSet(null, t);
consumerDone.countDown();
}
@Override
public void onComplete() {
consumerDone.countDown();
}
});
consumerDone.await();
} catch (Throwable t) {
error.compareAndSet(null, t);
}
});
producerThread.start();
consumerThread.start();
// make sure both threads exit
producerThread.join();
// provides visibility for received from consumerThread
consumerThread.join();
assertNull(error.get());
// assertThat() times out
assertArrayEquals(data, received);
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class GracefulConnectionClosureHandlingTest method setUp.
void setUp(HttpProtocol protocol, boolean initiateClosureFromClient, boolean useUds, boolean viaProxy) throws Exception {
this.protocol = protocol;
this.initiateClosureFromClient = initiateClosureFromClient;
if (useUds) {
Assumptions.assumeTrue(SERVER_CTX.ioExecutor().isUnixDomainSocketSupported(), "Server's IoExecutor does not support UnixDomainSocket");
Assumptions.assumeTrue(CLIENT_CTX.ioExecutor().isUnixDomainSocketSupported(), "Client's IoExecutor does not support UnixDomainSocket");
assumeFalse(viaProxy, "UDS cannot be used via proxy");
}
assumeFalse(protocol == HTTP_2 && viaProxy, "Proxy is not supported with HTTP/2");
HttpServerBuilder serverBuilder = (useUds ? forAddress(newSocketAddress()) : forAddress(localAddress(0))).protocols(protocol.config).ioExecutor(SERVER_CTX.ioExecutor()).executor(SERVER_CTX.executor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, () -> true).appendConnectionAcceptorFilter(original -> new DelegatingConnectionAcceptor(original) {
@Override
public Completable accept(final ConnectionContext context) {
if (!initiateClosureFromClient) {
((NettyConnectionContext) context).onClosing().whenFinally(onClosing::countDown).subscribe();
}
context.onClose().whenFinally(serverConnectionClosed::countDown).subscribe();
connectionAccepted.countDown();
return completed();
}
});
HostAndPort proxyAddress = null;
if (viaProxy) {
// Dummy proxy helps to emulate old intermediate systems that do not support half-closed TCP connections
proxyTunnel = new ProxyTunnel();
proxyAddress = proxyTunnel.startProxy();
serverBuilder.sslConfig(new ServerSslConfigBuilder(DefaultTestCerts::loadServerPem, DefaultTestCerts::loadServerKey).build());
} else {
proxyTunnel = null;
}
serverContext = serverBuilder.listenBlockingStreamingAndAwait((ctx, request, response) -> {
serverReceivedRequest.countDown();
response.addHeader(CONTENT_LENGTH, valueOf(RESPONSE_CONTENT.length()));
serverSendResponse.await();
try (HttpPayloadWriter<String> writer = response.sendMetaData(RAW_STRING_SERIALIZER)) {
// Subscribe to the request payload body before response writer closes
BlockingIterator<Buffer> iterator = request.payloadBody().iterator();
// Consume request payload body asynchronously:
ctx.executionContext().executor().submit(() -> {
int receivedSize = 0;
while (iterator.hasNext()) {
Buffer chunk = iterator.next();
assert chunk != null;
receivedSize += chunk.readableBytes();
}
serverReceivedRequestPayload.add(receivedSize);
}).beforeOnError(cause -> {
LOGGER.error("failure while reading request", cause);
serverReceivedRequestPayload.add(-1);
}).toFuture();
serverSendResponsePayload.await();
writer.write(RESPONSE_CONTENT);
}
});
serverContext.onClose().whenFinally(serverContextClosed::countDown).subscribe();
client = (viaProxy ? forSingleAddress(serverHostAndPort(serverContext)).proxyAddress(proxyAddress).sslConfig(new ClientSslConfigBuilder(DefaultTestCerts::loadServerCAPem).peerHost(serverPemHostname()).build()) : forResolvedAddress(serverContext.listenAddress())).protocols(protocol.config).executor(CLIENT_CTX.executor()).ioExecutor(CLIENT_CTX.ioExecutor()).executionStrategy(defaultStrategy()).enableWireLogging("servicetalk-tests-wire-logger", TRACE, Boolean.TRUE::booleanValue).appendConnectionFactoryFilter(ConnectionFactoryFilter.withStrategy(cf -> initiateClosureFromClient ? new OnClosingConnectionFactoryFilter<>(cf, onClosing) : cf, ExecutionStrategy.offloadNone())).buildStreaming();
connection = client.reserveConnection(client.get("/")).toFuture().get();
connection.onClose().whenFinally(clientConnectionClosed::countDown).subscribe();
// wait until server accepts connection
connectionAccepted.await();
toClose = initiateClosureFromClient ? connection : serverContext;
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method clientAllowDropTrailers.
private void clientAllowDropTrailers(boolean allowDrop, boolean serverAddTrailerHeader) throws Exception {
String trailerName = "t1";
String trailerValue = "v1";
InetSocketAddress serverAddress = serverAddTrailerHeader ? bindHttpEchoServerWithTrailer(trailerName) : bindHttpEchoServer();
try (StreamingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).allowDropResponseTrailers(allowDrop).executionStrategy(clientExecutionStrategy).buildStreaming()) {
StreamingHttpResponse response = client.request(client.get("/").transform(new StatelessTrailersTransformer<Buffer>() {
@Override
protected HttpHeaders payloadComplete(final HttpHeaders trailers) {
trailers.add(trailerName, trailerValue);
return trailers;
}
})).toFuture().get();
SingleSource.Processor<HttpHeaders, HttpHeaders> trailersProcessor = Processors.newSingleProcessor();
// intermediate Buffer transform may drop trailers
response.transformPayloadBody(buf -> buf).transform(new StatelessTrailersTransformer<Buffer>() {
@Override
protected HttpHeaders payloadComplete(final HttpHeaders trailers) {
trailersProcessor.onSuccess(trailers);
return trailers;
}
}).messageBody().ignoreElements().toFuture().get();
HttpHeaders responseTrailers = fromSource(trailersProcessor).toFuture().get();
if (allowDrop && !serverAddTrailerHeader) {
assertFalse(responseTrailers.contains(trailerName));
} else {
assertHeaderValue(responseTrailers, trailerName, trailerValue);
}
}
}
Aggregations