Search in sources :

Example 16 with Buffer

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).onResponseCancel();
    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, atMostOnce()).onResponseData(any(Buffer.class));
    serverInOrder.verify(serverResponseObserver).onResponseCancel();
    serverRequestInOrder.verify(serverRequestObserver).onRequestData(any(Buffer.class));
    serverRequestInOrder.verify(serverRequestObserver).onRequestComplete();
    serverInOrder.verify(serverExchangeObserver).onExchangeFinally();
    verifyNoMoreInteractions(serverLifecycleObserver, serverExchangeObserver, serverRequestObserver, serverResponseObserver);
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) HttpHeaders(io.servicetalk.http.api.HttpHeaders) TestPublisher(io.servicetalk.concurrent.api.TestPublisher) StreamingHttpResponseFactory(io.servicetalk.http.api.StreamingHttpResponseFactory) StreamingHttpServiceFilter(io.servicetalk.http.api.StreamingHttpServiceFilter) Single(io.servicetalk.concurrent.api.Single) HttpServiceContext(io.servicetalk.http.api.HttpServiceContext) Collection(java.util.Collection) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) ConnectionInfo(io.servicetalk.transport.api.ConnectionInfo) StreamingHttpConnection(io.servicetalk.http.api.StreamingHttpConnection) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) EnumSource(org.junit.jupiter.params.provider.EnumSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 17 with Buffer

use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.

the class ContentLengthAndTrailersTest method test.

private void test(Transformer<StreamingHttpRequest> requestTransformer, Transformer<StreamingHttpResponse> responseTransformer, boolean hasContentLength, boolean chunked, boolean hasTrailers) throws Exception {
    StreamingHttpRequest preRequest = streamingHttpConnection().post("/");
    if (!content.isEmpty()) {
        preRequest.payloadBody(from(content), appSerializerUtf8FixLen());
    }
    StreamingHttpRequest request = requestTransformer.transform(preRequest);
    StreamingHttpResponse response = responseTransformer.transform(makeRequest(request));
    assertResponse(response, protocol.version, OK);
    HttpHeaders headers = response.headers();
    assertThat("Unexpected content-length on the response", mergeValues(headers.values(CONTENT_LENGTH)), contentEqualTo(hasContentLength ? valueOf(addFixedLengthFramingOverhead(content.length())) : ""));
    assertThat("Unexpected transfer-encoding on the response", mergeValues(headers.values(TRANSFER_ENCODING)), contentEqualTo(chunked ? CHUNKED : ""));
    assertThat("Unexpected content-length on the request", headers.get(CLIENT_CONTENT_LENGTH), hasContentLength ? contentEqualTo(valueOf(addFixedLengthFramingOverhead(content.length()))) : nullValue());
    assertThat("Unexpected transfer-encoding on the request", headers.get(CLIENT_TRANSFER_ENCODING), chunked ? contentEqualTo(CHUNKED) : nullValue());
    if (content.isEmpty()) {
        response.transform(new TrailersTransformer<Object, Buffer>() {

            @Nullable
            @Override
            public Integer newState() {
                return null;
            }

            @Override
            public Buffer accept(@Nullable final Object o, final Buffer buffer) {
                assertThat(buffer.readableBytes(), equalTo(0));
                return buffer;
            }

            @Override
            public HttpHeaders payloadComplete(@Nullable final Object o, final HttpHeaders trailers) {
                assertThat("Unexpected trailers on the request", trailers.get(TRAILER_NAME), hasTrailers ? contentEqualTo(TRAILER_VALUE) : nullValue());
                return trailers;
            }

            @Override
            public HttpHeaders catchPayloadFailure(@Nullable final Object o, final Throwable cause, final HttpHeaders trailers) throws Throwable {
                throw cause;
            }
        }).messageBody().ignoreElements().toFuture().get();
    } else {
        response.transform(new TrailersTransformer<StringBuilder, String>() {

            @Override
            public StringBuilder newState() {
                return new StringBuilder();
            }

            @Override
            public String accept(final StringBuilder o, final String s) {
                o.append(s);
                return s;
            }

            @Override
            public HttpHeaders payloadComplete(final StringBuilder o, final HttpHeaders trailers) {
                assertThat(o.toString(), equalTo(content));
                assertThat("Unexpected trailers on the request", trailers.get(TRAILER_NAME), hasTrailers ? contentEqualTo(TRAILER_VALUE) : nullValue());
                return trailers;
            }

            @Override
            public HttpHeaders catchPayloadFailure(@Nullable final StringBuilder o, final Throwable cause, final HttpHeaders trailers) throws Throwable {
                throw cause;
            }
        }, appSerializerUtf8FixLen()).messageBody().ignoreElements().toFuture().get();
    }
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) HttpHeaders(io.servicetalk.http.api.HttpHeaders) CharSequences.newAsciiString(io.servicetalk.buffer.api.CharSequences.newAsciiString) StreamingHttpRequest(io.servicetalk.http.api.StreamingHttpRequest) StreamingHttpResponse(io.servicetalk.http.api.StreamingHttpResponse) Nullable(javax.annotation.Nullable)

Example 18 with Buffer

use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.

the class HttpRequestEncoderTest method contentLengthNoTrailersHeaderWhiteSpaceEncodedWithValidationOff.

@Test
void contentLengthNoTrailersHeaderWhiteSpaceEncodedWithValidationOff() {
    EmbeddedChannel channel = newEmbeddedChannel();
    byte[] content = new byte[128];
    ThreadLocalRandom.current().nextBytes(content);
    Buffer buffer = allocator.wrap(content);
    HttpRequestMetaData request = newRequestMetaData(HTTP_1_1, GET, "/some/path?foo=bar&baz=yyy", new DefaultHttpHeadersFactory(false, false, false).newHeaders());
    request.headers().add(" " + CONNECTION + " ", " " + KEEP_ALIVE).add("  " + USER_AGENT + "   ", "    unit-test   ").add(CONTENT_LENGTH, valueOf(content.length));
    channel.writeOutbound(request);
    channel.writeOutbound(buffer.duplicate());
    ByteBuf byteBuf = channel.readOutbound();
    String actualMetaData = byteBuf.toString(US_ASCII);
    byteBuf.release();
    assertTrue(actualMetaData.contains("GET /some/path?foo=bar&baz=yyy HTTP/1.1" + "\r\n"), () -> "unexpected metadata: " + actualMetaData);
    assertTrue(actualMetaData.contains(" " + CONNECTION + " :  " + KEEP_ALIVE + "\r\n"), () -> "unexpected metadata: " + actualMetaData);
    assertTrue(actualMetaData.contains("  " + USER_AGENT + "   :     unit-test   " + "\r\n"), () -> "unexpected metadata: " + actualMetaData);
    assertTrue(actualMetaData.contains(CONTENT_LENGTH + ": " + buffer.readableBytes() + "\r\n"), () -> "unexpected metadata: " + actualMetaData);
    assertTrue(actualMetaData.endsWith("\r\n" + "\r\n"), () -> "unexpected metadata: " + actualMetaData);
    byteBuf = channel.readOutbound();
    assertEquals(buffer.toNioBuffer(), byteBuf.nioBuffer());
    byteBuf.release();
    assertFalse(channel.finishAndReleaseAll());
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) HttpRequestMetaData(io.servicetalk.http.api.HttpRequestMetaData) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) Integer.toHexString(java.lang.Integer.toHexString) ByteBuf(io.netty.buffer.ByteBuf) DefaultHttpHeadersFactory(io.servicetalk.http.api.DefaultHttpHeadersFactory) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 19 with Buffer

