polaris-mirror/src/ddns.rs
Antoine Gersant e41a5273a8 Autoformat
2017-06-28 23:59:48 -07:00

83 lines
1.9 KiB
Rust

use reqwest;
use reqwest::header::{Authorization, Basic};
use std::io;
use std::thread;
use std::time;
use errors;
#[derive(Debug, Deserialize, Queryable)]
pub struct DDNSConfig {
pub host: String,
pub username: String,
pub password: String,
}
pub trait DDNSConfigSource {
fn get_ddns_config(&self) -> errors::Result<DDNSConfig>;
}
#[derive(Debug)]
enum DDNSError {
InternalError(errors::Error),
IoError(io::Error),
ReqwestError(reqwest::Error),
UpdateError(reqwest::StatusCode),
}
impl From<io::Error> for DDNSError {
fn from(err: io::Error) -> DDNSError {
DDNSError::IoError(err)
}
}
impl From<errors::Error> for DDNSError {
fn from(err: errors::Error) -> DDNSError {
DDNSError::InternalError(err)
}
}
impl From<reqwest::Error> for DDNSError {
fn from(err: reqwest::Error) -> DDNSError {
DDNSError::ReqwestError(err)
}
}
const DDNS_UPDATE_URL: &'static str = "https://ydns.io/api/v1/update/";
fn update_my_ip<T>(config_source: &T) -> Result<(), DDNSError>
where T: DDNSConfigSource
{
let config = config_source.get_ddns_config()?;
if config.host.len() == 0 || config.username.len() == 0 {
println!("Skipping DDNS update because credentials are missing");
return Ok(());
}
let full_url = format!("{}?host={}", DDNS_UPDATE_URL, &config.host);
let auth_header = Authorization(Basic {
username: config.username.clone(),
password: Some(config.password.to_owned()),
});
let client = reqwest::Client::new()?;
let res = client
.get(full_url.as_str())
.header(auth_header)
.send()?;
if !res.status().is_success() {
return Err(DDNSError::UpdateError(*res.status()));
}
Ok(())
}
pub fn run<T>(config_source: &T)
where T: DDNSConfigSource
{
loop {
if let Err(e) = update_my_ip(config_source) {
println!("Dynamic DNS update error: {:?}", e);
}
thread::sleep(time::Duration::from_secs(60 * 30));
}
}