protected WebSocketMessage toMessage(WebSocketFrame frame) { DataBuffer payload = bufferFactory().wrap(frame.content()); return new WebSocketMessage(messageTypes.get(frame.getClass()), payload); }
@Override public Flux<DataBuffer> getBody() { return this.inbound.receive() .doOnSubscribe(s -> { if (this.rejectSubscribers.get()) { throw new IllegalStateException("The client response body can only be consumed once."); } }) .doOnCancel(() -> { // https://github.com/reactor/reactor-netty/issues/503 // FluxReceive rejects multiple subscribers, but not after a cancel(). // Subsequent subscribers after cancel() will not be rejected, but will hang instead. // So we need to intercept and reject them in that case. this.rejectSubscribers.set(true); }) .map(byteBuf -> { byteBuf.retain(); return this.bufferFactory.wrap(byteBuf); }); }
/** * Returns a {@link PooledDataBuffer} which will be released after consuming by the consumer. * Currently the {@link NettyDataBuffer} is only one implementation of the {@link PooledDataBuffer} * which is exposed to the public API. */ private PooledDataBuffer withNettyDataBufferFactory(ByteBufHttpData data) { return ((NettyDataBufferFactory) delegate).wrap(data.content()); }
@Override public Flux<DataBuffer> getBody() { return this.inbound.receive() .doOnSubscribe(s -> { if (this.rejectSubscribers.get()) { throw new IllegalStateException("The client response body can only be consumed once."); } }) .doOnCancel(() -> { // https://github.com/reactor/reactor-netty/issues/503 // FluxReceive rejects multiple subscribers, but not after a cancel(). // Subsequent subscribers after cancel() will not be rejected, but will hang instead. // So we need to intercept and reject them in that case. this.rejectSubscribers.set(true); }) .map(byteBuf -> { byteBuf.retain(); return this.bufferFactory.wrap(byteBuf); }); }
@Test // SPR-17054 public void unsupportedMediaTypeShouldConsumeAndCancel() { NettyDataBufferFactory factory = new NettyDataBufferFactory(new PooledByteBufAllocator(true)); NettyDataBuffer buffer = factory.wrap(ByteBuffer.wrap("spring".getBytes(StandardCharsets.UTF_8))); TestPublisher<DataBuffer> body = TestPublisher.create(); MockClientHttpResponse response = new MockClientHttpResponse(HttpStatus.OK); response.getHeaders().setContentType(MediaType.APPLICATION_PDF); response.setBody(body.flux()); BodyExtractor<Mono<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(User.class); StepVerifier.create(extractor.extract(response, this.context)) .then(() -> { body.assertWasSubscribed(); body.emit(buffer); }) .expectErrorSatisfies(throwable -> { assertTrue(throwable instanceof UnsupportedMediaTypeException); try { buffer.release(); Assert.fail("releasing the buffer should have failed"); } catch (IllegalReferenceCountException exc) { } body.assertCancelled(); }).verify(); }
@Override public Flux<DataBuffer> getBody() { return this.inbound.receive() .doOnSubscribe(s -> // See https://github.com/reactor/reactor-netty/issues/503 Assert.state(this.bodyConsumed.compareAndSet(false, true), "The client response body can only be consumed once.")) .map(byteBuf -> { byteBuf.retain(); return this.bufferFactory.wrap(byteBuf); }); }
protected WebSocketMessage toMessage(WebSocketFrame frame) { DataBuffer payload = bufferFactory().wrap(frame.content()); return new WebSocketMessage(MESSAGE_TYPES.get(frame.getClass()), payload); }
@Override public Flux<DataBuffer> getBody() { return response.receive() .doOnSubscribe(s -> // WebClient's onStatus handling tries to drain the body, which may // have also been done by application code in the onStatus callback. // That relies on the 2nd subscriber being rejected but FluxReceive // isn't consistent in doing so and may hang without completion. Assert.state(this.bodyConsumed.compareAndSet(false, true), "The client response body can only be consumed once.")) .map(byteBuf -> { // 5.0.x only: do not retain, make a copy.. byte[] data = new byte[byteBuf.readableBytes()]; byteBuf.readBytes(data); return ReactorClientHttpConnector.BUFFER_FACTORY.wrap(data); }); }
private static <T extends DataBuffer> T logging(Logger log, String inOrOut, T buffer) { try { InputStream dataBuffer = buffer.asInputStream(); byte[] bytes = IOUtils.toByteArray(dataBuffer); NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(new UnpooledByteBufAllocator(false)); if (log.isDebugEnabled()) { log.debug("\n" + "{}Payload : {}", inOrOut, new String(bytes)); } DataBufferUtils.release(buffer); return (T) nettyDataBufferFactory.wrap(bytes); } catch (IOException e) { log.error(e.getMessage(), e); } return null; } }