Skip to content
forked from penumbra-x/rquest

An fast asynchronous Rust HTTP/WebSocket Client with TLS/JA3/JA4/HTTP2 fingerprint impersonate

License

Notifications You must be signed in to change notification settings

xbabybus/rqeust

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rquest

Email Badge Crates.io License crates.io Documentation Crates.io Total Downloads

An fast asynchronous Rust HTTP/WebSocket Client with TLS/JA3/JA4/HTTP2 fingerprint impersonate

  • Async Client
  • Plain, JSON, urlencoded, multipart bodies
  • Headers Order
  • Customizable redirect policy
  • Cookie Store
  • HTTP/WebSocket Proxies
  • HTTPS/WebSocket via BoringSSL
  • Preconfigured TLS/HTTP2/Headers settings
  • Changelog

Additional learning resources include:

Usage

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.21"
use std::error::Error;
use rquest::tls::Impersonate;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Build a client to mimic Chrome129
    let client = rquest::Client::builder()
        .impersonate(Impersonate::Chrome129)
        .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.21", features = ["websocket"] }
use futures_util::{SinkExt, StreamExt, TryStreamExt};
use rquest::{tls::Impersonate, Client, Message};
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let websocket = rquest::websocket("wss://echo.websocket.org").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.21"
use boring::ssl::{SslConnector, SslMethod};
use http::{header, HeaderValue};
use rquest::{
    tls::{Http2Settings, ImpersonateSettings, TlsExtensionSettings},
    HttpVersionPref,
};
use rquest::{PseudoOrder::*, SettingsOrder::*};
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    // Create a pre-configured TLS settings
    let settings = ImpersonateSettings::builder()
        .tls((
            SslConnector::builder(SslMethod::tls_client())?,
            TlsExtensionSettings::builder()
                .tls_sni(true)
                .http_version_pref(HttpVersionPref::Http2)
                .application_settings(true)
                .pre_shared_key(true)
                .enable_ech_grease(true)
                .permute_extensions(true)
                .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(vec![
                    HeaderTableSize,
                    EnablePush,
                    MaxConcurrentStreams,
                    InitialWindowSize,
                    MaxFrameSize,
                    MaxHeaderListSize,
                    EnableConnectProtocol,
                ])
                .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(())
}

Device

Currently supported impersonate device types

  • Chrome

Chrome100Chrome101Chrome104Chrome105Chrome106Chrome107Chrome108Chrome109Chrome114Chrome116Chrome117Chrome118Chrome119Chrome120Chrome123Chrome124Chrome126Chrome127Chrome128Chrome129

  • Edge

Edge101Edge122Edge127

  • Safari

SafariIos17_2SafariIos17_4_1SafariIos16_5Safari15_3Safari15_5Safari15_6_1Safari16Safari16_5Safari17_0Safari17_2_1Safari17_4_1Safari17_5Safari18SafariIPad18

  • OkHttp

OkHttp3_9OkHttp3_11OkHttp3_13OkHttp3_14OkHttp4_9OkHttp4_10OkHttp5

Requirement

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.

Contributing

If you would like to submit your contribution, please open a Pull Request.

Getting help

Your question might already be answered on the issues

License

Apache-2.0 LICENSE

Accolades

The project is based on a fork of reqwest.

About

An fast asynchronous Rust HTTP/WebSocket Client with TLS/JA3/JA4/HTTP2 fingerprint impersonate

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Rust 100.0%