use of io.servicetalk.http.api.HttpHeaders in project servicetalk by apple.
the class ContentLengthAndTrailersTest method setUp.
private void setUp(HttpProtocol protocol, String content) {
this.protocol = protocol;
this.content = content;
protocol(protocol.config);
serviceFilterFactory(service -> new StreamingHttpServiceFilter(service) {
@Override
public Single<StreamingHttpResponse> handle(final HttpServiceContext ctx, final StreamingHttpRequest request, final StreamingHttpResponseFactory responseFactory) {
// Use transform to simulate access to request trailers
return delegate().handle(ctx, request.transform(new StatelessTrailersTransformer<>()), responseFactory).map(response -> {
final HttpHeaders headers = request.headers();
if (headers.contains(CONTENT_LENGTH)) {
response.setHeader(CLIENT_CONTENT_LENGTH, mergeValues(headers.values(CONTENT_LENGTH)));
}
if (headers.contains(TRANSFER_ENCODING)) {
response.setHeader(CLIENT_TRANSFER_ENCODING, mergeValues(headers.values(TRANSFER_ENCODING)));
}
return response;
});
}
});
setUp(CACHED, CACHED_SERVER);
}
use of io.servicetalk.http.api.HttpHeaders 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.HttpHeaders in project servicetalk by apple.
the class BlockingStreamingHttpServiceTest method respondWithPayloadBodyAndTrailers.
private void respondWithPayloadBodyAndTrailers(BlockingStreamingHttpService handler, boolean useDeserializer) throws Exception {
BlockingStreamingHttpClient client = context(handler);
BlockingStreamingHttpResponse response = client.request(client.get("/"));
assertResponse(response);
assertThat(response.headers().get(TRAILER).toString(), is(X_TOTAL_LENGTH));
final StringBuilder sb = new StringBuilder();
final HttpHeaders trailers;
if (useDeserializer) {
HttpMessageBodyIterator<String> msgBody = response.messageBody(appSerializerUtf8FixLen()).iterator();
while (msgBody.hasNext()) {
sb.append(msgBody.next());
}
trailers = msgBody.trailers();
} else {
HttpMessageBodyIterator<Buffer> msgBody = response.messageBody().iterator();
while (msgBody.hasNext()) {
sb.append(requireNonNull(msgBody.next()).toString(UTF_8));
}
trailers = msgBody.trailers();
}
assertThat(sb.toString(), is(HELLO_WORLD));
assertThat(trailers, notNullValue());
assertThat(trailers.get(X_TOTAL_LENGTH).toString(), is(HELLO_WORLD_LENGTH));
}
use of io.servicetalk.http.api.HttpHeaders in project servicetalk by apple.
the class BlockingStreamingHttpServiceTest method setRequestMessageBody.
@Test
void setRequestMessageBody() throws Exception {
BlockingStreamingHttpClient client = context((ctx, request, response) -> {
response.status(OK);
try {
HttpMessageBodyIterator<Buffer> reqItr = request.messageBody().iterator();
StringBuilder sb = new StringBuilder();
while (reqItr.hasNext()) {
sb.append(requireNonNull(reqItr.next()).toString(UTF_8));
}
assertThat(sb.toString(), is(HELLO_WORLD));
HttpHeaders trailers = reqItr.trailers();
assertThat(trailers, notNullValue());
assertThat(trailers.get(X_TOTAL_LENGTH).toString(), is(HELLO_WORLD_LENGTH));
} catch (Throwable cause) {
HttpPayloadWriter<String> payloadWriter = response.sendMetaData(appSerializerUtf8FixLen());
payloadWriter.write(cause.toString());
payloadWriter.close();
return;
}
response.sendMetaData(appSerializerUtf8FixLen()).close();
});
BufferAllocator alloc = client.executionContext().bufferAllocator();
BlockingStreamingHttpRequest req = client.get("/");
req.setHeader(TRAILER, X_TOTAL_LENGTH);
int split = HELLO_WORLD.length() / 2;
final BlockingIterable<Buffer> reqIterable = BlockingIterables.from(asList(alloc.fromAscii(HELLO_WORLD.substring(0, split)), alloc.fromAscii(HELLO_WORLD.substring(split))));
req.messageBody(() -> new HttpMessageBodyIterator<Buffer>() {
private final BlockingIterator<Buffer> iterator = reqIterable.iterator();
@Nullable
private HttpHeaders trailers;
private int totalLength;
@Nullable
@Override
public HttpHeaders trailers() {
if (trailers == null) {
trailers = DefaultHttpHeadersFactory.INSTANCE.newTrailers();
trailers.set(X_TOTAL_LENGTH, String.valueOf(totalLength));
}
return trailers;
}
@Override
public boolean hasNext(final long timeout, final TimeUnit unit) throws TimeoutException {
return iterator.hasNext(timeout, unit);
}
@Nullable
@Override
public Buffer next(final long timeout, final TimeUnit unit) throws TimeoutException {
return addTotalLength(iterator.next(timeout, unit));
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Nullable
@Override
public Buffer next() {
return addTotalLength(iterator.next());
}
@Override
public void close() throws Exception {
iterator.close();
}
@Nullable
private Buffer addTotalLength(@Nullable Buffer buffer) {
if (buffer != null) {
totalLength += buffer.readableBytes();
}
return buffer;
}
});
BlockingStreamingHttpResponse response = client.request(req);
assertThat(response.status(), is(OK));
assertThat(stream(response.payloadBody(appSerializerUtf8FixLen()).spliterator(), false).collect(Collectors.toList()), emptyIterable());
}
use of io.servicetalk.http.api.HttpHeaders in project servicetalk by apple.
the class AbstractEchoServerBasedHttpRequesterTest method makeRequestValidateResponseAndClose.
static void makeRequestValidateResponseAndClose(StreamingHttpRequester requester) throws ExecutionException, InterruptedException {
try {
StreamingHttpRequest request = requester.get("/request?foo=bar&foo=baz").payloadBody(from(DEFAULT_ALLOCATOR.fromAscii("Testing123")));
request.headers().set(HOST, "mock.servicetalk.io");
StreamingHttpResponse resp = awaitIndefinitelyNonNull(requester.request(request).retryWhen(retryWithExponentialBackoffFullJitter(10, t -> true, ofMillis(100), ofDays(10), CTX.executor())));
assertThat(resp.status(), equalTo(OK));
Single<String> respBody = resp.payloadBody().collect(StringBuilder::new, (sb, buf) -> {
sb.append(buf.toString(UTF_8));
return sb;
}).map(StringBuilder::toString);
HttpHeaders headers = resp.headers();
assertThat(headers.get("test-req-method"), hasToString(GET.toString()));
assertThat(headers.get("test-req-target"), hasToString("/request?foo=bar&foo=baz"));
assertThat(headers.get("test-req-header-host"), hasToString("mock.servicetalk.io"));
assertThat(headers.get("test-req-header-transfer-encoding"), equalTo(CHUNKED));
assertThat(respBody.toFuture().get(), equalTo("Testing123"));
} finally {
requester.closeAsync().toFuture().get();
}
}
Aggregations