|
15 | 15 | */
|
16 | 16 | package io.rsocket.core;
|
17 | 17 |
|
| 18 | +import static io.rsocket.core.PayloadValidationUtils.assertValidateSetup; |
| 19 | + |
18 | 20 | import io.netty.buffer.ByteBuf;
|
19 | 21 | import io.netty.buffer.Unpooled;
|
20 | 22 | import io.rsocket.ConnectionSetupPayload;
|
@@ -92,7 +94,7 @@ public class RSocketConnector {
|
92 | 94 | private Supplier<Leases<?>> leasesSupplier;
|
93 | 95 |
|
94 | 96 | private int mtu = 0;
|
95 |
| - private int maxReassemblySize = Integer.MAX_VALUE; |
| 97 | + private int maxInboundPayloadSize = Integer.MAX_VALUE; |
96 | 98 | private PayloadDecoder payloadDecoder = PayloadDecoder.DEFAULT;
|
97 | 99 |
|
98 | 100 | private RSocketConnector() {}
|
@@ -419,14 +421,18 @@ public RSocketConnector lease(Supplier<Leases<? extends LeaseStats>> supplier) {
|
419 | 421 | * <p>By default this is not set in which case maximum reassembled payloads size is not
|
420 | 422 | * controlled.
|
421 | 423 | *
|
422 |
| - * @param maxReassemblySize the threshold size for reassembly, must be no less than 16,777,215 |
| 424 | + * @param maxInboundPayloadSize the threshold size for reassembly, must no be less than 64 bytes. |
| 425 | + * Please note, {@code maxInboundPayloadSize} must always be greater or equal to {@link |
| 426 | + * io.rsocket.transport.Transport#maxFrameLength()}, otherwise inbound frame can exceed the |
| 427 | + * {@code maxInboundPayloadSize} |
423 | 428 | * @return the same instance for method chaining
|
424 | 429 | * @see <a
|
425 | 430 | * href="https://github.com/rsocket/rsocket/blob/master/Protocol.md#fragmentation-and-reassembly">Fragmentation
|
426 | 431 | * and Reassembly</a>
|
427 | 432 | */
|
428 |
| - public RSocketConnector reassemble(int maxReassemblySize) { |
429 |
| - this.maxReassemblySize = ReassemblyDuplexConnection.assertMaxReassemblySize(maxReassemblySize); |
| 433 | + public RSocketConnector maxInboundPayloadSize(int maxInboundPayloadSize) { |
| 434 | + this.maxInboundPayloadSize = |
| 435 | + ReassemblyDuplexConnection.assertInboundPayloadSize(maxInboundPayloadSize); |
430 | 436 | return this;
|
431 | 437 | }
|
432 | 438 |
|
@@ -506,122 +512,142 @@ public Mono<RSocket> connect(ClientTransport transport) {
|
506 | 512 | */
|
507 | 513 | public Mono<RSocket> connect(Supplier<ClientTransport> transportSupplier) {
|
508 | 514 |
|
509 |
| - Mono<DuplexConnection> connectionMono = |
510 |
| - Mono.fromSupplier(transportSupplier) |
511 |
| - .flatMap(ClientTransport::connect) |
512 |
| - .map( |
513 |
| - connection -> |
514 |
| - mtu > 0 |
515 |
| - ? new FragmentationDuplexConnection( |
516 |
| - connection, mtu, maxReassemblySize, "client") |
517 |
| - : new ReassemblyDuplexConnection(connection, maxReassemblySize)); |
518 |
| - return connectionMono |
519 |
| - .flatMap( |
520 |
| - connection -> |
521 |
| - setupPayloadMono |
522 |
| - .defaultIfEmpty(EmptyPayload.INSTANCE) |
523 |
| - .map(setupPayload -> Tuples.of(connection, setupPayload)) |
524 |
| - .doOnError(ex -> connection.dispose()) |
525 |
| - .doOnCancel(connection::dispose)) |
| 515 | + return Mono.fromSupplier(transportSupplier) |
526 | 516 | .flatMap(
|
527 |
| - tuple -> { |
528 |
| - DuplexConnection connection = tuple.getT1(); |
529 |
| - Payload setupPayload = tuple.getT2(); |
530 |
| - |
531 |
| - ByteBuf resumeToken; |
532 |
| - KeepAliveHandler keepAliveHandler; |
533 |
| - DuplexConnection wrappedConnection; |
534 |
| - |
535 |
| - if (resume != null) { |
536 |
| - resumeToken = resume.getTokenSupplier().get(); |
537 |
| - ClientRSocketSession session = |
538 |
| - new ClientRSocketSession( |
539 |
| - connection, |
540 |
| - resume.getSessionDuration(), |
541 |
| - resume.getRetry(), |
542 |
| - resume.getStoreFactory(CLIENT_TAG).apply(resumeToken), |
543 |
| - resume.getStreamTimeout(), |
544 |
| - resume.isCleanupStoreOnKeepAlive()) |
545 |
| - .continueWith(connectionMono) |
546 |
| - .resumeToken(resumeToken); |
547 |
| - keepAliveHandler = |
548 |
| - new KeepAliveHandler.ResumableKeepAliveHandler(session.resumableConnection()); |
549 |
| - wrappedConnection = session.resumableConnection(); |
550 |
| - } else { |
551 |
| - resumeToken = Unpooled.EMPTY_BUFFER; |
552 |
| - keepAliveHandler = new KeepAliveHandler.DefaultKeepAliveHandler(connection); |
553 |
| - wrappedConnection = connection; |
554 |
| - } |
555 |
| - |
556 |
| - ClientServerInputMultiplexer multiplexer = |
557 |
| - new ClientServerInputMultiplexer(wrappedConnection, interceptors, true); |
558 |
| - |
559 |
| - boolean leaseEnabled = leasesSupplier != null; |
560 |
| - Leases<?> leases = leaseEnabled ? leasesSupplier.get() : null; |
561 |
| - RequesterLeaseHandler requesterLeaseHandler = |
562 |
| - leaseEnabled |
563 |
| - ? new RequesterLeaseHandler.Impl(CLIENT_TAG, leases.receiver()) |
564 |
| - : RequesterLeaseHandler.None; |
565 |
| - |
566 |
| - RSocket rSocketRequester = |
567 |
| - new RSocketRequester( |
568 |
| - multiplexer.asClientConnection(), |
569 |
| - payloadDecoder, |
570 |
| - StreamIdSupplier.clientSupplier(), |
571 |
| - mtu, |
572 |
| - (int) keepAliveInterval.toMillis(), |
573 |
| - (int) keepAliveMaxLifeTime.toMillis(), |
574 |
| - keepAliveHandler, |
575 |
| - requesterLeaseHandler, |
576 |
| - Schedulers.single(Schedulers.parallel())); |
577 |
| - |
578 |
| - RSocket wrappedRSocketRequester = interceptors.initRequester(rSocketRequester); |
579 |
| - |
580 |
| - ByteBuf setupFrame = |
581 |
| - SetupFrameCodec.encode( |
582 |
| - wrappedConnection.alloc(), |
583 |
| - leaseEnabled, |
584 |
| - (int) keepAliveInterval.toMillis(), |
585 |
| - (int) keepAliveMaxLifeTime.toMillis(), |
586 |
| - resumeToken, |
587 |
| - metadataMimeType, |
588 |
| - dataMimeType, |
589 |
| - setupPayload); |
590 |
| - |
591 |
| - SocketAcceptor acceptor = |
592 |
| - this.acceptor != null ? this.acceptor : SocketAcceptor.with(new RSocket() {}); |
593 |
| - |
594 |
| - ConnectionSetupPayload setup = new DefaultConnectionSetupPayload(setupFrame); |
595 |
| - |
596 |
| - return interceptors |
597 |
| - .initSocketAcceptor(acceptor) |
598 |
| - .accept(setup, wrappedRSocketRequester) |
| 517 | + ct -> { |
| 518 | + int maxFrameLength = ct.maxFrameLength(); |
| 519 | + |
| 520 | + Mono<DuplexConnection> connectionMono = |
| 521 | + Mono.fromCallable( |
| 522 | + () -> { |
| 523 | + assertValidateSetup(maxFrameLength, maxInboundPayloadSize, mtu); |
| 524 | + return ct; |
| 525 | + }) |
| 526 | + .flatMap(ClientTransport::connect) |
| 527 | + .map( |
| 528 | + connection -> |
| 529 | + mtu > 0 |
| 530 | + ? new FragmentationDuplexConnection( |
| 531 | + connection, mtu, maxInboundPayloadSize, "client") |
| 532 | + : new ReassemblyDuplexConnection( |
| 533 | + connection, maxInboundPayloadSize)); |
| 534 | + |
| 535 | + return connectionMono |
599 | 536 | .flatMap(
|
600 |
| - rSocketHandler -> { |
601 |
| - RSocket wrappedRSocketHandler = interceptors.initResponder(rSocketHandler); |
602 |
| - |
603 |
| - ResponderLeaseHandler responderLeaseHandler = |
| 537 | + connection -> |
| 538 | + setupPayloadMono |
| 539 | + .defaultIfEmpty(EmptyPayload.INSTANCE) |
| 540 | + .map(setupPayload -> Tuples.of(connection, setupPayload)) |
| 541 | + .doOnError(ex -> connection.dispose()) |
| 542 | + .doOnCancel(connection::dispose)) |
| 543 | + .flatMap( |
| 544 | + tuple -> { |
| 545 | + DuplexConnection connection = tuple.getT1(); |
| 546 | + Payload setupPayload = tuple.getT2(); |
| 547 | + ByteBuf resumeToken; |
| 548 | + KeepAliveHandler keepAliveHandler; |
| 549 | + DuplexConnection wrappedConnection; |
| 550 | + |
| 551 | + if (resume != null) { |
| 552 | + resumeToken = resume.getTokenSupplier().get(); |
| 553 | + ClientRSocketSession session = |
| 554 | + new ClientRSocketSession( |
| 555 | + connection, |
| 556 | + resume.getSessionDuration(), |
| 557 | + resume.getRetry(), |
| 558 | + resume.getStoreFactory(CLIENT_TAG).apply(resumeToken), |
| 559 | + resume.getStreamTimeout(), |
| 560 | + resume.isCleanupStoreOnKeepAlive()) |
| 561 | + .continueWith(connectionMono) |
| 562 | + .resumeToken(resumeToken); |
| 563 | + keepAliveHandler = |
| 564 | + new KeepAliveHandler.ResumableKeepAliveHandler( |
| 565 | + session.resumableConnection()); |
| 566 | + wrappedConnection = session.resumableConnection(); |
| 567 | + } else { |
| 568 | + resumeToken = Unpooled.EMPTY_BUFFER; |
| 569 | + keepAliveHandler = |
| 570 | + new KeepAliveHandler.DefaultKeepAliveHandler(connection); |
| 571 | + wrappedConnection = connection; |
| 572 | + } |
| 573 | + |
| 574 | + ClientServerInputMultiplexer multiplexer = |
| 575 | + new ClientServerInputMultiplexer(wrappedConnection, interceptors, true); |
| 576 | + |
| 577 | + boolean leaseEnabled = leasesSupplier != null; |
| 578 | + Leases<?> leases = leaseEnabled ? leasesSupplier.get() : null; |
| 579 | + RequesterLeaseHandler requesterLeaseHandler = |
604 | 580 | leaseEnabled
|
605 |
| - ? new ResponderLeaseHandler.Impl<>( |
606 |
| - CLIENT_TAG, |
607 |
| - wrappedConnection.alloc(), |
608 |
| - leases.sender(), |
609 |
| - leases.stats()) |
610 |
| - : ResponderLeaseHandler.None; |
611 |
| - |
612 |
| - RSocket rSocketResponder = |
613 |
| - new RSocketResponder( |
614 |
| - multiplexer.asServerConnection(), |
615 |
| - wrappedRSocketHandler, |
| 581 | + ? new RequesterLeaseHandler.Impl(CLIENT_TAG, leases.receiver()) |
| 582 | + : RequesterLeaseHandler.None; |
| 583 | + |
| 584 | + RSocket rSocketRequester = |
| 585 | + new RSocketRequester( |
| 586 | + multiplexer.asClientConnection(), |
616 | 587 | payloadDecoder,
|
617 |
| - responderLeaseHandler, |
618 |
| - mtu); |
619 |
| - |
620 |
| - return wrappedConnection |
621 |
| - .sendOne(setupFrame.retain()) |
622 |
| - .thenReturn(wrappedRSocketRequester); |
623 |
| - }) |
624 |
| - .doFinally(signalType -> setup.release()); |
| 588 | + StreamIdSupplier.clientSupplier(), |
| 589 | + mtu, |
| 590 | + maxFrameLength, |
| 591 | + (int) keepAliveInterval.toMillis(), |
| 592 | + (int) keepAliveMaxLifeTime.toMillis(), |
| 593 | + keepAliveHandler, |
| 594 | + requesterLeaseHandler, |
| 595 | + Schedulers.single(Schedulers.parallel())); |
| 596 | + |
| 597 | + RSocket wrappedRSocketRequester = |
| 598 | + interceptors.initRequester(rSocketRequester); |
| 599 | + |
| 600 | + ByteBuf setupFrame = |
| 601 | + SetupFrameCodec.encode( |
| 602 | + wrappedConnection.alloc(), |
| 603 | + leaseEnabled, |
| 604 | + (int) keepAliveInterval.toMillis(), |
| 605 | + (int) keepAliveMaxLifeTime.toMillis(), |
| 606 | + resumeToken, |
| 607 | + metadataMimeType, |
| 608 | + dataMimeType, |
| 609 | + setupPayload); |
| 610 | + |
| 611 | + SocketAcceptor acceptor = |
| 612 | + this.acceptor != null |
| 613 | + ? this.acceptor |
| 614 | + : SocketAcceptor.with(new RSocket() {}); |
| 615 | + |
| 616 | + ConnectionSetupPayload setup = |
| 617 | + new DefaultConnectionSetupPayload(setupFrame); |
| 618 | + |
| 619 | + return interceptors |
| 620 | + .initSocketAcceptor(acceptor) |
| 621 | + .accept(setup, wrappedRSocketRequester) |
| 622 | + .flatMap( |
| 623 | + rSocketHandler -> { |
| 624 | + RSocket wrappedRSocketHandler = |
| 625 | + interceptors.initResponder(rSocketHandler); |
| 626 | + |
| 627 | + ResponderLeaseHandler responderLeaseHandler = |
| 628 | + leaseEnabled |
| 629 | + ? new ResponderLeaseHandler.Impl<>( |
| 630 | + CLIENT_TAG, |
| 631 | + wrappedConnection.alloc(), |
| 632 | + leases.sender(), |
| 633 | + leases.stats()) |
| 634 | + : ResponderLeaseHandler.None; |
| 635 | + |
| 636 | + RSocket rSocketResponder = |
| 637 | + new RSocketResponder( |
| 638 | + multiplexer.asServerConnection(), |
| 639 | + wrappedRSocketHandler, |
| 640 | + payloadDecoder, |
| 641 | + responderLeaseHandler, |
| 642 | + mtu, |
| 643 | + maxFrameLength); |
| 644 | + |
| 645 | + return wrappedConnection |
| 646 | + .sendOne(setupFrame.retain()) |
| 647 | + .thenReturn(wrappedRSocketRequester); |
| 648 | + }) |
| 649 | + .doFinally(signalType -> setup.release()); |
| 650 | + }); |
625 | 651 | })
|
626 | 652 | .as(
|
627 | 653 | source -> {
|
|
0 commit comments