Перейти до вмісту
Гайды 7 хв читання 34 переглядів

Використання проксі в Rust

Ця стаття детально описує, як ефективно інтегрувати та використовувати HTTP/S проксі у ваших

Використання проксі в Rust

Використання проксі в Rust з reqwest передбачає налаштування ClientBuilder з параметрами проксі, тоді як hyper, будучи низькорівневою HTTP-бібліотекою, вимагає ручного встановлення з'єднання через проксі-сервер.

Проксі-сервери діють як посередники для мережевих запитів, пропонуючи такі переваги, як анонімність, доступ до географічно обмеженого контенту, балансування навантаження та фільтрація трафіку. Асинхронні HTTP-клієнти Rust, reqwest та hyper, пропонують різні підходи до інтеграції функціональності проксі. reqwest пропонує високорівневу, вбудовану підтримку, тоді як hyper вимагає більш детального контролю над процесом з'єднання.

Використання проксі з reqwest

reqwest — це популярний, зручний HTTP-клієнт для Rust, побудований на основі hyper. Він спрощує типові HTTP-завдання, включаючи конфігурацію проксі. ClientBuilder у reqwest надає методи для налаштування різних типів проксі.

Конфігурація проксі

Щоб використовувати проксі з reqwest, створіть екземпляр reqwest::Client за допомогою reqwest::ClientBuilder та його методу proxy(). Метод proxy() приймає об'єкт reqwest::Proxy, який можна створити для різних схем проксі:

  • HTTP-проксі: Налаштовується за допомогою Proxy::http(url) для звичайних HTTP-запитів.
  • HTTPS-проксі (метод CONNECT): Налаштовується за допомогою Proxy::https(url) для HTTPS-запитів. reqwest використовує метод CONNECT для тунелювання TLS-з'єднання через проксі.
  • SOCKS5-проксі: Налаштовується за допомогою Proxy::socks5(url) для SOCKS5-проксі-серверів.
  • Уніфікований проксі: Proxy::all(url) налаштовує єдиний проксі як для HTTP, так і для HTTPS-запитів.

Автентифікація проксі

Багато проксі-серверів вимагають автентифікації. reqwest::Proxy підтримує базову автентифікацію за допомогою методу basic_auth().

Підтримка змінних середовища

За замовчуванням ClientBuilder у reqwest автоматично перевіряє змінні середовища HTTP_PROXY, HTTPS_PROXY та NO_PROXY. Якщо вони встановлені, reqwest використовуватиме їх, якщо це явно не перевизначено за допомогою ClientBuilder::no_proxy() або шляхом налаштування конкретного проксі.

Приклад: Використання проксі reqwest

Цей приклад демонструє налаштування reqwest для використання HTTP, HTTPS та SOCKS5 проксі, включаючи базову автентифікацію.

use reqwest::{Client, Error, Proxy};
use std::time::Duration;

