Making periodic http requests in Rust
Making http requests in Rust using reqwest, tokio, async/await and http proxies and cookies
In this post, we will look into how we can write. a a simple program to make periodic http requests using request
in Rust.
Lets start with creating a client using request
let client = reqwest::Client::builder()
Now, lets add basic http headers and some cookies, to the client,
let user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36";
let cookies = format!("{}", std::env::var("COOKIES")?);
let mut headers = header::HeaderMap::new();
headers.insert("accept", header::HeaderValue::from_static("*/*"));
headers.insert("cookie", header::HeaderValue::from_str(&cookies).unwrap());
let client = reqwest::Client::builder()
.user_agent(user_agent)
.default_headers(headers)
And then add our http proxy to the client with:
let proxy_url = format!("{}", std::env::var("PROXY_URL")?);
let http_proxy = reqwest::Proxy::http(&proxy_url)?;
let https_proxy = reqwest::Proxy::https(&proxy_url)?;
let client = reqwest::Client::builder()
.user_agent(user_agent)
.default_headers(headers)
.danger_accept_invalid_certs(true)
.gzip(true)
.proxy(http_proxy)
.proxy(https_proxy)
.connect_timeout(std::time::Duration::from_secs(60))
.timeout(std::time::Duration::from_secs(600))
.build()
.unwrap();
Now let's wrap everything together with
use dotenv::dotenv;
use reqwest::header;
use reqwest::Client;
use tokio::time;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
dotenv().ok();
let proxy_url = format!("{}", std::env::var("PROXY_URL")?);
let cookies = format!("{}", std::env::var("COOKIES")?);
let ipify_url = format!("https://api.ipify.org?format=json");
let user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36";
let http_proxy = reqwest::Proxy::http(&proxy_url)?;
let https_proxy = reqwest::Proxy::https(&proxy_url)?;
let mut headers = header::HeaderMap::new();
headers.insert("accept", header::HeaderValue::from_static("*/*"));
headers.insert("cookie", header::HeaderValue::from_str(&cookies).unwrap());
let client = reqwest::Client::builder()
.user_agent(user_agent)
.default_headers(headers)
.danger_accept_invalid_certs(true)
.gzip(true)
.proxy(http_proxy)
.proxy(https_proxy)
.connect_timeout(std::time::Duration::from_secs(60))
.timeout(std::time::Duration::from_secs(600))
.build()
.unwrap();
tokio::join!(fetch(&client, &ipify_url), fetch(&client, &ipify_url));
Ok(())
}
async fn fetch(client: &Client, url: &str) -> Result<(), Box<dyn std::error::Error>> {
let mut interval = time::interval(std::time::Duration::from_secs(60));
loop {
interval.tick().await;
let res = client.get(url).send().await.unwrap();
match res.status() {
reqwest::StatusCode::OK => {
println!("Status: OK, url:{:?}", res.url().path());
println!("URL: {}", url);
}
status => println!("status: {}, path: {}", status, res.url().path()),
}
}
}