From ec1bc9efc1991cbb243ae01835ef5c81981eae77 Mon Sep 17 00:00:00 2001 From: 0x676e67 Date: Fri, 16 Aug 2024 13:19:38 +0800 Subject: [PATCH] feat(client): Add `impersonate_with_headers` allows optionally setting request headers (#127) --- examples/impersonate_with_headers.rs | 18 ++++++++++++++ src/client/client.rs | 35 +++++++++++++++++++++++----- 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 examples/impersonate_with_headers.rs diff --git a/examples/impersonate_with_headers.rs b/examples/impersonate_with_headers.rs new file mode 100644 index 0000000..4bb948b --- /dev/null +++ b/examples/impersonate_with_headers.rs @@ -0,0 +1,18 @@ +use rquest::tls::Impersonate; +use std::error::Error; + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Build a client to mimic Edge127 with headers + let client = rquest::Client::builder() + .impersonate_with_headers(Impersonate::Edge127, false) + .enable_ech_grease() + .permute_extensions() + .build()?; + + // Use the API you're already familiar with + let resp = client.get("https://tls.peet.ws/api/all").send().await?; + println!("{}", resp.text().await?); + + Ok(()) +} diff --git a/src/client/client.rs b/src/client/client.rs index a080a2a..cd15d74 100644 --- a/src/client/client.rs +++ b/src/client/client.rs @@ -264,29 +264,52 @@ impl ClientBuilder { /// This is only available with the `boring-tls` feature. #[cfg(feature = "boring-tls")] pub fn impersonate(self, impersonate: Impersonate) -> ClientBuilder { + self.impersonate_with_headers(impersonate, true) + } + + /// Sets the necessary values to mimic the specified impersonate version (with headers). + /// This will set the necessary headers and TLS settings. + /// This is only available with the `boring-tls` feature. + #[cfg(feature = "boring-tls")] + pub fn impersonate_with_headers( + self, + impersonate: Impersonate, + set_headers: bool, + ) -> ClientBuilder { // Try to get the settings for the impersonate version - if let Ok((settings, func)) = tls::tls_settings(impersonate) { - return self.apply_tls_settings(settings, func); + if let Ok((settings, header_initializer)) = tls::tls_settings(impersonate) { + return self.apply_tls_settings(settings, header_initializer, set_headers); } self } /// Use the preconfigured TLS settings. #[cfg(feature = "boring-tls")] - pub fn use_preconfigured_tls(self, settings: TlsSettings, func: F) -> ClientBuilder + pub fn use_preconfigured_tls( + self, + settings: TlsSettings, + header_initializer: F, + ) -> ClientBuilder where F: FnOnce(&mut HeaderMap), { - self.apply_tls_settings(settings, func) + self.apply_tls_settings(settings, header_initializer, true) } /// Apply the given TLS settings and header function. #[cfg(feature = "boring-tls")] - fn apply_tls_settings(mut self, settings: TlsSettings, func: F) -> ClientBuilder + fn apply_tls_settings( + mut self, + settings: TlsSettings, + header_initializer: F, + set_headers: bool, + ) -> ClientBuilder where F: FnOnce(&mut HeaderMap), { - func(&mut self.config.headers); + if set_headers { + header_initializer(&mut self.config.headers); + } self.config.tls.builder = Some(settings.builder); self.config.tls.extension = settings.extension;