#[tokio::main]
async fn main() -> Result<(), Error> {
    // 1. HTTP-проксі
    let http_proxy_url = "http://user:password@your-http-proxy.com:8080";
    let http_client = Client::builder()
        .proxy(Proxy::http(http_proxy_url)?)
        .timeout(Duration::from_secs(10))
        .build()?;

    println!("HTTP Proxy request...");
    let http_res = http_client.get("http://httpbin.org/ip").send().await?;
    println!("HTTP Proxy Response: {:?}", http_res.text().await?);

    // 2. HTTPS-проксі (метод CONNECT)
    // Примітка: Для HTTPS URL проксі сам по собі може бути HTTP, але він тунелює HTTPS-трафік.
    let https_proxy_url = "http://user:password@your-https-proxy.com:8080";
    let https_client = Client::builder()
        .proxy(Proxy::https(https_proxy_url)?)
        .timeout(Duration::from_secs(10))
        .build()?;

    println!("\nHTTPS Proxy request...");
    let https_res = https_client.get("https://httpbin.org/ip").send().await?;
    println!("HTTPS Proxy Response: {:?}", https_res.text().await?);

    // 3. SOCKS5-проксі
    let socks5_proxy_url = "socks5://user:password@your-socks5-proxy.com:1080";
    let socks5_client = Client::builder()
        .proxy(Proxy::socks5(socks5_proxy_url)?)
        .timeout(Duration::from_secs(10))
        .build()?;

    println!("\nSOCKS5 Proxy request...");
    let socks5_res = socks5_client.get("http://httpbin.org/ip").send().await?;
    println!("SOCKS5 Proxy Response: {:?}", socks5_res.text().await?);

    // 4. Уніфікований проксі (застосовується як до HTTP, так і до HTTPS-запитів)
    let all_proxy_url = "http://user:password@your-all-proxy.com:8080";
    let all_client = Client::builder()
        .proxy(Proxy::all(all_proxy_url)?)
        .timeout(Duration::from_secs(10))
        .build()?;

    println!("\nUnified Proxy (HTTP) request...");
    let all_http_res = all_client.get("http://httpbin.org/ip").send().await?;
    println!("Unified Proxy (HTTP) Response: {:?}", all_http_res.text().await?);

    println!("\nUnified Proxy (HTTPS) request...");
    let all_https_res = all_client.get("https://httpbin.org/ip").send().await?;
    println!("Unified Proxy (HTTPS) Response: {:?}", all_https_res.text().await?);

    Ok(())
}

Примітка: Замініть your-http-proxy.com:8080, your-https-proxy.com:8080 та your-socks5-proxy.com:1080 на фактичні адреси та порти проксі-серверів, включаючи user:password для автентифікованих проксі.

Використання проксі з hyper

hyper — це низькорівнева, високопродуктивна HTTP-бібліотека, яка є основою для багатьох інших HTTP-крейтів Rust, включаючи reqwest. На відміну від reqwest, hyper не пропонує вбудованих, прямих методів конфігурації проксі для свого клієнта. Натомість, використання проксі з hyper вимагає ручного керування базовим TCP-з'єднанням або інтеграції із зовнішніми крейтами, специфічними для проксі.

Ручне керування з'єднанням

Щоб використовувати проксі з hyper, ви повинні спочатку встановити з'єднання з проксі-сервером, а потім вказати hyper використовувати це вже встановлене з'єднання або спеціальний конектор, який обробляє логіку проксі.

HTTP-проксі для HTTP-запитів

Для звичайних HTTP-запитів через HTTP-проксі клієнт встановлює TCP-з'єднання з проксі-сервером. Потім він надсилає HTTP-запит безпосередньо проксі, вказуючи повний цільовий URL у рядку запиту (наприклад, GET http://target.com/path HTTP/1.1). Заголовок Host все ще повинен посилатися на цільовий сервер.

HTTP-проксі для HTTPS-запитів (метод CONNECT)

Для HTTPS-запитів клієнт спочатку надсилає HTTP CONNECT запит проксі, вказуючи йому встановити TCP-тунель до цільового хоста та порту. Як тільки проксі відповідає 200 OK, клієнт виконує TLS-рукостискання безпосередньо з цільовим сервером через встановлений тунель.

SOCKS5-проксі

SOCKS5-проксі працюють на нижчому рівні, ніж HTTP-проксі, і підтримують різні протоколи, включаючи TCP та UDP. Інтеграція SOCKS5 з hyper зазвичай передбачає використання спеціальної клієнтської бібліотеки SOCKS5 (наприклад, tokio-socks) для встановлення проксі-з'єднання, яке потім передається до будівельника з'єднань hyper.

Приклад: Використання проксі hyper (HTTP-проксі для HTTP)

Цей приклад демонструє, як зробити базовий HTTP-запит через HTTP-проксі за допомогою hyper, вручну конструюючи запит та керуючи TCP-потоком. Це ілюструє базовий механізм; для надійних рішень розгляньте можливість обгортання цієї логіки або використання спеціального конектора.

