use of io.servicetalk.http.api.StreamingHttpResponse in project servicetalk by apple.
the class GrpcRouter method bind.
Single<GrpcServerContext> bind(final ServerBinder binder, final GrpcExecutionContext executionContext) {
final CompositeCloseable closeable = AsyncCloseables.newCompositeCloseable();
final Map<String, StreamingHttpService> allRoutes = new HashMap<>();
populateRoutes(executionContext, allRoutes, routes, closeable, executionStrategies);
populateRoutes(executionContext, allRoutes, streamingRoutes, closeable, executionStrategies);
populateRoutes(executionContext, allRoutes, blockingRoutes, closeable, executionStrategies);
populateRoutes(executionContext, allRoutes, blockingStreamingRoutes, closeable, executionStrategies);
// TODO: Optimize to bind a specific programming model service based on routes
return binder.bindStreaming(new StreamingHttpService() {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
final StreamingHttpService service;
if (!POST.equals(request.method()) || (service = allRoutes.get(request.path())) == null) {
return NOT_FOUND_SERVICE.handle(ctx, request, responseFactory);
} else {
return service.handle(ctx, request, responseFactory);
}
}
@Override
public Completable closeAsync() {
return closeable.closeAsync();
}
@Override
public Completable closeAsyncGracefully() {
return closeable.closeAsyncGracefully();
}
}).map(httpServerContext -> new DefaultGrpcServerContext(httpServerContext, executionContext));
}
use of io.servicetalk.http.api.StreamingHttpResponse in project servicetalk by apple.
the class GracefulConnectionClosureHandlingTest method closeAfterRequestMetaDataSentResponseMetaDataReceived.
@ParameterizedTest(name = "{index}: protocol={0} initiateClosureFromClient={1} useUds={2} viaProxy={3}")
@MethodSource("data")
void closeAfterRequestMetaDataSentResponseMetaDataReceived(HttpProtocol protocol, boolean initiateClosureFromClient, boolean useUds, boolean viaProxy) throws Exception {
setUp(protocol, initiateClosureFromClient, useUds, viaProxy);
CountDownLatch clientSendRequestPayload = new CountDownLatch(1);
StreamingHttpRequest request = newRequest("/first", clientSendRequestPayload);
Future<StreamingHttpResponse> responseFuture = connection.request(request).toFuture();
serverSendResponse.countDown();
StreamingHttpResponse response = responseFuture.get();
assertResponse(response);
triggerGracefulClosure();
clientSendRequestPayload.countDown();
serverSendResponsePayload.countDown();
assertRequestPayloadBody(request);
assertResponsePayloadBody(response);
awaitConnectionClosed();
assertNextRequestFails();
}
use of io.servicetalk.http.api.StreamingHttpResponse in project servicetalk by apple.
the class GracefulConnectionClosureHandlingTest method closeAfterRequestMetaDataSentNoResponseReceived.
@ParameterizedTest(name = "{index}: protocol={0} initiateClosureFromClient={1} useUds={2} viaProxy={3}")
@MethodSource("data")
void closeAfterRequestMetaDataSentNoResponseReceived(HttpProtocol protocol, boolean initiateClosureFromClient, boolean useUds, boolean viaProxy) throws Exception {
setUp(protocol, initiateClosureFromClient, useUds, viaProxy);
CountDownLatch clientSendRequestPayload = new CountDownLatch(1);
StreamingHttpRequest request = newRequest("/first", clientSendRequestPayload);
Future<StreamingHttpResponse> responseFuture = connection.request(request).toFuture();
serverReceivedRequest.await();
triggerGracefulClosure();
serverSendResponse.countDown();
StreamingHttpResponse response = responseFuture.get();
assertResponse(response);
clientSendRequestPayload.countDown();
serverSendResponsePayload.countDown();
assertRequestPayloadBody(request);
assertResponsePayloadBody(response);
awaitConnectionClosed();
assertNextRequestFails();
}
use of io.servicetalk.http.api.StreamingHttpResponse 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);
}
}
}
use of io.servicetalk.http.api.StreamingHttpResponse in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method clientGracefulClose.
@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void clientGracefulClose(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
setUp(strategy, h2PriorKnowledge);
InetSocketAddress serverAddress = bindHttpEchoServer();
StreamingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).buildStreaming();
CountDownLatch onCloseLatch = new CountDownLatch(1);
Processor<Buffer, Buffer> requestBody = newProcessor();
client.onClose().subscribe(onCloseLatch::countDown);
// We want to make a request, and intentionally not complete it. While the request is in process we invoke
// closeAsyncGracefully and verify that we wait until the request has completed before the underlying
// transport is closed.
StreamingHttpRequest request = client.post("/").payloadBody(fromSource(requestBody));
StreamingHttpResponse response = client.request(request).toFuture().get();
client.closeAsyncGracefully().subscribe();
// We expect this to timeout, because we have not completed the outstanding request.
assertFalse(onCloseLatch.await(300, MILLISECONDS));
requestBody.onComplete();
response.payloadBody().ignoreElements().toFuture();
onCloseLatch.await();
}
Aggregations