Skip to content

Commit

Permalink
Move device fingerprinting from rquest to separate rquest-util packag…
Browse files Browse the repository at this point in the history
…e for maintenance
  • Loading branch information
0x676e67 committed Mar 3, 2025
1 parent 1138e2b commit 3a76ee4
Show file tree
Hide file tree
Showing 10 changed files with 289 additions and 191 deletions.
18 changes: 9 additions & 9 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ edition = "2021"
rust-version = "1.80"

[features]
default = ["impersonate"]
impersonate = ["dep:http", "dep:serde", "dep:typed-builder"]
impersonate-gzip = []
impersonate-brotli = []
impersonate-deflate = []
impersonate-zstd = []
default = ["emulation", "gzip", "brotli", "deflate", "zstd"]
emulation = ["dep:http", "dep:serde", "dep:typed-builder"]
gzip = ["rquest/gzip"]
brotli = ["rquest/brotli"]
deflate = ["rquest/deflate"]
zstd = ["rquest/zstd"]

[dependencies]
http = { version = "1", optional = true }
Expand All @@ -31,6 +31,6 @@ tokio = { version = "1", features = ["full"] }
doctest = false

[[example]]
name = "impersonate"
path = "examples/impersonate.rs"
required-features = ["impersonate", "impersonate-gzip", "impersonate-brotli", "impersonate-deflate", "impersonate-zstd", "rquest/full"]
name = "emulation"
path = "examples/emulation.rs"
required-features = ["emulation", "gzip", "brotli", "deflate", "zstd", "rquest/full"]
6 changes: 3 additions & 3 deletions examples/impersonate.rs → examples/emulation.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
use rquest::Client;
use rquest_util::Impersonate;
use rquest_util::Emulation;

