use of io.servicetalk.http.api.StreamingHttpResponseFactory in project servicetalk by apple.
the class ConsumeRequestPayloadOnResponsePathTest method test.
private void test(final BiFunction<Single<StreamingHttpResponse>, StreamingHttpRequest, Single<StreamingHttpResponse>> consumeRequestPayload) throws Exception {
try (ServerContext serverContext = HttpServers.forAddress(localAddress(0)).appendServiceFilter(service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
return consumeRequestPayload.apply(delegate().handle(ctx, request, responseFactory), request);
}
}).listenStreamingAndAwait((ctx, request, responseFactory) -> {
final StreamingHttpResponse response = responseFactory.ok().addHeader(TRAILER, X_TOTAL_LENGTH).payloadBody(from("Response\n", "Payload\n", "Body\n"), appSerializerUtf8FixLen()).transform(new TrailersTransformer<AtomicInteger, Buffer>() {
@Override
public AtomicInteger newState() {
return new AtomicInteger();
}
@Override
public Buffer accept(final AtomicInteger total, final Buffer chunk) {
total.addAndGet(chunk.readableBytes());
return chunk;
}
@Override
public HttpHeaders payloadComplete(final AtomicInteger total, final HttpHeaders trailers) {
trailers.add(X_TOTAL_LENGTH, String.valueOf(total.get()));
return trailers;
}
@Override
public HttpHeaders catchPayloadFailure(final AtomicInteger __, final Throwable ___, final HttpHeaders trailers) {
return trailers;
}
});
return succeeded(response);
})) {
HttpResponse response;
try (BlockingHttpClient client = HttpClients.forSingleAddress(AddressUtils.serverHostAndPort(serverContext)).buildBlocking()) {
response = client.request(client.post("/").payloadBody(EXPECTED_REQUEST_PAYLOAD, textSerializerUtf8()));
serverLatch.await();
}
assertThat(response.status(), is(OK));
assertThat("Request payload body might be consumed by someone else", errorRef.get(), is(nullValue()));
assertThat(receivedPayload.toString(), is(EXPECTED_REQUEST_PAYLOAD));
assertThat(response.headers().contains(TRAILER, X_TOTAL_LENGTH), is(true));
assertThat(response.trailers().contains(X_TOTAL_LENGTH), is(true));
CharSequence trailerLength = response.trailers().get(X_TOTAL_LENGTH);
assertNotNull(trailerLength);
assertThat("Unexpected response payload: '" + response.payloadBody().toString(UTF_8) + "'", trailerLength.toString(), is(Integer.toString(response.payloadBody().readableBytes())));
}
}
use of io.servicetalk.http.api.StreamingHttpResponseFactory in project servicetalk by apple.
the class HttpLifecycleObserverTest method testClientCancelsRequestBeforeResponse.
@ParameterizedTest(name = "{displayName} [{index}] protocol={0}")
@EnumSource(HttpProtocol.class)
void testClientCancelsRequestBeforeResponse(HttpProtocol protocol) throws Exception {
CountDownLatch requestReceived = new CountDownLatch(1);
serviceFilterFactory(service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(HttpServiceContext ctx, StreamingHttpRequest request, StreamingHttpResponseFactory responseFactory) {
return delegate().handle(ctx, request.transformMessageBody(mb -> mb.afterOnNext(__ -> requestReceived.countDown())), responseFactory);
}
});
setUp(protocol);
StreamingHttpClient client = streamingHttpClient();
Future<StreamingHttpResponse> responseFuture = client.request(client.post(SVC_NEVER).payloadBody(Publisher.from(CONTENT.duplicate()).concat(Publisher.never()))).toFuture();
requestReceived.await();
responseFuture.cancel(true);
bothTerminate.await();
verify(serverExchangeObserver, await()).onExchangeFinally();
clientInOrder.verify(clientLifecycleObserver).onNewExchange();
clientInOrder.verify(clientExchangeObserver).onRequest(any(StreamingHttpRequest.class));
clientInOrder.verify(clientExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
clientInOrder.verify(clientExchangeObserver).onResponseCancel();
clientRequestInOrder.verify(clientRequestObserver).onRequestData(any(Buffer.class));
clientRequestInOrder.verify(clientRequestObserver).onRequestCancel();
clientInOrder.verify(clientExchangeObserver).onExchangeFinally();
verifyNoMoreInteractions(clientLifecycleObserver, clientExchangeObserver, clientRequestObserver);
verifyNoInteractions(clientResponseObserver);
serverInOrder.verify(serverLifecycleObserver).onNewExchange();
serverInOrder.verify(serverExchangeObserver).onConnectionSelected(any(ConnectionInfo.class));
serverInOrder.verify(serverExchangeObserver).onRequest(any(StreamingHttpRequest.class));
serverRequestInOrder.verify(serverRequestObserver).onRequestData(any(Buffer.class));
serverRequestInOrder.verify(serverRequestObserver).onRequestError(any(IOException.class));
// because of offloading, cancel from the IO-thread may race with an error propagated through request publisher:
verify(serverExchangeObserver, atMostOnce()).onResponseCancel();
verify(serverExchangeObserver, atMostOnce()).onResponse(any(StreamingHttpResponse.class));
verify(serverResponseObserver, atMostOnce()).onResponseComplete();
serverInOrder.verify(serverExchangeObserver).onExchangeFinally();
verifyNoMoreInteractions(serverLifecycleObserver, serverExchangeObserver, serverRequestObserver, serverResponseObserver);
}
use of io.servicetalk.http.api.StreamingHttpResponseFactory in project servicetalk by apple.
the class HttpResponseFactoryStatusCodeTest method testStreamingStatusCode.
@Test
void testStreamingStatusCode() {
final StreamingHttpResponseFactory streamingHttpResponseFactory = new DefaultStreamingHttpResponseFactory(INSTANCE, DEFAULT_ALLOCATOR, HTTP_1_1);
List<HttpResponseStatus> actualStatuses = buildHttpStatuses(streamingHttpResponseFactory, StreamingHttpResponseFactory.class, StreamingHttpResponse.class);
assertThat("unexpected statuses", actualStatuses, containsInAnyOrder(expectedStatuses.toArray()));
}
use of io.servicetalk.http.api.StreamingHttpResponseFactory in project servicetalk by apple.
the class TrailersOnlyErrorTest method testServiceFilterThrows.
@Test
void testServiceFilterThrows() throws Exception {
final BlockingQueue<Throwable> asyncErrors = new LinkedBlockingDeque<>();
final TesterService service = mockTesterService();
final GrpcServerBuilder serverBuilder = GrpcServers.forAddress(localAddress(0)).initializeHttp(builder -> builder.appendServiceFilter(svc -> new StreamingHttpServiceFilter(svc) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
throw DELIBERATE_EXCEPTION;
}
}));
try (ServerContext serverContext = serverBuilder.listenAndAwait(new Tester.ServiceFactory(service))) {
final GrpcClientBuilder<HostAndPort, InetSocketAddress> clientBuilder = GrpcClients.forAddress(serverHostAndPort(serverContext)).initializeHttp(builder -> builder.appendClientFilter(__ -> true, setupResponseVerifierFilter(asyncErrors)));
try (TesterClient client = clientBuilder.build(new Tester.ClientFactory())) {
verifyException(client.test(TestRequest.newBuilder().build()).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testRequestStream(Publisher.from(TestRequest.newBuilder().build())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testResponseStream(TestRequest.newBuilder().build()).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testBiDiStream(from(TestRequest.newBuilder().build()).concat(never())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
verifyException(client.testBiDiStream(from(TestRequest.newBuilder().build())).toFuture(), UNKNOWN);
assertNoAsyncErrors(asyncErrors);
}
}
}
Aggregations