diff --git a/Cargo.lock b/Cargo.lock index 7e3d9e9..c5f2f01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1569,11 +1569,12 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vcr-cassette" version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "364f53759622897886653050d8836272da6ba50f3a4f6ad7065a78ef7141554d" +source = "git+https://github.com/mpalmer/vcr-cassette.git?branch=full-body-workout#5345e13069d9008a4b17f27ad2eb4ed367f5cbcf" dependencies = [ "chrono", + "regex", "serde", + "serde_json", "url", "void", ] diff --git a/Cargo.toml b/Cargo.toml index 1ecd4a3..f1442b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,9 @@ name = "rvcr" [features] default = [] compress = ["dep:zip"] - +json = ["vcr-cassette/json"] +matching = ["vcr-cassette/matching"] +regex = ["vcr-cassette/regex"] [dependencies] anyhow = "^1" @@ -46,3 +48,5 @@ tracing-subscriber = { version = "0.3", features = ["registry", "env-filter"] } tracing-test = { version = "0.2.4", features = ["no-env-filter"] } url = "2.4" +[patch.crates-io] +vcr-cassette = { git = "https://github.com/mpalmer/vcr-cassette.git", branch = "full-body-workout" } diff --git a/src/lib.rs b/src/lib.rs index 7f9e4bd..2deec98 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -34,7 +34,7 @@ use std::{fs, path::PathBuf, str::FromStr, sync::Mutex}; use base64::{engine::general_purpose, Engine}; use reqwest_middleware::Middleware; -use vcr_cassette::{HttpInteraction, RecorderId}; +use vcr_cassette::{Body, HttpInteraction, RecorderId}; pub const VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -166,7 +166,7 @@ impl VCRMiddleware { Err(e) => { tracing::debug!("Can not deserialize utf-8 string: {e:?}"); let base64_str = general_purpose::STANDARD_NO_PAD.encode(body_bytes); - vcr_cassette::Body { + vcr_cassette::Body::EncodedString { string: base64_str, encoding: Some(BASE64.to_string()), } @@ -323,9 +323,9 @@ impl VCRMiddleware { diff.push_str(" Body differs:\n"); diff.push_str(&format!( " recorded: \"{}\"\n", - interaction.request.body.string + interaction.request.body )); - diff.push_str(&format!(" got: \"{}\"\n", req.body.string)); + diff.push_str(&format!(" got: \"{}\"\n", req.body)); } diff.push('\n'); } @@ -353,25 +353,28 @@ impl VCRMiddleware { ); let builder = builder.version(http_version); - match response.body.encoding { - None => { - if !response.body.string.is_empty() { - reqwest::Response::from(builder.body(response.body.string).unwrap()) - } else { - reqwest::Response::from(builder.body("".as_bytes()).unwrap()) - } - } - Some(encoding) => { - if encoding == "base64" { - let decoded = general_purpose::STANDARD_NO_PAD - .decode(encoding) - .expect("Invalid response body base64 can not be decoded"); - reqwest::Response::from(builder.body(decoded).unwrap()) - } else { - // FIXME: support more encodings - panic!("Unsupported encoding: {encoding}"); - } - } + match response.body { + Body::String(s) => reqwest::Response::from(builder.body(s.clone()).unwrap()), + Body::EncodedString { encoding, string } => match encoding.as_deref() { + Some("base64") => reqwest::Response::from( + builder + .body( + general_purpose::STANDARD_NO_PAD + .decode(string) + .expect("invalid response body, base64 decoding failed"), + ) + .unwrap(), + ), + Some(enc) => panic!("Unsupported encoding: {enc}"), + None => reqwest::Response::from(builder.body(string.clone()).unwrap()), + }, + #[cfg(feature = "json")] + Body::Json(j) => reqwest::Response::from( + builder + .body(serde_json::to_string(&j).expect("invalid JSON response body")) + .unwrap(), + ), + b => panic!("Unsupported response body specification: {b:?}"), } }