@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
@Override public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) { // NOTICE: nothing in "pre" filter stage as CLIENT_RESPONSE_CONN_ATTR is not added // until the NettyRoutingFilter is run return chain.filter(exchange).then(Mono.defer(() -> { Connection connection = exchange.getAttribute(CLIENT_RESPONSE_CONN_ATTR); if (connection == null) { return Mono.empty(); } log.trace("NettyWriteResponseFilter start"); ServerHttpResponse response = exchange.getResponse(); NettyDataBufferFactory factory = (NettyDataBufferFactory) response.bufferFactory(); //TODO: what if it's not netty final Flux<NettyDataBuffer> body = connection.inbound().receive() .retain() //TODO: needed? .map(factory::wrap); MediaType contentType = null; try { contentType = response.getHeaders().getContentType(); } catch (Exception e) { log.trace("invalid media type", e); } return (isStreamingMediaType(contentType) ? response.writeAndFlushWith(body.map(Flux::just)) : response.writeWith(body)); })); }
@Override public Flux<Frame> receive() { return connection.inbound().receive().map(buf -> Frame.from(buf.retain())); }
@Override public Flux<Frame> receive() { return connection .inbound() .receive() .map( buf -> { CompositeByteBuf composite = connection.channel().alloc().compositeBuffer(); ByteBuf length = wrappedBuffer(new byte[FRAME_LENGTH_SIZE]); FrameHeaderFlyweight.encodeLength(length, 0, buf.readableBytes()); composite.addComponents(true, length, buf.retain()); return Frame.from(composite); }); }
@Override public Flux<Frame> receive() { return connection.inbound().receive().map(buf -> Frame.from(buf.retain())); }
@Override public Flux<Frame> receive() { return connection .inbound() .receive() .map( buf -> { CompositeByteBuf composite = connection.channel().alloc().compositeBuffer(); ByteBuf length = wrappedBuffer(new byte[FRAME_LENGTH_SIZE]); FrameHeaderFlyweight.encodeLength(length, 0, buf.readableBytes()); composite.addComponents(true, length, buf.retain()); return Frame.from(composite); }); }
@Override public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri, Function<? super ClientHttpRequest, Mono<Void>> requestCallback) { if (!uri.isAbsolute()) { return Mono.error(new IllegalArgumentException("URI is not absolute: " + uri)); } return this.httpClient .request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name())) .uri(uri.toString()) .send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound))) .responseConnection((res, con) -> Mono.just(adaptResponse(res, con.inbound(), con.outbound().alloc()))) .next(); }
this.outbound = (WebsocketOutbound) connection.outbound().options(SendOptions::flushOnEach); WebsocketInbound inbound = (WebsocketInbound) connection.inbound(); inbound .aggregateFrames()
@Override @SuppressWarnings("unchecked") public void onStateChange(Connection connection, State newState) { if (newState == State.CONFIGURED) { try { if (log.isDebugEnabled()) { log.debug(format(connection.channel(), "Handler is being applied: {}"), handler); } Mono.fromDirect(handler.apply(connection.inbound(), connection.outbound())) .subscribe(connection.disposeSubscriber()); } catch (Throwable t) { log.error(format(connection.channel(), ""), t); connection.channel() .close(); } } } }
@Override @SuppressWarnings("unchecked") public void onStateChange(Connection connection, State newState) { if (newState == State.CONFIGURED) { try { if (log.isDebugEnabled()) { log.debug(format(connection.channel(), "Handler is being applied: {}"), handler); } Mono.fromDirect(handler.apply(connection.inbound(), connection.outbound())) .subscribe(connection.disposeSubscriber()); } catch (Throwable t) { log.error(format(connection.channel(), ""), t); connection.channel() .close(); } } } }
@Test public void disableChunkImplicitDefault() { ConnectionProvider p = ConnectionProvider.fixed("test", 1); HttpClient client = HttpClient.create(p) .tcpConfiguration(tcpClient -> tcpClient.host("google.com")) .wiretap(true) .chunkedTransfer(false); Tuple2<HttpResponseStatus, Channel> r = client.get() .uri("/unsupportedURI") .responseConnection((res, conn) -> Mono.just(res.status()) .delayUntil(s -> conn.inbound().receive()) .zipWith(Mono.just(conn.channel()))) .blockLast(Duration.ofSeconds(30)); assertThat(r).isNotNull(); Channel r2 = client.get() .uri("/unsupportedURI") .responseConnection((res, conn) -> Mono.just(conn.channel()) .delayUntil(s -> conn.inbound().receive())) .blockLast(Duration.ofSeconds(30)); assertThat(r2).isNotNull(); Assert.assertSame(r.getT2(), r2); Assert.assertEquals(r.getT1(), HttpResponseStatus.NOT_FOUND); p.dispose(); }
.uri("/test/index.html") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(3099)); .uri("/test/test.css") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(3099)); .uri("/test/test1.css") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(30)); .uri("/test/test2.css") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(30)); .uri("/test/test3.css") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(30)); .uri("/test/test4.css") .responseConnection((res, c) -> Mono.just(c.channel()) .delayUntil(ch -> c.inbound().receive())) .blockLast(Duration.ofSeconds(30));