Reqwest: Libreria Client HTTP per Rust

Reqwest è una libreria client HTTP di alto livello che semplifica la gestione delle richieste HTTP e fornisce numerose funzionalità comunemente utilizzate:

  • Supporto per API sia asincrone che bloccanti
  • Gestione di diversi tipi di corpi di richiesta: testo semplice, JSON, form codificati URL, form multipart
  • Politiche di reindirizzamento personalizzabili
  • Supporto per proxy HTTP
  • Crittografia TLS abilitata per impostazione predefinita
  • Gestione dei cookie

Utilizzo Base

Effettuare una Richiesta GET

Per richieste singole, puoi utilizzare il metodo pratico get:

let body = reqwest::get("https://www.rust-lang.org")
    .await?
    .text()
    .await?;

println!("body = {body:?}");

Nota: Se prevedi di effettuare più richieste, è meglio creare un Client e riutilizzarlo per sfruttare il pool di connessioni.

let client = reqwest::Client::new();
let res = client.get("https://www.rust-lang.org")
    .send()
    .await?;

Effettuare una Richiesta POST

Puoi impostare il corpo della richiesta utilizzando il metodo body():

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .body("il corpo esatto che viene inviato")
    .send()
    .await?;

Dati di Form

L'invio di dati di form è un'esigenza comune. Puoi utilizzare qualsiasi tipo che possa essere serializzato in dati di form:

// Questo invierà una richiesta POST con un corpo `foo=bar&baz=quux`
let params = [("foo", "bar"), ("baz", "quux")];
let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .form(&params)
    .send()
    .await?;

Dati JSON

Puoi facilmente inviare dati JSON utilizzando il metodo json (richiede la funzionalità json):

// Questo invierà una richiesta POST con un corpo `{"lang":"rust","body":"json"}`
let mut map = HashMap::new();
map.insert("lang", "rust");
map.insert("body", "json");

let client = reqwest::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()
    .await?;

Gestione della Risposta

Le risposte possono essere gestite in vari modi:

let res = client.get("https://www.rust-lang.org").send().await?;

// Ottieni il codice di stato
let status = res.status();

// Ottieni gli header della risposta
let content_type = res.headers().get("content-type").unwrap();

// Leggi il corpo della risposta come testo
let body = res.text().await?;

// Oppure analizzalo come JSON
let json: serde_json::Value = res.json().await?;

Funzionalità Avanzate

Politica di Reindirizzamento

Per impostazione predefinita, il client gestirà automaticamente i reindirizzamenti HTTP, seguendo fino a 10 salti. Puoi personalizzare questo comportamento utilizzando ClientBuilder:

let custom_client = reqwest::Client::builder()
    .redirect(reqwest::redirect::Policy::none()) // Disabilita i reindirizzamenti
    .build()?;

Puoi abilitare la memorizzazione e l'invio automatico dei cookie di sessione tramite ClientBuilder:

let client = reqwest::Client::builder()
    .cookie_store(true)
    .build()?;

Impostazioni Proxy

I proxy di sistema sono abilitati per impostazione predefinita, che cercheranno le impostazioni del proxy HTTP o HTTPS nelle variabili d'ambiente:

  • HTTP_PROXY o http_proxy: proxy per connessioni HTTP
  • HTTPS_PROXY o https_proxy: proxy per connessioni HTTPS
  • ALL_PROXY o all_proxy: proxy per entrambi i tipi di connessioni

Puoi anche impostare esplicitamente un proxy tramite codice:

let proxy = reqwest::Proxy::http("https://secure.example")?;
let client = reqwest::Client::builder()
    .proxy(proxy)
    .build()?;

// Oppure disabilita i proxy
let client = reqwest::Client::builder()
    .no_proxy()
    .build()?;

Configurazione TLS

Il client utilizza TLS per impostazione predefinita per connettersi a destinazioni HTTPS:

// Aggiungi certificati server aggiuntivi
let cert = reqwest::Certificate::from_pem(&cert_bytes)?;
let client = reqwest::Client::builder()
    .add_root_certificate(cert)
    .build()?;

// Configura certificati client
let identity = reqwest::Identity::from_pkcs12_der(&pkcs12_der, "password")?;
let client = reqwest::Client::builder()
    .identity(identity)
    .build()?;

Impostazioni di Timeout

Puoi configurare le durate di timeout per le richieste:

let client = reqwest::Client::builder()
    .timeout(std::time::Duration::from_secs(10))
    .build()?;

Funzionalità Opzionali

Reqwest fornisce varie funzionalità opzionali che possono essere abilitate o disabilitate tramite le funzionalità di Cargo:

  • http2 (abilitato per impostazione predefinita): supporto per HTTP/2
  • default-tls (abilitato per impostazione predefinita): fornisce supporto TLS per HTTPS
  • rustls-tls: fornisce funzionalità TLS utilizzando rustls
  • blocking: fornisce un'API client bloccante
  • json: fornisce funzionalità di serializzazione e deserializzazione JSON
  • multipart: fornisce funzionalità per form multipart
  • cookies: fornisce supporto per sessioni con cookie
  • gzip, brotli, deflate, zstd: supporto per varie decompressioni del corpo della risposta
  • socks: fornisce supporto per proxy SOCKS5

API Bloccante

Quando non sono necessarie operazioni asincrone, puoi utilizzare l'API bloccante (richiede la funzionalità blocking):

let body = reqwest::blocking::get("https://www.rust-lang.org")?.text()?;

let client = reqwest::blocking::Client::new();
let res = client.post("http://httpbin.org/post")
    .json(&map)
    .send()?;