zombienet_support/
net.rs

1use std::{io::Cursor, str::FromStr, time::Duration};
2
3use reqwest::{Method, Request, StatusCode, Url};
4use tracing::trace;
5
6use crate::constants::THIS_IS_A_BUG;
7
8type Result<T> = std::result::Result<T, Box<dyn std::error::Error + Send + Sync>>;
9
10pub async fn download_file(url: String, dest: String) -> Result<()> {
11    let response = reqwest::get(url).await?;
12    let mut file = std::fs::File::create(dest)?;
13    let mut content = Cursor::new(response.bytes().await?);
14    std::io::copy(&mut content, &mut file)?;
15    Ok(())
16}
17
18pub async fn wait_ws_ready(url: &str) -> Result<()> {
19    let mut parsed = Url::from_str(url)?;
20    parsed
21        .set_scheme("http")
22        .map_err(|_| anyhow::anyhow!("Can not set the scheme, {}", THIS_IS_A_BUG))?;
23
24    let http_client = reqwest::Client::new();
25    loop {
26        let req = Request::new(Method::OPTIONS, parsed.clone());
27        let res = http_client.execute(req).await;
28        match res {
29            Ok(res) => {
30                if res.status() == StatusCode::OK {
31                    // ready to go!
32                    break;
33                }
34
35                trace!("http_client status: {}, continuing...", res.status());
36            },
37            Err(e) => {
38                if !skip_err_while_waiting(&e) {
39                    return Err(e.into());
40                }
41
42                trace!("http_client err: {}, continuing... ", e.to_string());
43            },
44        }
45
46        tokio::time::sleep(Duration::from_secs(1)).await;
47    }
48
49    Ok(())
50}
51
52pub fn skip_err_while_waiting(e: &reqwest::Error) -> bool {
53    // if the error is connecting/request could be the case that the node
54    // is not listening yet, so we keep waiting
55    // Skipped errs like:
56    // 'tcp connect error: Connection refused (os error 61)'
57    // 'operation was canceled: connection closed before message completed'
58    // 'connection error: Connection reset by peer (os error 54)'
59    e.is_connect() || e.is_request()
60}