use hyper::{Body, Client, Request, Uri};
use hyper::client::conn::Builder;
use tokio::net::TcpStream;
use std::str::FromStr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
    let proxy_addr = "127.0.0.1:8080"; // Замініть на адресу вашого HTTP-проксі
    let target_url = "http://httpbin.org/ip";

    println!("Connecting to proxy: {}", proxy_addr);
    let stream = TcpStream::connect(proxy_addr).await?;

    // Для HTTP-проксі ми підключаємося до проксі та надсилаємо повний URI в запиті.
    // Метод CONNECT не потрібен для звичайних HTTP-цілей.
    let (mut sender, conn) = Builder::new()
        .http1_only(true) // Забезпечити HTTP/1.1 для сумісності з HTTP-проксі
        .handshake(stream)
        .await?;

    tokio::spawn(async move {
        if let Err(e) = conn.await {
            eprintln!("Connection error: {:?}", e);
        }
    });

    let req = Request::builder()
        .uri(Uri::from_str(target_url)?) // Абсолютний URI для пересилання HTTP-проксі
        .header("Host", "httpbin.org") // Заголовок Host для цільового сервера
        .body(Body::empty())?;

    println!("Sending request through proxy to: {}", target_url);
    let res = sender.send(req).await?;

    println!("Response Status: {}", res.status());
    let body_bytes = hyper::body::to_bytes(res.into_body()).await?;
    println!("Response Body: {}", String::from_utf8_lossy(&body_bytes));

    Ok(())
}

Примітка: Цей приклад передбачає базовий HTTP-проксі, який не вимагає автентифікації та безпосередньо пересилає HTTP-запити. Для HTTPS або автентифікованих проксі логіка стає значно складнішою, включаючи запити CONNECT або спеціальні бібліотеки для узгодження проксі.

Використання зовнішніх конекторів для hyper

Для більш складних сценаріїв проксі з hyper, особливо для SOCKS5 або автентифікованих HTTP/HTTPS-проксі, зазвичай реалізують власний hyper::client::connect::Connection або використовують крейт, який надає таку реалізацію. Наприклад, для SOCKS5 ви зазвичай використовуєте крейт, такий як tokio-socks, щоб встановити проксі-TcpStream через SOCKS5, а потім використовуєте hyper::client::conn::Builder::handshake з цим потоком.

reqwest проти hyper для використання проксі

Функція reqwest hyper
Конфігурація проксі Вбудовані, високорівневі методи (ClientBuilder::proxy()) Ручна реалізація hyper::client::connect::Connection або інтеграція із зовнішніми бібліотеками
Простота використання Високорівнева, проста для поширених типів проксі Низькорівнева, складна для проксі, вимагає більше шаблонного коду
Підтримувані типи проксі HTTP, HTTPS (CONNECT), SOCKS5 Вимагає ручної обробки для кожного типу; часто використовує зовнішні крейти для SOCKS5 або складної автентифікації
Автентифікація Вбудована (Proxy::basic_auth()) Ручне впровадження заголовків (Proxy-Authorization) або функції спеціальних бібліотек проксі
Рівень контролю Помірний, абстрагує деталі з'єднання Високий, детальний контроль над з'єднаннями та деталями HTTP-протоколу
Залежності Простіші для проксіювання, reqwest обробляє базову складність Може вимагати додаткових крейтів (tokio-socks, спеціальні конектори) для надійної логіки проксі
Типовий випадок використання Більшість програм, що вимагають HTTP-запитів з підтримкою проксі, пріоритет – швидкість розробки та простота Створення власних HTTP-клієнтів, серверів або високооптимізованих мережевих компонентів, де важливий детальний контроль над мережевими з'єднаннями

Найкращі практики та міркування

Обробка помилок

