use of reactor.netty.DisposableServer in project reactor-netty by reactor.
the class HttpServerTests method testCancelReceivingForWebSocketClient.
@Test
void testCancelReceivingForWebSocketClient() throws Exception {
AtomicReference<WebSocketCloseStatus> statusServer = new AtomicReference<>();
AtomicReference<WebSocketCloseStatus> statusClient = new AtomicReference<>();
CountDownLatch latch = new CountDownLatch(2);
disposableServer = createServer().handle((req, resp) -> resp.sendWebsocket((in, out) -> {
in.receiveCloseStatus().doOnNext(o -> {
statusServer.set(o);
latch.countDown();
}).subscribe();
return out.sendString(Flux.interval(Duration.ofMillis(10)).map(l -> l + ""));
})).bindNow();
createClient(disposableServer.port()).websocket().uri("/").handle((in, out) -> {
in.receiveCloseStatus().doOnNext(o -> {
statusClient.set(o);
latch.countDown();
}).subscribe();
in.receive().take(1).subscribe();
return Mono.never();
}).subscribe();
assertThat(latch.await(30, TimeUnit.SECONDS)).isTrue();
assertThat(statusClient.get()).isNotNull().isEqualTo(WebSocketCloseStatus.ABNORMAL_CLOSURE);
assertThat(statusServer.get()).isNotNull().isEqualTo(WebSocketCloseStatus.EMPTY);
}
use of reactor.netty.DisposableServer in project reactor-netty by reactor.
the class HttpServerTests method testCancelConnectionCloseForWebSocketServer.
@Test
void testCancelConnectionCloseForWebSocketServer() throws Exception {
AtomicReference<WebSocketCloseStatus> statusServer = new AtomicReference<>();
AtomicReference<WebSocketCloseStatus> statusClient = new AtomicReference<>();
CountDownLatch latch = new CountDownLatch(2);
disposableServer = createServer().handle((req, resp) -> resp.sendWebsocket((in, out) -> {
in.receiveCloseStatus().doOnNext(o -> {
statusServer.set(o);
latch.countDown();
}).subscribe();
in.withConnection(Connection::dispose);
return Mono.never();
})).bindNow();
createClient(disposableServer.port()).websocket().uri("/").handle((in, out) -> {
in.receiveCloseStatus().doOnNext(o -> {
statusClient.set(o);
latch.countDown();
}).subscribe();
return Mono.never();
}).subscribe();
assertThat(latch.await(30, TimeUnit.SECONDS)).isTrue();
assertThat(statusClient.get()).isNotNull().isEqualTo(WebSocketCloseStatus.EMPTY);
assertThat(statusServer.get()).isNotNull().isEqualTo(WebSocketCloseStatus.ABNORMAL_CLOSURE);
}
use of reactor.netty.DisposableServer in project reactor-netty by reactor.
the class HttpServerTests method startRouterAndAwait.
@Test
void startRouterAndAwait() throws InterruptedException {
ExecutorService ex = Executors.newSingleThreadExecutor();
AtomicReference<DisposableServer> ref = new AtomicReference<>();
Future<?> f = ex.submit(() -> createServer().route(routes -> routes.get("/hello", (req, resp) -> resp.sendString(Mono.just("hello!")))).bindUntilJavaShutdown(Duration.ofSeconds(2), ref::set));
// if the server cannot be started, a ExecutionException will be thrown instead
assertThatExceptionOfType(TimeoutException.class).isThrownBy(() -> f.get(1, TimeUnit.SECONDS));
// the router is not done and is still blocking the thread
assertThat(f.isDone()).isFalse();
assertThat(ref.get()).withFailMessage("Server is not initialized after 1s").isNotNull();
// shutdown the router to unblock the thread
ref.get().disposeNow();
Thread.sleep(100);
assertThat(f.isDone()).isTrue();
}
use of reactor.netty.DisposableServer in project reactor-netty by reactor.
the class HttpServerTests method testContentLengthHeadRequest.
@Test
void testContentLengthHeadRequest() {
AtomicReference<HttpHeaders> sentHeaders = new AtomicReference<>();
disposableServer = createServer().host("localhost").route(r -> r.route(req -> req.uri().equals("/1"), (req, res) -> res.sendString(Flux.just("OK").hide())).route(req -> req.uri().startsWith("/2"), (req, res) -> res.chunkedTransfer(false).sendString(Flux.just("OK").hide())).route(req -> req.uri().startsWith("/3"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 2);
return res.sendString(Mono.just("OK")).then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/4"), (req, res) -> res.sendHeaders()).route(req -> req.uri().startsWith("/5"), (req, res) -> res.chunkedTransfer(false).sendHeaders()).route(req -> req.uri().startsWith("/6"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 2);
return res.sendHeaders().then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/7"), (req, res) -> res.send().then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()))).route(req -> req.uri().startsWith("/8"), (req, res) -> res.chunkedTransfer(false).send().then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()))).route(req -> req.uri().startsWith("/9"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 2);
return res.send().then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/10"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 0);
return res.sendString(Mono.just("OK")).then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/11"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 0);
return res.sendString(Flux.just("OK").hide()).then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/12"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 2);
return res.sendObject(Unpooled.wrappedBuffer("OK".getBytes(Charset.defaultCharset()))).then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
}).route(req -> req.uri().startsWith("/13"), (req, res) -> {
res.responseHeaders().set(HttpHeaderNames.CONTENT_LENGTH, 0);
return res.sendObject(Unpooled.wrappedBuffer("OK".getBytes(Charset.defaultCharset()))).then().doOnSuccess(aVoid -> sentHeaders.set(res.responseHeaders()));
})).bindNow();
InetSocketAddress address = (InetSocketAddress) disposableServer.address();
doTestContentLengthHeadRequest("/1", address, HttpMethod.GET, sentHeaders, true, false);
doTestContentLengthHeadRequest("/1", address, HttpMethod.HEAD, sentHeaders, true, false);
doTestContentLengthHeadRequest("/2", address, HttpMethod.GET, sentHeaders, false, true);
doTestContentLengthHeadRequest("/2", address, HttpMethod.HEAD, sentHeaders, false, true);
doTestContentLengthHeadRequest("/3", address, HttpMethod.GET, sentHeaders, false, false);
doTestContentLengthHeadRequest("/3", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/4", address, HttpMethod.HEAD, sentHeaders, true, false);
doTestContentLengthHeadRequest("/5", address, HttpMethod.HEAD, sentHeaders, false, true);
doTestContentLengthHeadRequest("/6", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/7", address, HttpMethod.HEAD, sentHeaders, true, false);
doTestContentLengthHeadRequest("/8", address, HttpMethod.HEAD, sentHeaders, false, true);
doTestContentLengthHeadRequest("/9", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/10", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/11", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/12", address, HttpMethod.HEAD, sentHeaders, false, false);
doTestContentLengthHeadRequest("/13", address, HttpMethod.HEAD, sentHeaders, false, false);
}
use of reactor.netty.DisposableServer in project reactor-netty by reactor.
the class HttpRedirectTest method redirect_issuesOnRequestForEachAttempt.
/**
* This ensures functionality such as metrics and tracing can accurately count requests.
*/
@Test
void redirect_issuesOnRequestForEachAttempt() {
disposableServer = createServer().host("localhost").route(r -> r.get("/1", (req, res) -> res.sendRedirect("/3")).get("/3", (req, res) -> res.status(200).sendString(Mono.just("OK")))).bindNow();
AtomicInteger onRequestCount = new AtomicInteger();
AtomicInteger onResponseCount = new AtomicInteger();
AtomicInteger onRedirectCount = new AtomicInteger();
AtomicInteger doOnResponseError = new AtomicInteger();
Tuple2<String, HttpResponseStatus> response = createClient(disposableServer::address).followRedirect(true).doOnRequest((r, c) -> onRequestCount.incrementAndGet()).doOnResponse((r, c) -> onResponseCount.incrementAndGet()).doOnRedirect((r, c) -> onRedirectCount.incrementAndGet()).doOnResponseError((r, t) -> doOnResponseError.incrementAndGet()).get().uri("/1").responseSingle((res, bytes) -> bytes.asString().zipWith(Mono.just(res.status()))).block(Duration.ofSeconds(30));
assertThat(response).isNotNull();
assertThat(response.getT1()).isEqualTo("OK");
assertThat(response.getT2()).isEqualTo(HttpResponseStatus.OK);
assertThat(onRequestCount.get()).isEqualTo(2);
assertThat(onResponseCount.get()).isEqualTo(1);
assertThat(onRedirectCount.get()).isEqualTo(1);
assertThat(doOnResponseError.get()).isEqualTo(0);
}
Aggregations