use of io.servicetalk.http.api.StreamingHttpRequest in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method serverThrowsFromHandler.
@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void serverThrowsFromHandler(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
setUp(strategy, h2PriorKnowledge);
InetSocketAddress serverAddress = bindHttpEchoServer(service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
throw DELIBERATE_EXCEPTION;
}
}, null);
try (BlockingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).buildBlocking()) {
HttpResponse response = client.request(client.get("/"));
assertThat(response.status(), is(INTERNAL_SERVER_ERROR));
assertThat(response.payloadBody(), equalTo(EMPTY_BUFFER));
}
}
use of io.servicetalk.http.api.StreamingHttpRequest in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method clientSendsInvalidContentLength.
private void clientSendsInvalidContentLength(boolean addTrailers, BiConsumer<HttpHeaders, Integer> headersModifier) throws Exception {
assumeFalse(!h2PriorKnowledge && addTrailers, "HTTP/1.1 does not support Content-Length with trailers");
InetSocketAddress serverAddress = bindHttpEchoServer();
try (BlockingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).appendClientFilter(client1 -> new StreamingHttpClientFilter(client1) {
@Override
protected Single<StreamingHttpResponse> request(final StreamingHttpRequester delegate, final StreamingHttpRequest request) {
return request.toRequest().map(req -> {
req.headers().remove(TRANSFER_ENCODING);
headersModifier.accept(req.headers(), req.payloadBody().readableBytes());
return req.toStreamingRequest();
}).flatMap(delegate::request);
}
}).buildBlocking()) {
HttpRequest request = client.get("/").payloadBody("a", textSerializerUtf8());
if (addTrailers) {
request.trailers().set("mytrailer", "myvalue");
}
if (h2PriorKnowledge) {
assertThrows(H2StreamResetException.class, () -> client.request(request));
} else {
try (ReservedBlockingHttpConnection reservedConn = client.reserveConnection(request)) {
assertThrows(IOException.class, () -> {
// Either the current request or the next one should fail
reservedConn.request(request);
reservedConn.request(client.get("/"));
});
}
}
}
}
use of io.servicetalk.http.api.StreamingHttpRequest in project servicetalk by apple.
the class H2PriorKnowledgeFeatureParityTest method clientFilterAsyncContext.
@ParameterizedTest(name = "{displayName} [{index}] client={0}, h2PriorKnowledge={1}")
@MethodSource("clientExecutors")
void clientFilterAsyncContext(HttpTestExecutionStrategy strategy, boolean h2PriorKnowledge) throws Exception {
setUp(strategy, h2PriorKnowledge);
InetSocketAddress serverAddress = bindHttpEchoServer();
final Queue<Throwable> errorQueue = new ConcurrentLinkedQueue<>();
try (BlockingHttpClient client = forSingleAddress(HostAndPort.of(serverAddress)).protocols(h2PriorKnowledge ? h2Default() : h1Default()).executionStrategy(clientExecutionStrategy).appendClientFilter(client2 -> new StreamingHttpClientFilter(client2) {
@Override
protected Single<StreamingHttpResponse> request(final StreamingHttpRequester delegate, final StreamingHttpRequest request) {
return asyncContextTestRequest(errorQueue, delegate, request);
}
}).buildBlocking()) {
final String responseBody = "foo";
HttpResponse response = client.request(client.post("/0").payloadBody(responseBody, textSerializerUtf8()));
assertEquals(responseBody, response.payloadBody(textSerializerUtf8()));
assertNoAsyncErrors(errorQueue);
}
}
use of io.servicetalk.http.api.StreamingHttpRequest in project servicetalk by apple.
the class HttpClientAsyncContextTest method makeClientRequestWithId.
private static void makeClientRequestWithId(StreamingHttpClient client, String requestId) throws ExecutionException, InterruptedException {
StreamingHttpRequest request = client.get("/");
request.headers().set(REQUEST_ID_HEADER, requestId);
client.request(request).whenOnSuccess(response -> assertEquals(OK, response.status())).flatMapCompletable(response -> response.messageBody().ignoreElements()).toFuture().get();
}
use of io.servicetalk.http.api.StreamingHttpRequest in project servicetalk by apple.
the class HttpRequestEncoderTest method protocolPayloadEndOutboundShouldNotTriggerOnFailedFlush.
@Test
void protocolPayloadEndOutboundShouldNotTriggerOnFailedFlush() throws Exception {
AtomicReference<CloseHandler> closeHandlerRef = new AtomicReference<>();
try (CompositeCloseable resources = newCompositeCloseable()) {
Processor serverCloseTrigger = newCompletableProcessor();
CountDownLatch serverChannelLatch = new CountDownLatch(1);
AtomicReference<Channel> serverChannelRef = new AtomicReference<>();
ReadOnlyTcpServerConfig sConfig = new TcpServerConfig().asReadOnly();
ServerContext serverContext = resources.prepend(TcpServerBinder.bind(localAddress(0), sConfig, false, SEC, null, (channel, observer) -> DefaultNettyConnection.initChannel(channel, SEC.bufferAllocator(), SEC.executor(), SEC.ioExecutor(), forPipelinedRequestResponse(false, channel.config()), defaultFlushStrategy(), null, new TcpServerChannelInitializer(sConfig, observer).andThen(channel2 -> {
serverChannelRef.compareAndSet(null, channel2);
serverChannelLatch.countDown();
}), defaultStrategy(), mock(Protocol.class), observer, false, __ -> false), connection -> {
}).toFuture().get());
ReadOnlyHttpClientConfig cConfig = new HttpClientConfig().asReadOnly();
assert cConfig.h1Config() != null;
NettyConnection<Object, Object> conn = resources.prepend(TcpConnector.connect(null, serverHostAndPort(serverContext), cConfig.tcpConfig(), false, CEC, (channel, connectionObserver) -> {
CloseHandler closeHandler = spy(forPipelinedRequestResponse(true, channel.config()));
closeHandlerRef.compareAndSet(null, closeHandler);
return DefaultNettyConnection.initChannel(channel, CEC.bufferAllocator(), CEC.executor(), CEC.ioExecutor(), closeHandler, defaultFlushStrategy(), null, new TcpClientChannelInitializer(cConfig.tcpConfig(), connectionObserver).andThen(new HttpClientChannelInitializer(getByteBufAllocator(CEC.bufferAllocator()), cConfig.h1Config(), closeHandler)).andThen(channel2 -> channel2.pipeline().addLast(new ChannelInboundHandlerAdapter() {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
// Propagate the user event in the pipeline before
// triggering the test condition.
ctx.fireUserEventTriggered(evt);
if (evt instanceof ChannelInputShutdownReadComplete) {
serverCloseTrigger.onComplete();
}
}
})), defaultStrategy(), HTTP_1_1, connectionObserver, true, __ -> false);
}, NoopTransportObserver.INSTANCE).toFuture().get());
// The server needs to wait to close the conneciton until after the client has established the connection.
serverChannelLatch.await();
Channel serverChannel = serverChannelRef.get();
assertNotNull(serverChannel);
assumeFalse(serverChannel instanceof NioSocketChannel, "Windows doesn't emit ChannelInputShutdownReadComplete. Investigation Required.");
((SocketChannel) serverChannel).config().setSoLinger(0);
// Close and send RST concurrently with client write
serverChannel.close();
StreamingHttpRequest request = reqRespFactory.post("/closeme");
fromSource(serverCloseTrigger).toFuture().get();
Completable write = conn.write(from(request, allocator.fromAscii("Bye"), EmptyHttpHeaders.INSTANCE));
assertThrows(ExecutionException.class, () -> write.toFuture().get());
CloseHandler closeHandler = closeHandlerRef.get();
assertNotNull(closeHandler);
verify(closeHandler, never()).protocolPayloadEndOutbound(any(), any());
}
}
Aggregations