Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add impersonate-chrome and impersonate-ff features (#482) #483

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ zlib-ng-compat = ["curl-sys/zlib-ng-compat", "static-curl"]
upkeep_7_62_0 = ["curl-sys/upkeep_7_62_0"]
poll_7_68_0 = ["curl-sys/poll_7_68_0"]
ntlm = ["curl-sys/ntlm"]
impersonate-chrome = ["curl-sys/impersonate-chrome"]
impersonate-ff = ["curl-sys/impersonate-ff"]

[[test]]
name = "atexit"
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ with various Cargo features:
- `poll_7_68_0`: Enable curl_multi_poll()/curl_multi_wakeup() support, requires curl 7.68.0 or later. Disabled by default.
- `ntlm`: Enable NTLM support in curl. Disabled by default.
- `windows-static-ssl`: Enable Openssl support on Windows via the static build provided by vcpkg. Incompatible with `ssl` (use `--no-default-features`). Disabled by default.
- `impersonate-chrome`: Use [curl-impersonate](curl-impersonate) in chrome flavor. Incompatible with `static-curl`, enforces built-in BoringSSL as TLS backend.
- `impersonate-ff`: Use [curl-impersonate](curl-impersonate) in firefox flavor. Incompatible with `static-curl`, enforces built-in NSS as TLS backend.

Note that to install openssl on windows via vcpkg the following commands needs to be ran:
```shell
Expand Down Expand Up @@ -182,3 +184,4 @@ details.
[Rustls]: https://github.com/ctz/rustls
[Schannel]: https://docs.microsoft.com/en-us/windows/win32/com/schannel
[Secure Transport]: https://developer.apple.com/documentation/security/secure_transport
[curl-impersonate]: https://github.com/lwthiker/curl-impersonate
2 changes: 2 additions & 0 deletions curl-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,5 @@ zlib-ng-compat = ["libz-sys/zlib-ng", "static-curl"]
upkeep_7_62_0 = []
poll_7_68_0 = []
ntlm = []
impersonate-chrome = []
impersonate-ff = []
52 changes: 40 additions & 12 deletions curl-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,31 @@ fn main() {
let host = env::var("HOST").unwrap();
let target = env::var("TARGET").unwrap();
let windows = target.contains("windows");
let curlname = if cfg!(feature = "impersonate-chrome") {
"curl-impersonate-chrome"
} else if cfg!(feature = "impersonate-ff") {
"curl-impersonate-ff"
} else {
"curl"
};
let libname = format!("lib{curlname}");
let configname = format!("{curlname}-config");

if cfg!(feature = "mesalink") {
println!("cargo:warning=MesaLink support has been removed as of curl 7.82.0, will use default TLS backend instead.");
}

if cfg!(feature = "impersonate-chrome") && cfg!(feature = "impersonate-ff") {
panic!("impersonate-chrome and impersonate-ff features cannot be both enabled");
}
if (cfg!(feature = "impersonate-chrome") || cfg!(feature = "impersonate-ff"))
&& cfg!(feature = "static-curl")
{
panic!(
"impersonate-chrome and impersonate-ff features don't work together with static-curl"
);
}

// This feature trumps all others, and is largely set by rustbuild to force
// usage of the system library to ensure that we're always building an
// ABI-compatible Cargo.
Expand All @@ -31,7 +51,9 @@ fn main() {
if !cfg!(feature = "static-curl") {
// OSX ships libcurl by default, so we just use that version
// so long as it has the right features enabled.
if target.contains("apple") && (!cfg!(feature = "http2") || curl_config_reports_http2()) {
if target.contains("apple")
&& (!cfg!(feature = "http2") || curl_config_reports_http2(&configname, &libname))
{
return println!("cargo:rustc-flags=-l curl");
}

Expand All @@ -40,11 +62,17 @@ fn main() {
if try_vcpkg() {
return;
}
} else if try_pkg_config() {
} else if try_pkg_config(&configname, &libname) {
return;
}
}

if cfg!(feature = "impersonate-chrome") || cfg!(feature = "impersonate-ff") {
panic!(
"impersonate feature is enabled, but {} was not found in system. fallback to static not available", libname
);
}

if !Path::new("curl/.git").exists() {
let _ = Command::new("git")
.args(&["submodule", "update", "--init"])
Expand Down Expand Up @@ -500,14 +528,14 @@ fn try_vcpkg() -> bool {
false
}

fn try_pkg_config() -> bool {
fn try_pkg_config(configname: &str, libname: &str) -> bool {
let mut cfg = pkg_config::Config::new();
cfg.cargo_metadata(false);
let lib = match cfg.probe("libcurl") {
let lib = match cfg.probe(libname) {
Ok(lib) => lib,
Err(e) => {
println!(
"Couldn't find libcurl from pkgconfig ({:?}), \
"Couldn't find {libname} from pkgconfig ({:?}), \
compiling it from source...",
e
);
Expand All @@ -517,13 +545,13 @@ fn try_pkg_config() -> bool {

// Not all system builds of libcurl have http2 features enabled, so if we've
// got a http2-requested build then we may fall back to a build from source.
if cfg!(feature = "http2") && !curl_config_reports_http2() {
if cfg!(feature = "http2") && !curl_config_reports_http2(configname, libname) {
return false;
}

// Re-find the library to print cargo's metadata, then print some extra
// metadata as well.
cfg.cargo_metadata(true).probe("libcurl").unwrap();
cfg.cargo_metadata(true).probe(libname).unwrap();
for path in lib.include_paths.iter() {
println!("cargo:include={}", path.display());
}
Expand All @@ -548,24 +576,24 @@ fn xcode_major_version() -> Option<u8> {
None
}

fn curl_config_reports_http2() -> bool {
let output = Command::new("curl-config").arg("--features").output();
fn curl_config_reports_http2(configname: &str, libname: &str) -> bool {
let output = Command::new(configname).arg("--features").output();
let output = match output {
Ok(out) => out,
Err(e) => {
println!("failed to run curl-config ({}), building from source", e);
println!("failed to run {configname} ({}), building from source", e);
return false;
}
};
if !output.status.success() {
println!("curl-config failed: {}", output.status);
println!("{configname} failed: {}", output.status);
return false;
}
let stdout = String::from_utf8_lossy(&output.stdout);
if !stdout.contains("HTTP2") {
println!(
"failed to find http-2 feature enabled in pkg-config-found \
libcurl, building from source"
{libname}, building from source"
);
return false;
}
Expand Down