Add the ability to return a super basic HTML page
This commit is contained in:
parent
ef3a57328e
commit
f7d8e46752
|
@ -5,6 +5,7 @@ dependencies = [
|
|||
"clap 2.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clippy 0.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"horrorshow 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hyper 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iron 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -142,6 +143,11 @@ dependencies = [
|
|||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "horrorshow"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "hpack"
|
||||
version = "0.2.0"
|
||||
|
@ -742,6 +748,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum flate2 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "3eeb481e957304178d2e782f2da1257f1434dfecbae883bafb61ada2a9fea3bb"
|
||||
"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
|
||||
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
|
||||
"checksum horrorshow 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)" = "234628f89d562b0ad97069e3f808cf109d0ed51b71a7825bfa6d32f317569543"
|
||||
"checksum hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d2da7d3a34cf6406d9d700111b8eafafe9a251de41ae71d8052748259343b58"
|
||||
"checksum httparse 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6a8abece705b1d32c478f49447b3a575cd07f6e362ff12518f2ee2c9b9ced64e"
|
||||
"checksum hyper 0.9.12 (registry+https://github.com/rust-lang/crates.io-index)" = "d7da01615e9402761faab442396821b57ecb5adb12ac51958561411a82cfdf66"
|
||||
|
|
|
@ -6,6 +6,7 @@ authors = ["Frank Denis <github@pureftpd.org>"]
|
|||
[dependencies]
|
||||
clap = "*"
|
||||
flate2 = "*"
|
||||
horrorshow = "*"
|
||||
hyper = "*"
|
||||
iron = "*"
|
||||
log = "*"
|
||||
|
|
|
@ -7,6 +7,8 @@ extern crate flate2;
|
|||
extern crate iron;
|
||||
#[macro_use]
|
||||
extern crate router;
|
||||
#[macro_use]
|
||||
extern crate horrorshow;
|
||||
extern crate hyper;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use asns::*;
|
||||
use horrorshow::prelude::*;
|
||||
use iron::{BeforeMiddleware, typemap};
|
||||
use iron::headers::{CacheControl, CacheDirective};
|
||||
use iron::headers::{CacheControl, CacheDirective, Accept};
|
||||
use iron::mime::*;
|
||||
use iron::modifiers::Header;
|
||||
use iron::prelude::*;
|
||||
|
@ -34,6 +35,11 @@ impl BeforeMiddleware for ASNsMiddleware {
|
|||
}
|
||||
}
|
||||
|
||||
enum OutputType {
|
||||
Json,
|
||||
Html,
|
||||
}
|
||||
|
||||
pub struct WebService;
|
||||
|
||||
impl WebService {
|
||||
|
@ -47,13 +53,116 @@ impl WebService {
|
|||
"See https://iptoasn.com")))
|
||||
}
|
||||
|
||||
fn accept_type(req: &Request) -> OutputType {
|
||||
let mut output_type = OutputType::Json;
|
||||
if let Some(header_accept) = req.headers.get::<Accept>() {
|
||||
for header in header_accept.iter() {
|
||||
match header.item {
|
||||
Mime(TopLevel::Text, SubLevel::Html, _) => {
|
||||
output_type = OutputType::Html;
|
||||
break;
|
||||
}
|
||||
Mime(_, SubLevel::Json, _) => {
|
||||
output_type = OutputType::Json;
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
output_type
|
||||
}
|
||||
|
||||
fn output_json(_ip_str: &str,
|
||||
map: serde_json::Map<&'static str, serde_json::value::Value>,
|
||||
cache_header: Header<CacheControl>)
|
||||
-> IronResult<Response> {
|
||||
let json = serde_json::to_string(&map).unwrap();
|
||||
let mime_json = Mime(TopLevel::Application,
|
||||
SubLevel::Json,
|
||||
vec![(Attr::Charset, Value::Utf8)]);
|
||||
Ok(Response::with((status::Ok, mime_json, cache_header, json)))
|
||||
}
|
||||
|
||||
fn output_html(ip_str: &str,
|
||||
map: serde_json::Map<&'static str, serde_json::value::Value>,
|
||||
cache_header: Header<CacheControl>)
|
||||
-> IronResult<Response> {
|
||||
let mime_html = Mime(TopLevel::Text,
|
||||
SubLevel::Html,
|
||||
vec![(Attr::Charset, Value::Utf8)]);
|
||||
let html = html!{
|
||||
head {
|
||||
title { : "iptoasn lookup" }
|
||||
meta(name="viewport", content="width=device-widthinitial-scale=1") { }
|
||||
link(rel="stylesheet", href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.5/css/bootstrap.min.css", integrity="sha384-AysaV+vQoT3kOAXZkl02PThvDr8HYKPZhNT5h/CXfBThSRXQ6jW5DO2ekP5ViFdi", crossorigin="anonymous") { }
|
||||
style {
|
||||
: "body { margin: 1em 4em }"
|
||||
}
|
||||
}
|
||||
body(class="container-fluid") {
|
||||
header {
|
||||
h1 {
|
||||
: format_args!("Information for IP address: {}", ip_str)
|
||||
}
|
||||
}
|
||||
table {
|
||||
tr {
|
||||
th { : "Announced" }
|
||||
td { : format_args!("{}", map.get("announced")
|
||||
.unwrap().as_bool().unwrap() ) }
|
||||
}
|
||||
@ if map.get("announced").unwrap().as_bool().unwrap() == true {
|
||||
tr {
|
||||
th { : "First IP" }
|
||||
td { : format_args!("{}", map.get("first_ip")
|
||||
.unwrap().as_str().unwrap() )}
|
||||
}
|
||||
tr {
|
||||
th { : "Last IP" }
|
||||
td { : format_args!("{}", map.get("last_ip")
|
||||
.unwrap().as_str().unwrap() )}
|
||||
}
|
||||
tr {
|
||||
th { : "AS Number" }
|
||||
td { : format_args!("{}", map.get("as_number")
|
||||
.unwrap().as_u64().unwrap() )}
|
||||
}
|
||||
tr {
|
||||
th { : "AS Country code" }
|
||||
td { : format_args!("{}", map.get("as_country_code")
|
||||
.unwrap().as_str().unwrap() )}
|
||||
}
|
||||
tr {
|
||||
th { : "AS Description" }
|
||||
td { : format_args!("{}", map.get("as_description")
|
||||
.unwrap().as_str().unwrap() )}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.into_string()
|
||||
.unwrap();
|
||||
let html = format!("<!doctype html>\n<html>\n{}</html>", html);
|
||||
Ok(Response::with((status::Ok, mime_html, cache_header, html)))
|
||||
}
|
||||
|
||||
fn output(output_type: OutputType,
|
||||
ip_str: &str,
|
||||
map: serde_json::Map<&'static str, serde_json::value::Value>,
|
||||
cache_header: Header<CacheControl>)
|
||||
-> IronResult<Response> {
|
||||
match output_type {
|
||||
OutputType::Json => Self::output_json(ip_str, map, cache_header),
|
||||
_ => Self::output_html(ip_str, map, cache_header),
|
||||
}
|
||||
}
|
||||
|
||||
fn ip_lookup(req: &mut Request) -> IronResult<Response> {
|
||||
let mime_text = Mime(TopLevel::Text,
|
||||
SubLevel::Plain,
|
||||
vec![(Attr::Charset, Value::Utf8)]);
|
||||
let mime_json = Mime(TopLevel::Application,
|
||||
SubLevel::Json,
|
||||
vec![(Attr::Charset, Value::Utf8)]);
|
||||
let cache_header = Header(CacheControl(vec![CacheDirective::Public,
|
||||
CacheDirective::MaxAge(TTL)]));
|
||||
let ip_str = match req.extensions.get::<Router>().unwrap().find("ip") {
|
||||
|
@ -80,8 +189,7 @@ impl WebService {
|
|||
None => {
|
||||
let mut map = serde_json::Map::new();
|
||||
map.insert("announced", serde_json::value::Value::Bool(false));
|
||||
let json = serde_json::to_string(&map).unwrap();
|
||||
return Ok(Response::with((status::Ok, mime_json, cache_header, json)));
|
||||
return Self::output(Self::accept_type(&req), ip_str, map, cache_header);
|
||||
}
|
||||
Some(found) => found,
|
||||
};
|
||||
|
@ -97,8 +205,7 @@ impl WebService {
|
|||
serde_json::value::Value::String(found.country.clone()));
|
||||
map.insert("as_description",
|
||||
serde_json::value::Value::String(found.description.clone()));
|
||||
let json = serde_json::to_string(&map).unwrap();
|
||||
Ok(Response::with((status::Ok, mime_json, cache_header, json)))
|
||||
Self::output(Self::accept_type(&req), ip_str, map, cache_header)
|
||||
}
|
||||
|
||||
pub fn start(asns_arc: Arc<RwLock<Arc<ASNs>>>, listen_addr: &str) {
|
||||
|
|
Loading…
Reference in New Issue