fn scheduled_renegotiate_with_async_init()

in bindings/rust/extended/s2n-tls/src/renegotiate.rs [1065:1129]


    fn scheduled_renegotiate_with_async_init() -> Result<(), Box<dyn Error>> {
        // To test that the initializer method triggers again on the second
        // handshake, we need to set an easily verified connection-level value.
        #[derive(Clone)]
        struct TestInitializer {
            count: usize,
            context: String,
        }
        impl ConnectionInitializer for TestInitializer {
            fn initialize_connection(
                &self,
                _: &mut crate::connection::Connection,
            ) -> ConnectionFutureResult {
                Ok(Some(Box::pin(self.clone())))
            }
        }
        impl ConnectionFuture for TestInitializer {
            fn poll(
                self: Pin<&mut Self>,
                conn: &mut Connection,
                ctx: &mut core::task::Context,
            ) -> Poll<Result<(), crate::error::Error>> {
                ctx.waker().wake_by_ref();
                let this = self.get_mut();
                // Assert that nothing is currently set
                assert!(conn.application_context::<String>().is_none());
                if this.count > 1 {
                    // Repeatedly block the handshake in order to verify
                    // that renegotiate can handle Pending callbacks.
                    this.count -= 1;
                    Pending
                } else {
                    conn.set_application_context(this.context.clone());
                    Ready(Ok(()))
                }
            }
        }

        let count_per_handshake = 10;
        let expected_context = "helloworld".to_owned();
        let initializer = TestInitializer {
            count: count_per_handshake,
            context: expected_context.clone(),
        };

        let mut builder = config::Builder::new();
        builder.set_renegotiate_callback(RenegotiateResponse::Schedule)?;
        builder.set_connection_initializer(initializer)?;
        let mut pair = RenegotiateTestPair::from(builder)?;

        let (waker, wake_count) = new_count_waker();
        pair.client.set_waker(Some(&waker))?;

        pair.handshake().expect("Initial handshake");
        assert_eq!(wake_count, count_per_handshake);
        pair.send_renegotiate_request()
            .expect("Server sends request");
        pair.assert_renegotiate()?;
        assert_eq!(wake_count, count_per_handshake * 2);

        let context: Option<&String> = pair.client.application_context();
        assert_eq!(Some(&expected_context), context);

        Ok(())
    }