use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.

the class HttpRequestEncoderTest method variableNoTrailers.

@Test
void variableNoTrailers() {
    EmbeddedChannel channel = newEmbeddedChannel();
    byte[] content = new byte[128];
    ThreadLocalRandom.current().nextBytes(content);
    Buffer buffer = allocator.wrap(content);
    HttpRequestMetaData request = newRequestMetaData(HTTP_1_1, GET, "/some/path?foo=bar&baz=yyy", INSTANCE.newHeaders());
    request.headers().add(CONNECTION, KEEP_ALIVE).add(USER_AGENT, "unit-test");
    channel.writeOutbound(request);
    channel.writeOutbound(buffer.duplicate());
    channel.writeOutbound(EmptyHttpHeaders.INSTANCE);
    verifyHttpRequest(channel, buffer, TransferEncoding.Variable, false);
    assertFalse(channel.finishAndReleaseAll());
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) HttpRequestMetaData(io.servicetalk.http.api.HttpRequestMetaData) EmbeddedChannel(io.netty.channel.embedded.EmbeddedChannel) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 20 with Buffer

use of io.servicetalk.buffer.api.Buffer in project servicetalk by apple.

the class TcpClient method connectWithFdBlocking.

/**
 * Connect using a {@link FileDescriptorSocketAddress} and await for the connection.
 *
 * @param executionContext {@link ExecutionContext} to use for the connections.
 * @param address to connect.
 * @return New {@link NettyConnection}.
 * @throws ExecutionException If connect failed.
 * @throws InterruptedException If interrupted while waiting for connect to complete.
 */
