polaris-mirror/src/ddns.rs
2017-05-07 21:21:30 -07:00

79 lines
1.9 KiB
Rust

use hyper;
use hyper::client::Client;
use hyper::header::{Authorization, Basic};
use std::io;
use std::io::Read;
use std::thread;
use std::time;
#[derive(Debug, Clone)]
pub struct DDNSConfig {
pub host: String,
pub username: String,
pub password: String,
}
#[derive(Debug)]
enum DDNSError {
IoError(io::Error),
HyperError(hyper::Error),
UpdateError(hyper::status::StatusCode),
}
impl From<io::Error> for DDNSError {
fn from(err: io::Error) -> DDNSError {
DDNSError::IoError(err)
}
}
impl From<hyper::Error> for DDNSError {
fn from(err: hyper::Error) -> DDNSError {
DDNSError::HyperError(err)
}
}
const MY_IP_API_URL: &'static str = "http://api.ipify.org";
const DDNS_UPDATE_URL: &'static str = "http://ydns.io/api/v1/update/";
fn get_my_ip() -> Result<String, DDNSError> {
let client = Client::new();
let mut res = client.get(MY_IP_API_URL).send()?;
let mut buf = String::new();
res.read_to_string(&mut buf)?;
Ok(buf)
}
fn update_my_ip(ip: &String, config: &DDNSConfig) -> Result<(), DDNSError> {
let client = Client::new();
let url = DDNS_UPDATE_URL;
let host = &config.host;
let full_url = format!("{}?host={}&ip={}", url, host, ip);
let auth_header = Authorization(Basic {
username: config.username.clone(),
password: Some(config.password.to_owned()),
});
let res = client
.get(full_url.as_str())
.header(auth_header)
.send()?;
match res.status {
hyper::status::StatusCode::Ok => Ok(()),
s => Err(DDNSError::UpdateError(s)),
}
}
pub fn run(config: DDNSConfig) {
loop {
let my_ip_res = get_my_ip();
if let Ok(my_ip) = my_ip_res {
match update_my_ip(&my_ip, &config) {
Err(e) => println!("Dynamic DNS Error: {:?}", e),
Ok(_) => (),
};
} else {
println!("Dynamic DNS Error: could not retrieve our own IP address");
}
thread::sleep(time::Duration::from_secs(60 * 30));
}
}