cloud-sdk-reqwest 0.27.0

Optional provider-neutral reqwest transport boundary for cloud-sdk.
Documentation
use std::time::Duration;

use cloud_sdk::Method;
use cloud_sdk::transport::{
    AsyncRawHttpExecutor, ContentType, DeliveryPhase, RequestHeader, RequestHeaders,
    ResponseBuffer, TransportRequest,
};

use super::{build_raw_loopback, policy};
use crate::asynchronous::{MAX_RAW_REQUEST_BODY_BYTES, RawHttpError};
use crate::test_server::spawn;

#[test]
fn public_path_accepts_exact_and_rejects_plus_one_request_body() {
    super::super::run_async_test(async {
        let Ok(server) = spawn(
            "200 OK",
            &[("Content-Type", "application/json")],
            b"{}",
            Duration::ZERO,
        ) else {
            return;
        };
        let Some(client) = build_raw_loopback(&server.endpoint) else {
            return;
        };
        let Ok(target) = cloud_sdk::transport::RequestTarget::new("/servers") else {
            return;
        };
        let header_values = [RequestHeader::content_type(ContentType::JSON)];
        let Ok(headers) = RequestHeaders::new(&header_values) else {
            return;
        };
        let Some(policy) = policy(2) else { return };
        let exact = std::vec![0x5a; MAX_RAW_REQUEST_BODY_BYTES];
        let mut body = [0xa5_u8; 16];
        let mut header_storage = [0xa5_u8; 128];
        let mut response = ResponseBuffer::new(&mut body, 16, &mut header_storage);
        assert!(
            client
                .execute(
                    TransportRequest::new(Method::Post, target)
                        .with_headers(headers)
                        .with_body(&exact),
                    policy,
                    response.writer(),
                )
                .await
                .is_ok()
        );
        drop(exact);

        let Some(client) = build_raw_loopback("http://127.0.0.1:9/v1") else {
            return;
        };
        let oversized = std::vec![0x5a; MAX_RAW_REQUEST_BODY_BYTES.saturating_add(1)];
        let mut body = [0xa5_u8; 16];
        let mut header_storage = [0xa5_u8; 128];
        let mut response = ResponseBuffer::new(&mut body, 16, &mut header_storage);
        assert!(matches!(
            client
                .execute(
                    TransportRequest::new(Method::Post, target)
                        .with_headers(headers)
                        .with_body(&oversized),
                    policy,
                    response.writer(),
                )
                .await,
            Err(error)
                if error.phase() == DeliveryPhase::NotSent
                    && error.error() == &RawHttpError::RequestBodyTooLarge
        ));
    });
}