З'єднання проксі можуть виходити з ладу з різних причин (проблеми з мережею, проксі не працює, помилка автентифікації). Реалізуйте надійну обробку помилок для операцій, пов'язаних з проксі, особливо при ручному керуванні з'єднаннями за допомогою hyper. reqwest повертає reqwest::Error, який можна перевірити на наявність проблем, специфічних для проксі.

Типи проксі та сумісність протоколів

  • HTTP-проксі: Переважно для HTTP-трафіку. Може тунелювати HTTPS-трафік за допомогою методу CONNECT.
  • SOCKS5-проксі: Протокольно-незалежні, підтримують TCP та UDP. Часто кращі для не-HTTP-трафіку або коли бажаний вищий ступінь анонімності.
  • Переконайтеся, що налаштований тип проксі відповідає можливостям проксі-сервера та типу трафіку, який ви маєте намір надсилати.

Автентифікація

Завжди надавайте правильні облікові дані для автентифікованих проксі. Неправильно налаштована автентифікація є поширеним джерелом помилок з'єднання проксі. Для reqwest використовуйте Proxy::basic_auth(). Для hyper або спеціальних конекторів надсилайте заголовок Proxy-Authorization з відповідними обліковими даними (наприклад, Base64-кодовані username:password).

Вплив на продуктивність

Використання проксі додає додатковий стрибок у мережевому шляху, що може збільшити затримку. Накладні витрати на продуктивність залежать від розташування проксі-сервера, навантаження та мережевих умов між вашим клієнтом, проксі та цільовим сервевером.

Міркування безпеки

  • Довіра: Використовуйте лише довірені проксі-сервери. Шкідливі проксі можуть перевіряти, змінювати або реєструвати ваш трафік.
  • HTTPS-проксіювання: При використанні HTTPS-проксі з методом CONNECT проксі встановлює тунель, і ваш клієнт виконує TLS-рукостискання безпосередньо з цільовим сервером. Це означає, що проксі не може розшифрувати вміст вашого HTTPS-трафіку (якщо це не проксі "людина посередині" з встановленим на вашому клієнті спеціальним кореневим сертифікатом). reqwest обробляє це безпечно за замовчуванням.
  • Заголовки проксі: Проксі часто додають заголовки, такі як X-Forwarded-For. Зверніть на це увагу, якщо анонімність є головною турботою.

Взаємодія зі змінними середовища

reqwest автоматично враховує змінні середовища HTTP_PROXY, HTTPS_PROXY та NO_PROXY. Якщо вам потрібно перевизначити цю поведінку, використовуйте ClientBuilder::no_proxy() або явно налаштуйте проксі. При безпосередньому використанні hyper ви повинні вручну розібрати та застосувати ці змінні середовища, якщо це необхідно.

Оновлено: 03.03.2026
Назад до категорії

Читайте також

Гайды 1 хв

Налаштування проксі в Cypress для E2E тестування

Налаштування проксі в Cypress: змінні HTTP_PROXY, cy-proxy-middleware та тестування геозалежного контенту.

Гайды 1 хв

Як автоматизувати купівлю проксі через API

Автоматизація купівлі та управління проксі через API провайдерів: інтеграція, моніторинг використання та автопоновлення.

Гайды 1 хв

Створення інформаційної панелі моніторингу проксі в Grafana

Покрокове створення інформаційної панелі для моніторингу проксі в Grafana: метрики,

Гайды 1 хв

Як тестувати проксі перед покупкою

Чек-лист тестування проксі перед покупкою: швидкість, стабільність, анонімність, гео та сумісність з ціллю

Гайды 1 хв

Як налаштувати липкі сесії через проксі

Липкі сесії: підтримка однієї IP-адреси протягом усієї сесії, налаштовуються через провайдера та самостійно.

Гайды 1 хв

Використання проксі з Camoufox

Camoufox — це модифікований Firefox для обходу антиботів. Налаштування проксі, відбиток та режим невидимості.

Спробуйте наші проксі

20,000+ проксі в 100+ країнах світу

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.