Skip to content
This repository has been archived by the owner on Jan 16, 2025. It is now read-only.

feat(client): Add impersonate_with_headers allows optionally setting request headers #127

Merged
merged 5 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions examples/impersonate_with_headers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use rquest::tls::Impersonate;
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 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(())
}
35 changes: 29 additions & 6 deletions src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<F>(self, settings: TlsSettings, func: F) -> ClientBuilder
pub fn use_preconfigured_tls<F>(
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<F>(mut self, settings: TlsSettings, func: F) -> ClientBuilder
fn apply_tls_settings<F>(
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;

Expand Down
Loading