Crates.io | rquest |
lib.rs | rquest |
version | 0.27.5 |
source | src |
created_at | 2024-07-27 01:09:24.255915 |
updated_at | 2024-11-05 04:43:09.160559 |
description | An ergonomic, all-in-one JA3/JA4/HTTP2 fingerprint HTTP/WebSocket client |
homepage | |
repository | https://github.com/penumbra-x/rquest |
max_upload_size | |
id | 1316932 |
size | 663,488 |
🚀 Support my journey to full-time open-source development by sponsoring me on GitHub
An ergonomic, all-in-one JA3
/JA4
/HTTP2
fingerprint HTTP
/WebSocket
client.
HTTPS
/WebSocket
via BoringSSLTLS
/HTTP2
settingsHTTP
, HTTPS
, SOCKS4
and SOCKS5
proxiesAdditional learning resources include:
âš This crate is under active development and the API is not yet stable.
This asynchronous example uses Tokio and enables some
optional features, so your Cargo.toml
could look like this:
HTTP
[dependencies]
tokio = { version = "1", features = ["full"] }
rquest = "0.27"
use rquest::tls::Impersonate;
#[tokio::main]
async fn main() -> Result<(), rquest::Error> {
// Build a client to mimic Chrome130
let client = rquest::Client::builder()
.impersonate(Impersonate::Chrome130)
.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(())
}
WebSocket
[dependencies]
tokio = { version = "1", features = ["full"] }
rquest = { version = "0.27", features = ["websocket"] }
use futures_util::{SinkExt, StreamExt, TryStreamExt};
use rquest::{tls::Impersonate, Client, Message};
#[tokio::main]
async fn main() -> Result<(), rquest::Error> {
// Build a client to mimic Chrome130
let client = Client::builder()
.impersonate(Impersonate::Chrome130)
.build()?;
// Use the API you're already familiar with
let websocket = client
.websocket("wss://echo.websocket.org")
.send()
.await?
.into_websocket()
.await?;
let (mut tx, mut rx) = websocket.split();
tokio::spawn(async move {
for i in 1..11 {
tx.send(Message::Text(format!("Hello, World! #{i}")))
.await
.unwrap();
}
});
while let Some(message) = rx.try_next().await? {
match message {
Message::Text(text) => println!("received: {text}"),
_ => {}
}
}
Ok(())
}
Preconfigured TLS
/HTTP2
[dependencies]
tokio = { version = "1", features = ["full"] }
rquest = "0.27"
use boring::ssl::{SslConnector, SslCurve, SslMethod, SslOptions};
use http::{header, HeaderValue};
use rquest::{
tls::{Http2Settings, ImpersonateSettings, TlsSettings, Version},
HttpVersionPref,
};
use rquest::{PseudoOrder::*, SettingsOrder::*};
#[tokio::main]
async fn main() -> Result<(), rquest::Error> {
// Create a pre-configured TLS settings
let settings = ImpersonateSettings::builder()
.tls(
TlsSettings::builder()
.connector(Box::new(|| {
let mut builder = SslConnector::builder(SslMethod::tls_client())?;
builder.set_curves(&[SslCurve::SECP224R1, SslCurve::SECP521R1])?;
builder.set_options(SslOptions::NO_TICKET);
Ok(builder)
}))
.tls_sni(true)
.http_version_pref(HttpVersionPref::All)
.application_settings(true)
.pre_shared_key(true)
.enable_ech_grease(true)
.permute_extensions(true)
.min_tls_version(Version::TLS_1_0)
.max_tls_version(Version::TLS_1_3)
.build(),
)
.http2(
Http2Settings::builder()
.initial_stream_window_size(6291456)
.initial_connection_window_size(15728640)
.max_concurrent_streams(1000)
.max_header_list_size(262144)
.header_table_size(65536)
.enable_push(false)
.headers_priority((0, 255, true))
.headers_pseudo_order([Method, Scheme, Authority, Path])
.settings_order([
HeaderTableSize,
EnablePush,
MaxConcurrentStreams,
InitialWindowSize,
MaxFrameSize,
MaxHeaderListSize,
UnknownSetting8,
UnknownSetting9,
])
.build(),
)
.headers(Box::new(|headers| {
headers.insert(header::USER_AGENT, HeaderValue::from_static("rquest"));
}))
.build();
// Build a client with pre-configured TLS settings
let client = rquest::Client::builder()
.use_preconfigured_tls(settings)
.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(())
}
Currently supported impersonate device types
Chrome100
,Chrome101
,Chrome104
,Chrome105
,Chrome106
,Chrome107
,Chrome108
,Chrome109
,Chrome114
,Chrome116
,Chrome117
,Chrome118
,Chrome119
,Chrome120
,Chrome123
,Chrome124
,Chrome126
,Chrome127
,Chrome128
,Chrome129
,Chrome130
Edge101
,Edge122
,Edge127
SafariIos17_2
,SafariIos17_4_1
,SafariIos16_5
,Safari15_3
,Safari15_5
,Safari15_6_1
,Safari16
,Safari16_5
,Safari17_0
,Safari17_2_1
,Safari17_4_1
,Safari17_5
,Safari18
,SafariIPad18
OkHttp3_9
,OkHttp3_11
,OkHttp3_13
,OkHttp3_14
,OkHttp4_9
,OkHttp4_10
,OkHttp5
Install the environment required to build BoringSSL
Do not compile with crates that depend on OpenSSL
; their prefixing symbols are the same and may cause linking failures.
If both OpenSSL
and BoringSSL
are used as dependencies simultaneously, even if the compilation succeeds, strange issues may still arise.
sudo apt-get install build-essential cmake perl pkg-config libclang-dev musl-tools -y
cargo build --release
You can also use this GitHub Actions workflow to compile your project on Linux, Windows, and macOS.
If you would like to submit your contribution, please open a Pull Request.
Your question might already be answered on the issues
Apache-2.0 LICENSE
The project is based on a fork of reqwest.