1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
/** * Copyright (c) 2019, Jesús Rubio <jesusprubio@gmail.com> * * This source code is licensed under the MIT License found in * the LICENSE.txt file in the root directory of this source tree. */ use async_std::{ io::{timeout as tout, Error}, net::TcpStream, }; use std::time::Duration; // Captive portals: // - https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/captivePortal // - http://clients3.google.com/generate_204 // - http://detectportal.firefox.com/success.txt. const ADDRS: &str = "clients3.google.com:80"; const ADDRS_BACK: &str = "detectportal.firefox.com:80"; async fn probe(addrs: &str, timeout: Option<Duration>) -> Result<TcpStream, Error> { match timeout { Some(d) => tout(d, TcpStream::connect(addrs)).await, _ => TcpStream::connect(addrs).await, } } /// Check if the internet connection is up. When the check succeeds, the returned future is resolved to `true`. /// /// * `timeout` - Number of seconds to wait for a response (default: OS dependent) pub async fn online(timeout: Option<u64>) -> Result<bool, Error> { //! ```rust //! use online::*; //! //! #[async_std::main] //! async fn main() { //! assert_eq!(online(None).await.unwrap(), true); //! //! // with timeout //! assert_eq!(online(Some(6)).await.unwrap(), true); //! } //! ``` let secs = match timeout { Some(n) => Some(Duration::from_secs(n)), _ => None, }; match probe(ADDRS, secs).await { Ok(_) => Ok(true), Err(e) => match probe(ADDRS_BACK, secs).await { Ok(_) => Ok(true), // If both failed we return the first one. Err(_) => Err(e), }, } }