private static LiveHttpResponse.Builder response() { return LiveHttpResponse.response(); }
private static LiveHttpResponse.Builder response(HttpResponseStatus status) { return LiveHttpResponse.response(status); }
@VisibleForTesting static LiveHttpResponse.Builder toStyxResponse(io.netty.handler.codec.http.HttpResponse nettyResponse) { LiveHttpResponse.Builder responseBuilder = response(statusWithCode(nettyResponse.getStatus().code())); stream(nettyResponse.headers().spliterator(), false) .forEach(header -> responseBuilder.addHeader(header.getKey(), header.getValue())); return responseBuilder; }
@Override public Eventual<LiveHttpResponse> intercept(LiveHttpRequest request, Chain chain) { if (CONNECT.equals(request.method())) { return Eventual.of(response(METHOD_NOT_ALLOWED).build()); } else { return chain.proceed(request); } }
private Eventual<LiveHttpResponse> getCurrentOrPutNewState(LiveHttpRequest request, HttpInterceptor.Context context) { if (GET.equals(request.method())) { return getCurrentState(request, context); } else if (PUT.equals(request.method())) { return putNewState(request, context); } else { return Eventual.of(response(METHOD_NOT_ALLOWED).build()); } }
private State onResponseObservableCompletedTooSoon(ChannelHandlerContext ctx, Object requestId) { metrics.counter("requests.cancelled.observableCompletedTooSoon").inc(); if (!ongoingRequest.id().equals(requestId)) { return this.state(); } cancelSubscription(); statsSink.onTerminate(ongoingRequest.id()); tracker.endTrack(ongoingRequest); responseWriterFactory.create(ctx).write(LiveHttpResponse.response(INTERNAL_SERVER_ERROR).build()) .handle((dontCare, ignore) -> ctx.close()); return TERMINATED; }
private static HttpHandler buildFallbackHandler(List<String> parents, RouteHandlerFactory routeHandlerFactory, ConditionRouterConfig config) { if (config.fallback == null) { return (request, context) -> Eventual.of(LiveHttpResponse.response(BAD_GATEWAY).build()); } else { return routeHandlerFactory.build(append(parents, "fallback"), config.fallback); } }
private LiveHttpResponse exceptionToResponse(Throwable exception, LiveHttpRequest request) { HttpResponseStatus status = status(exception instanceof PluginException ? exception.getCause() : exception); String message = status.code() >= 500 ? "Site temporarily unavailable." : status.description(); return responseEnhancer.enhance( LiveHttpResponse .response(status) .body(new ByteStream(Flux.just(new Buffer(message, UTF_8)))) .build() .newBuilder(), request) .header(CONTENT_LENGTH, message.getBytes(UTF_8).length) .build(); }
@Test public void firesResponseContentError() { Mono<LiveHttpResponse> publisher = Mono.just( response(OK) .body(new ByteStream(Flux.error(new RuntimeException()))) .build()); Publisher<LiveHttpResponse> listener = ResponseEventListener.from(publisher) .whenContentError(cause -> responseError.set(cause)) .apply(); StepVerifier.create(listener) .consumeNextWith(LiveHttpMessage::consume) .verifyComplete(); assertTrue(responseError.get() instanceof RuntimeException); }
@Test public void doesntFireEventsThatNeverOccurred() { Mono<LiveHttpResponse> publisher = Mono.just(response(OK).body(new ByteStream(Flux.just(new Buffer("hey", UTF_8)))).build()); Flux<LiveHttpResponse> listener = ResponseEventListener.from(publisher) .whenCancelled(() -> cancelled.set(true)) .whenResponseError(cause -> responseError.set(cause)) .whenContentError(cause -> contentError.set(cause)) .whenCompleted(() -> completed.set(true)) .apply(); StepVerifier.create(listener) .consumeNextWith(LiveHttpMessage::consume) .then(() -> { assertFalse(cancelled.get()); assertNull(responseError.get()); assertNull(contentError.get()); assertTrue(completed.get()); }) .verifyComplete(); }
@Override public Eventual<LiveHttpResponse> handle(LiveHttpRequest request, HttpInterceptor.Context context) { return Eventual.of(response(statusWithCode(status)).body(new ByteStream(Flux.just(new Buffer(text, UTF_8)))).build()); }
@Test public void ignoresResponseErrorAfterHeaders() { Flux<LiveHttpResponse> publisher = Flux.just( response(OK) .body(new ByteStream(Flux.just(new Buffer("hey", UTF_8)))) .build()) .concatWith(Flux.error(new RuntimeException())); Publisher<LiveHttpResponse> listener = ResponseEventListener.from(publisher) .whenCancelled(() -> cancelled.set(true)) .whenResponseError(cause -> responseError.set(cause)) .whenContentError(cause -> contentError.set(cause)) .apply(); StepVerifier.create(listener) .consumeNextWith(LiveHttpMessage::consume) .verifyError(); assertFalse(cancelled.get()); assertNull(responseError.get()); assertNull(contentError.get()); }
@BeforeMethod public void setUp() { publisher = TestPublisher.create(); request = get("/").body(new ByteStream(publisher)).build(); response = response(OK).body(new ByteStream(publisher)).build(); completed = new AtomicReference<>(); }
@Test public void toFullResponseReleasesOriginalRefCountedBuffers() throws ExecutionException, InterruptedException { Buffer content = new Buffer(Unpooled.copiedBuffer("original", UTF_8)); LiveHttpResponse original = LiveHttpResponse.response(OK) .body(new ByteStream(Flux.just(content))) .build(); StepVerifier.create(original.aggregate(100)) .expectNextCount(1) .then(() -> assertThat(content.delegate().refCnt(), is(0))) .verifyComplete(); }
@Test public void firesWhenContentCancelled() { EmitterProcessor<Buffer> contentPublisher = EmitterProcessor.create(); Flux<LiveHttpResponse> listener = ResponseEventListener.from( Flux.just(response(OK) .body(new ByteStream(contentPublisher)) .build())) .whenCancelled(() -> cancelled.set(true)) .apply(); StepVerifier.create(listener) .consumeNextWith(response -> StepVerifier.create(response.body()) .then(() -> assertFalse(cancelled.get())) .thenCancel() .verify()) .verifyComplete(); assertTrue(cancelled.get()); }