use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class ExpectContinueTest method serverError.
@ParameterizedTest(name = "protocol={0} withCL={1}")
@MethodSource("arguments")
void serverError(HttpProtocol protocol, boolean withCL) throws Exception {
try (HttpServerContext serverContext = startServer(protocol, (ctx, request, response) -> {
requestReceived.countDown();
returnResponse.await();
if (request.headers().contains(EXPECT, CONTINUE)) {
response.status(INTERNAL_SERVER_ERROR);
}
response.sendMetaData().close();
});
StreamingHttpClient client = createClient(serverContext, protocol);
StreamingHttpConnection connection = client.reserveConnection(client.get("/")).toFuture().get()) {
TestPublisher<Buffer> payload = new TestPublisher.Builder<Buffer>().singleSubscriber().build();
connection.request(newRequest(connection, withCL, true, payload)).subscribe(responses::add);
requestReceived.await();
assertThat("Unexpected subscribe to payload body before 100 (Continue)", payload.isSubscribed(), is(false));
returnResponse.countDown();
assertResponse(INTERNAL_SERVER_ERROR, "");
// send a follow-up request on the same connection:
connection.request(connection.get("/")).subscribe(responses::add);
assertResponse(OK, "");
}
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class HttpConnectionEmptyPayloadTest method headRequestContentEmpty.
@Test
void headRequestContentEmpty() throws Exception {
try (CompositeCloseable closeable = AsyncCloseables.newCompositeCloseable()) {
final int expectedContentLength = 128;
byte[] expectedPayload = new byte[expectedContentLength];
ThreadLocalRandom.current().nextBytes(expectedPayload);
ServerContext serverContext = closeable.merge(HttpServers.forAddress(localAddress(0)).ioExecutor(executionContextRule.ioExecutor()).executionStrategy(offloadNone()).listenStreamingAndAwait((ctx, req, factory) -> {
StreamingHttpResponse resp = factory.ok().payloadBody(from(HEAD.equals(req.method()) ? EMPTY_BUFFER : ctx.executionContext().bufferAllocator().newBuffer(expectedContentLength).writeBytes(expectedPayload)));
resp.addHeader(CONTENT_LENGTH, String.valueOf(expectedContentLength));
return succeeded(resp);
}));
StreamingHttpClient client = closeable.merge(forResolvedAddress(serverHostAndPort(serverContext)).ioExecutor(executionContextRule.ioExecutor()).protocols(h1().maxPipelinedRequests(3).build()).executor(executionContextRule.executor()).executionStrategy(defaultStrategy()).buildStreaming());
StreamingHttpConnection connection = closeable.merge(client.reserveConnection(client.get("/")).toFuture().get());
// Request HEAD, GET, HEAD to verify that we can keep reading data despite a HEAD request providing a hint
// about content-length (and not actually providing the content).
Single<StreamingHttpResponse> response1Single = connection.request(connection.newRequest(HEAD, "/"));
Single<StreamingHttpResponse> response2Single = connection.request(connection.get("/"));
Single<StreamingHttpResponse> response3Single = connection.request(connection.newRequest(HEAD, "/"));
StreamingHttpResponse response = awaitIndefinitelyNonNull(response1Single);
assertEquals(OK, response.status());
CharSequence contentLength = response.headers().get(CONTENT_LENGTH);
assertNotNull(contentLength);
assertEquals(expectedContentLength, parseInt(contentLength.toString()));
// Drain the current response content so we will be able to read the next response.
response.messageBody().ignoreElements().toFuture().get();
response = awaitIndefinitelyNonNull(response2Single);
assertEquals(OK, response.status());
contentLength = response.headers().get(CONTENT_LENGTH);
assertNotNull(contentLength);
assertEquals(expectedContentLength, parseInt(contentLength.toString()));
Buffer buffer = awaitIndefinitelyNonNull(response.payloadBody().collect(() -> connection.connectionContext().executionContext().bufferAllocator().newBuffer(), Buffer::writeBytes));
byte[] actualBytes = new byte[buffer.readableBytes()];
buffer.readBytes(actualBytes);
assertArrayEquals(expectedPayload, actualBytes);
response = awaitIndefinitelyNonNull(response3Single);
assertEquals(OK, response.status());
contentLength = response.headers().get(CONTENT_LENGTH);
assertNotNull(contentLength);
assertEquals(expectedContentLength, parseInt(contentLength.toString()));
response.messageBody().ignoreElements().toFuture().get();
}
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class HttpLifecycleObserverTest method testClientCancelsRequestAfterResponse.
@ParameterizedTest(name = "{displayName} [{index}] protocol={0}")
@EnumSource(HttpProtocol.class)
void testClientCancelsRequestAfterResponse(HttpProtocol protocol) throws Exception {
TestPublisher<Buffer> serverResponsePayload = new TestPublisher<>();
serviceFilterFactory(service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(HttpServiceContext ctx, StreamingHttpRequest request, StreamingHttpResponseFactory responseFactory) {
return request.payloadBody().ignoreElements().concat(succeeded(responseFactory.ok().payloadBody(serverResponsePayload)));
}
});
setUp(protocol);
StreamingHttpConnection connection = streamingHttpConnection();
StreamingHttpRequest request = connection.post("/").payloadBody(Publisher.from(CONTENT.duplicate())).transform(// adds empty trailers
new StatelessTrailersTransformer<>());
StreamingHttpResponse response = connection.request(request).toFuture().get();
assertResponse(response, protocol.version, OK);
Future<Collection<Buffer>> payload = response.payloadBody().toFuture();
payload.cancel(true);
if (protocol == HttpProtocol.HTTP_1) {
// wait for cancellation to close the connection:
connection.onClose().toFuture().get();
}
// try to write server content to trigger write failure and close the server-side connection:
serverResponsePayload.onNext(CONTENT.duplicate());
bothTerminate.await();
clientInOrder.verify(clientLifecycleObserver).onNewExchange();
clientInOrder.verify(clientExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
clientInOrder.verify(clientExchangeObserver).onRequest(any(StreamingHttpRequest.class));
clientInOrder.verify(clientExchangeObserver).onResponse(any(StreamingHttpResponse.class));
clientInOrder.verify(clientResponseObserver, atLeastOnce()).onResponseDataRequested(anyLong());
clientInOrder.verify(clientResponseObserver).onResponseCancel();
verify(clientRequestObserver, atLeastOnce()).onRequestDataRequested(anyLong());
clientRequestInOrder.verify(clientRequestObserver).onRequestData(any(Buffer.class));
clientRequestInOrder.verify(clientRequestObserver).onRequestTrailers(any(HttpHeaders.class));
clientRequestInOrder.verify(clientRequestObserver).onRequestComplete();
clientInOrder.verify(clientExchangeObserver).onExchangeFinally();
verifyNoMoreInteractions(clientLifecycleObserver, clientExchangeObserver, clientRequestObserver, clientResponseObserver);
serverInOrder.verify(serverLifecycleObserver).onNewExchange();
serverInOrder.verify(serverExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
serverInOrder.verify(serverExchangeObserver).onRequest(any(StreamingHttpRequest.class));
serverInOrder.verify(serverExchangeObserver).onResponse(any(StreamingHttpResponse.class));
verify(serverResponseObserver, atLeastOnce()).onResponseDataRequested(anyLong());
verify(serverResponseObserver, atMostOnce()).onResponseData(any(Buffer.class));
serverInOrder.verify(serverResponseObserver).onResponseCancel();
serverRequestInOrder.verify(serverRequestObserver, atLeastOnce()).onRequestDataRequested(anyLong());
serverRequestInOrder.verify(serverRequestObserver).onRequestData(any(Buffer.class));
serverRequestInOrder.verify(serverRequestObserver).onRequestComplete();
serverInOrder.verify(serverExchangeObserver).onExchangeFinally();
verifyNoMoreInteractions(serverLifecycleObserver, serverExchangeObserver, serverRequestObserver, serverResponseObserver);
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class ClientEffectiveStrategyTest method getResponse.
private String getResponse(ClientType clientType, StreamingHttpClient client) throws Exception {
switch(clientType) {
case Blocking:
BlockingHttpClient blockingClient = client.asBlockingClient();
return blockingClient.request(blockingClient.get("/")).payloadBody().toString(StandardCharsets.US_ASCII);
case BlockingStreaming:
BlockingStreamingHttpClient blockingStreamingClient = client.asBlockingStreamingClient();
Supplier<CompositeBuffer> supplier = client.executionContext().bufferAllocator()::newCompositeBuffer;
return StreamSupport.stream(blockingStreamingClient.request(blockingStreamingClient.get("/")).payloadBody().spliterator(), false).reduce((Buffer base, Buffer buffer) -> (base instanceof CompositeBuffer ? ((CompositeBuffer) base) : supplier.get().addBuffer(base)).addBuffer(buffer)).map(buffer -> buffer.toString(StandardCharsets.US_ASCII)).orElse("");
case AsyncStreaming:
return client.request(client.get("/")).flatMap(resp -> resp.payloadBody().collect(() -> client.executionContext().bufferAllocator().newCompositeBuffer(), CompositeBuffer::addBuffer)).toFuture().get().toString(StandardCharsets.US_ASCII);
case Async:
HttpClient httpClient = client.asClient();
return httpClient.request(httpClient.get("/")).toFuture().get().payloadBody().toString(StandardCharsets.US_ASCII);
default:
fail("Unexpected client type " + clientType);
/* NOTREACHED */
return "failed";
}
}
use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.
the class BlockingStreamingToStreamingServiceTest method throwAfterSendMetaData.
@Test
void throwAfterSendMetaData() throws Exception {
CountDownLatch onErrorLatch = new CountDownLatch(1);
AtomicReference<Throwable> throwableRef = new AtomicReference<>();
BlockingStreamingHttpService syncService = (ctx, request, response) -> {
response.sendMetaData();
throw DELIBERATE_EXCEPTION;
};
StreamingHttpService asyncService = toStreamingHttpService(syncService, offloadNone()).adaptor();
StreamingHttpResponse asyncResponse = asyncService.handle(mockCtx, reqRespFactory.get("/"), reqRespFactory).subscribeOn(executorExtension.executor()).toFuture().get();
assertMetaData(OK, asyncResponse);
toSource(asyncResponse.payloadBody()).subscribe(new Subscriber<Buffer>() {
@Override
public void onSubscribe(final Subscription s) {
}
@Override
public void onNext(final Buffer s) {
}
@Override
public void onError(final Throwable t) {
throwableRef.set(t);
onErrorLatch.countDown();
}
@Override
public void onComplete() {
}
});
onErrorLatch.await();
assertThat(throwableRef.get(), is(DELIBERATE_EXCEPTION));
}
Aggregations