Browse Source

Added support for parsing IP Addresses

develop
Drew Short 6 years ago
parent
commit
f2a0b0520c
  1. 2
      docker/build-linux.bat
  2. 49
      src/server/api.rs
  3. 30
      src/server/error.rs
  4. 1
      src/server/mod.rs

2
docker/build-linux.bat

@ -8,4 +8,4 @@ docker run --rm ^
-v "%cd%\docker\linux\cargo":/tmp/cargo ^
-w /usr/src/rsddns ^
rust:1.30.1-stretch ^
cargo build --release && strip $/usr/src/rsddns/target/release/rsddns
cargo build --release && strip /usr/src/rsddns/target/release/rsddns

49
src/server/api.rs

@ -1,4 +1,6 @@
use std::io::Read;
use std::net::IpAddr;
use std::str::FromStr;
use actix_web::{AsyncResponder, FutureResponse, HttpMessage, HttpRequest, HttpResponse, Scope};
use actix_web::http::Method;
@ -6,6 +8,8 @@ use actix_web::http::StatusCode;
use bytes::{Buf, Bytes, IntoBuf};
use futures::future::Future;
use server::error::APIError;
pub fn route(scope: Scope<()>) -> Scope<()> {
scope.resource("address", |r| r.method(Method::GET).f(get_address))
.nested("{root}/{zone}", |zone_scope| {
@ -23,20 +27,53 @@ fn update_address(address: String) -> String {
address
}
fn parse_remote_info(remote_info: &str) -> Result<IpAddr, APIError> {
let mut remote_address = String::from(remote_info);
if remote_address.contains(":") {
let last_colon_index = remote_address.rfind(":").unwrap();
let port = remote_address.split_off(last_colon_index);
if remote_address.starts_with("[") && remote_address.ends_with("]") {
remote_address = String::from(remote_address.trim_matches(|c| c == '[' || c == ']'))
}
match IpAddr::from_str(&remote_address) {
Ok(v) => Ok(v),
Err(e) => Err(APIError::new(&format!("Address Parse Error \"{}\"", remote_address), Some(Box::from(e))))
}
} else {
Err(APIError::new(&format!("{} could not be parsed", remote_address), None))
}
}
fn get_address(req: &HttpRequest) -> HttpResponse {
match req.connection_info().remote() {
Some(addr) => HttpResponse::build(StatusCode::OK)
.content_type("text/plain")
.body(format!("{}", addr)),
Some(remote_info) => {
match parse_remote_info(remote_info) {
Ok(addr) => HttpResponse::build(StatusCode::OK)
.content_type("text/plain")
.body(format!("{}", addr)),
Err(e) => {
error!("{}", e);
HttpResponse::build(StatusCode::BAD_REQUEST).finish()
}
}
}
None => HttpResponse::build(StatusCode::BAD_REQUEST).finish(),
}
}
fn update_address_automatically(req: &HttpRequest) -> HttpResponse {
match req.connection_info().remote() {
Some(addr) => HttpResponse::build(StatusCode::OK)
.content_type("text/plain")
.body(format!("{}", addr)),
Some(remote_info) => {
match parse_remote_info(remote_info) {
Ok(addr) => HttpResponse::build(StatusCode::OK)
.content_type("text/plain")
.body(format!("{}", addr)),
Err(e) => {
error!("{}", e);
HttpResponse::build(StatusCode::BAD_REQUEST).finish()
}
}
}
None => HttpResponse::build(StatusCode::BAD_REQUEST).finish(),
}
}

30
src/server/error.rs

@ -0,0 +1,30 @@
use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub struct APIError {
description: String,
original_error: Option<Box<Error>>,
}
impl APIError {
pub fn new(description: &str, original_error: Option<Box<Error>>) -> APIError {
APIError {
description: String::from(description),
original_error,
}
}
}
impl Error for APIError {}
impl fmt::Display for APIError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.original_error {
Some(original_error) => {
write!(f, "{}: \"{}\"", self.description, original_error)
}
None => write!(f, "{}", self.description)
}
}
}

1
src/server/mod.rs

@ -3,6 +3,7 @@ use actix_web::{HttpRequest, Json, Result};
use VERSION;
pub mod api;
pub mod error;
pub mod router;
#[derive(Serialize)]

Loading…
Cancel
Save