#[tokio::main]
async fn main() -> Result<(), rquest::Error> {
// Build a client to impersonate Firefox133
// Build a client to emulation Firefox135
let client = Client::builder()
.impersonate(Impersonate::Firefox133)
.emulation(Emulation::Firefox133)
.build()?;

// Use the API you're already familiar with
Expand Down
36 changes: 18 additions & 18 deletions src/imp/chrome.rs → src/emulation/device/chrome.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::imp::impersonate_imports::*;
use super::emulation_imports::*;
use http2::*;
use tls::*;

Expand All @@ -14,30 +14,30 @@ macro_rules! mod_generator {
use super::*;

#[inline(always)]
pub fn http_context(option: ImpersonateOption) -> HttpContext {
pub fn emulation(option: EmulationOption) -> EmulationProvider {
#[allow(unreachable_patterns)]
match option.impersonate_os {
match option.emulation_os {
$(
ImpersonateOS::$other_os => HttpContext::builder()
EmulationOS::$other_os => EmulationProvider::builder()
.tls_config($tls_config)
.http2_config(conditional_http2!(option.skip_http2, $http2_config))
.default_headers(conditional_headers!(option.skip_headers, || {
$header_initializer(
$other_sec_ch_ua,
$other_ua,
ImpersonateOS::$other_os,
EmulationOS::$other_os,
)
}))
.build(),
)*
_ => HttpContext::builder()
_ => EmulationProvider::builder()
.tls_config($tls_config)
.http2_config(conditional_http2!(option.skip_http2, $http2_config))
.default_headers(conditional_headers!(option.skip_headers, || {
$header_initializer(
$default_sec_ch_ua,
$default_ua,
ImpersonateOS::$default_os,
EmulationOS::$default_os,
)
}))
.build(),
Expand Down Expand Up @@ -133,15 +133,15 @@ macro_rules! http2_config {
fn header_initializer(
sec_ch_ua: &'static str,
ua: &'static str,
impersonate_os: ImpersonateOS,
emulation_os: EmulationOS,
) -> HeaderMap {
let mut headers = HeaderMap::new();
header_chrome_accpet!(headers);
header_chrome_sec_ch_ua!(
headers,
sec_ch_ua,
impersonate_os.platform(),
impersonate_os.is_mobile()
emulation_os.platform(),
emulation_os.is_mobile()
);
header_chrome_sec_fetch!(headers);
header_chrome_ua!(headers, ua);
Expand All @@ -152,15 +152,15 @@ fn header_initializer(
fn header_initializer_with_zstd(
sec_ch_ua: &'static str,
ua: &'static str,
impersonate_os: ImpersonateOS,
emulation_os: EmulationOS,
) -> HeaderMap {
let mut headers = HeaderMap::new();
header_chrome_accpet!(zstd, headers);
header_chrome_sec_ch_ua!(
headers,
sec_ch_ua,
impersonate_os.platform(),
impersonate_os.is_mobile()
emulation_os.platform(),
emulation_os.is_mobile()
);
header_chrome_sec_fetch!(headers);
header_chrome_ua!(headers, ua);
Expand All @@ -171,24 +171,24 @@ fn header_initializer_with_zstd(
fn header_initializer_with_zstd_priority(
sec_ch_ua: &'static str,
ua: &'static str,
impersonate_os: ImpersonateOS,
emulation_os: EmulationOS,
) -> HeaderMap {
let mut headers = HeaderMap::new();
header_chrome_accpet!(zstd, headers);
headers.insert("priority", HeaderValue::from_static("u=0, i"));
header_chrome_sec_ch_ua!(
headers,
sec_ch_ua,
impersonate_os.platform(),
impersonate_os.is_mobile()
emulation_os.platform(),
emulation_os.is_mobile()
);
header_chrome_sec_fetch!(headers);
header_chrome_ua!(headers, ua);
headers
}

mod tls {
use crate::imp::tls_imports::*;
use super::super::tls_imports::*;

pub const CURVES_1: &[SslCurve] = &[SslCurve::X25519, SslCurve::SECP256R1, SslCurve::SECP384R1];

Expand Down Expand Up @@ -290,7 +290,7 @@ mod tls {
}

mod http2 {
use crate::imp::http2_imports::*;
use super::super::http2_imports::*;

pub const HEADER_PRIORITY: (u32, u8, bool) = (0, 255, true);

Expand Down
123 changes: 115 additions & 8 deletions src/imp/firefox.rs → src/emulation/device/firefox.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use super::impersonate_imports::*;
use super::emulation_imports::*;
use http2::*;
use tls::*;

Expand All @@ -14,20 +14,20 @@ macro_rules! mod_generator {
use super::*;

#[inline(always)]
pub fn http_context(option: ImpersonateOption) -> HttpContext {
pub fn emulation(option: EmulationOption) -> EmulationProvider {
#[allow(unreachable_patterns)]
match option.impersonate_os {
match option.emulation_os {
$(
ImpersonateOS::$other_os => {
HttpContext::builder()
EmulationOS::$other_os => {
EmulationProvider::builder()
.tls_config($tls_config)
.http2_config(conditional_http2!(option.skip_http2, $http2_config))
.default_headers(conditional_headers!(option.skip_headers, $header_initializer, $other_ua))
.build()
}
),*
_ => {
HttpContext::builder()
EmulationProvider::builder()
.tls_config($tls_config)
.http2_config(conditional_http2!(option.skip_http2, $http2_config))
.default_headers(conditional_headers!(option.skip_headers, $header_initializer, $default_ua))
Expand Down Expand Up @@ -68,6 +68,42 @@ macro_rules! tls_config {
.key_shares_limit(2)
.build()
};
(4, $cipher_list:expr, $curves:expr) => {
FirefoxTlsConfig::builder()
.cipher_list($cipher_list)
.curves($curves)
.enable_ech_grease(true)
.enable_signed_cert_timestamps(true)
.session_ticket(true)
.pre_shared_key(true)
.psk_skip_session_tickets(true)
.key_shares_limit(3)
.cert_compression_algorithm(CERT_COMPRESSION_ALGORITHM)
.build()
};
(5, $cipher_list:expr, $curves:expr) => {
FirefoxTlsConfig::builder()
.cipher_list($cipher_list)
.curves($curves)
.enable_ech_grease(true)
.pre_shared_key(true)
.psk_skip_session_tickets(true)
.key_shares_limit(2)
.cert_compression_algorithm(CERT_COMPRESSION_ALGORITHM)
.build()
};
(6, $cipher_list:expr, $curves:expr) => {
FirefoxTlsConfig::builder()
.cipher_list($cipher_list)
.curves($curves)
.enable_ech_grease(true)
.enable_signed_cert_timestamps(true)
.session_ticket(false)
.psk_dhe_ke(false)
.key_shares_limit(3)
.cert_compression_algorithm(CERT_COMPRESSION_ALGORITHM)
.build()
};
}

macro_rules! http2_config {
Expand Down Expand Up @@ -111,6 +147,19 @@ macro_rules! http2_config {
.settings_order(SETTINGS_ORDER)
.build()
};
(4) => {
Http2Config::builder()
.initial_stream_id(3)
.header_table_size(4096)
.enable_push(false)
.initial_stream_window_size(32768)
.max_frame_size(16384)
.initial_connection_window_size(12517377 + 65535)
.headers_priority(HEADER_PRIORITY)
.headers_pseudo_order(HEADERS_PSEUDO_ORDER)
.settings_order(SETTINGS_ORDER)
.build()
};
}

#[inline]
Expand All @@ -136,7 +185,7 @@ fn header_initializer_with_zstd(ua: &'static str) -> HeaderMap {
}

mod tls {
use crate::imp::tls_imports::*;
use super::super::tls_imports::*;

pub const CURVES_1: &[SslCurve] = &[
SslCurve::X25519,
Expand Down Expand Up @@ -239,6 +288,7 @@ mod tls {
ExtensionType::APPLICATION_LAYER_PROTOCOL_NEGOTIATION,
ExtensionType::STATUS_REQUEST,
ExtensionType::DELEGATED_CREDENTIAL,
ExtensionType::CERTIFICATE_TIMESTAMP,
ExtensionType::KEY_SHARE,
ExtensionType::SUPPORTED_VERSIONS,
ExtensionType::SIGNATURE_ALGORITHMS,
Expand Down Expand Up @@ -277,6 +327,9 @@ mod tls {
#[builder(default = false, setter(into))]
enable_ech_grease: bool,

#[builder(default = false, setter(into))]
enable_signed_cert_timestamps: bool,

#[builder(default = false, setter(into))]
pre_shared_key: bool,

Expand Down Expand Up @@ -313,6 +366,7 @@ mod tls {
.record_size_limit(val.record_size_limit)
.enable_ocsp_stapling(true)
.enable_ech_grease(val.enable_ech_grease)
.enable_signed_cert_timestamps(val.enable_signed_cert_timestamps)
.alpn_protos(AlpnProtos::ALL)
.min_tls_version(TlsVersion::TLS_1_2)
.max_tls_version(TlsVersion::TLS_1_3)
Expand All @@ -328,7 +382,7 @@ mod tls {
}

mod http2 {
use crate::imp::http2_imports::*;
use super::super::http2_imports::*;

pub const HEADER_PRIORITY: (u32, u8, bool) = (0, 41, false);

Expand Down Expand Up @@ -470,3 +524,56 @@ mod_generator!(
)
]
);

mod_generator!(
ff135,
tls_config!(4, CIPHER_LIST_1, CURVES_2),
http2_config!(1),
header_initializer_with_zstd,
[
(
MacOS,
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0"
),
(
Windows,
"Mozilla/5.0 (Windows NT 10.0; rv:135.0) Gecko/20100101 Firefox/135.0"
),
(
Linux,
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0"
)
]
);

mod_generator!(
ff_private_135,
tls_config!(6, CIPHER_LIST_1, CURVES_2),
http2_config!(1),
header_initializer_with_zstd,
[
(
MacOS,
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:135.0) Gecko/20100101 Firefox/135.0"
),
(
Windows,
"Mozilla/5.0 (Windows NT 10.0; rv:135.0) Gecko/20100101 Firefox/135.0"
),
(
Linux,
"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0"
)
]
);

mod_generator!(
ff_android_135,
tls_config!(5, CIPHER_LIST_1, CURVES_1),
http2_config!(4),
header_initializer_with_zstd,
[(
Android,
"Mozilla/5.0 (Android 13; Mobile; rv:135.0) Gecko/135.0 Firefox/135.0"
)]
);
Loading

0 comments on commit 3a76ee4

Please sign in to comment.