public NettyConnection<Buffer, Buffer> connectWithFdBlocking(ExecutionContext<?> executionContext, SocketAddress address) throws Exception {
    assumeTrue(executionContext.ioExecutor().isFileDescriptorSocketAddressSupported());
    assumeTrue(Epoll.isAvailable() || KQueue.isAvailable());
    final Class<? extends Channel> channelClass;
    final EventLoopGroup eventLoopGroup;
    if (Epoll.isAvailable()) {
        eventLoopGroup = new EpollEventLoopGroup(1);
        channelClass = EpollSocketChannel.class;
    } else {
        eventLoopGroup = new KQueueEventLoopGroup(1);
        channelClass = KQueueSocketChannel.class;
    }
    AtomicBoolean dataReadDirectlyFromNetty = new AtomicBoolean();
    // Bootstrap a netty channel to the server so we can access its FD and wrap it later in ST.
    Bootstrap bs = new Bootstrap();
    UnixChannel channel = (UnixChannel) bs.channel(channelClass).group(eventLoopGroup).handler(new SimpleChannelInboundHandler<Object>() {

        @Override
        public void channelRead0(ChannelHandlerContext ctx, Object msg) {
            dataReadDirectlyFromNetty.set(true);
        }
    }).connect(address).sync().channel();
    // Unregister it from the netty EventLoop as we want to to handle it via ST.
    channel.deregister().sync();
    FileDescriptorSocketAddress fd = new FileDescriptorSocketAddress(channel.fd().intValue());
    NettyConnection<Buffer, Buffer> connection = connectBlocking(executionContext, fd);
    assertThat("Data read on the FileDescriptor from netty pipeline.", dataReadDirectlyFromNetty.get(), is(false));
    return connection;
}
Also used : Buffer(io.servicetalk.buffer.api.Buffer) ChannelHandlerContext(io.netty.channel.ChannelHandlerContext) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EpollEventLoopGroup(io.netty.channel.epoll.EpollEventLoopGroup) KQueueEventLoopGroup(io.netty.channel.kqueue.KQueueEventLoopGroup) EventLoopGroup(io.netty.channel.EventLoopGroup) EpollEventLoopGroup(io.netty.channel.epoll.EpollEventLoopGroup) KQueueEventLoopGroup(io.netty.channel.kqueue.KQueueEventLoopGroup) Bootstrap(io.netty.bootstrap.Bootstrap) UnixChannel(io.netty.channel.unix.UnixChannel) FileDescriptorSocketAddress(io.servicetalk.transport.api.FileDescriptorSocketAddress)

Aggregations

Buffer (io.servicetalk.buffer.api.Buffer)243 Test (org.junit.jupiter.api.Test)117 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)83 MethodSource (org.junit.jupiter.params.provider.MethodSource)56 StreamingHttpResponse (io.servicetalk.http.api.StreamingHttpResponse)39 StreamingHttpRequest (io.servicetalk.http.api.StreamingHttpRequest)30 StreamingHttpClient (io.servicetalk.http.api.StreamingHttpClient)29 HttpHeaders (io.servicetalk.http.api.HttpHeaders)26 Nullable (javax.annotation.Nullable)24 List (java.util.List)23 EmbeddedChannel (io.netty.channel.embedded.EmbeddedChannel)22 Publisher (io.servicetalk.concurrent.api.Publisher)21 CountDownLatch (java.util.concurrent.CountDownLatch)21 AtomicReference (java.util.concurrent.atomic.AtomicReference)20 CompositeBuffer (io.servicetalk.buffer.api.CompositeBuffer)18 Single (io.servicetalk.concurrent.api.Single)18 InputStream (java.io.InputStream)18 ArrayList (java.util.ArrayList)17 MatcherAssert.assertThat (org.hamcrest.MatcherAssert.assertThat)16 BufferAllocator (io.servicetalk.buffer.api.BufferAllocator)15