switch to rererouter

This commit is contained in:
Stepan Kuzmin 2017-11-27 12:48:31 +03:00
parent a5c8294d3c
commit 2ae8917591
5 changed files with 73 additions and 81 deletions

18
Cargo.lock generated
View File

@ -9,7 +9,7 @@ dependencies = [
"r2d2 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
"r2d2_postgres 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rererouter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -188,7 +188,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"plugin 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -253,7 +253,7 @@ dependencies = [
[[package]]
name = "mime_guess"
version = "1.8.2"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -431,6 +431,15 @@ name = "regex-syntax"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rererouter"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"iron 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "safemem"
version = "0.2.0"
@ -623,7 +632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum md5 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b6d9aab58e540f50b59d5cfa7f0da4c3d437476890e1e0b6206e230dce55a23c"
"checksum memchr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
"checksum mime_guess 1.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bbee1a836f344ac39d4a59bfe7be2bd3150353ff71678afb740216f8270b333e"
"checksum mime_guess 1.8.3 (registry+https://github.com/rust-lang/crates.io-index)" = "dc7e82a15629bb4ecd9e72365bf33d1382be91e030f820edb8e2a21c02430da8"
"checksum modifier 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "41f5c9112cb662acd3b204077e0de5bc66305fa8df65c8019d5adb10e9ab6e58"
"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
"checksum num_cpus 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "514f0d73e64be53ff320680ca671b64fe3fb91da01e1ae2ddc99eb51d453b20d"
@ -643,6 +652,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum redox_syscall 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "8dde11f18c108289bef24469638a04dce49da56084f2d50618b226e47eb04509"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum rererouter 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6101256368bbe7fcafa77c01b834cebfc41c5832dffb81eee43867abfc4a2621"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum scheduled-thread-pool 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d9fbe48ead32343b76f544c85953bf260ed39219a8bbbb62cd85f6a00f9644f"
"checksum sha2 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7d963c78ce367df26d7ea8b8cc655c651b42e8a1e584e869c1e17dae3ccb116a"

View File

@ -8,11 +8,11 @@ name = "falcon"
path = "src/main.rs"
[dependencies]
url = "1.6.0"
regex = "0.2.2"
iron = "0.6.0"
rererouter = "0.1.1"
persistent = "0.4.0"
lazy_static = "0.2.11"
r2d2 = "0.7.4"
r2d2_postgres = "0.13.0"
postgres = { version = "0.15.1", features = ["with-time", "with-uuid"] }
postgres = { version = "0.15.1", features = ["with-time", "with-uuid"] }

View File

@ -1,24 +1,31 @@
extern crate url;
extern crate iron;
extern crate regex;
extern crate persistent;
extern crate rererouter;
extern crate r2d2;
extern crate r2d2_postgres;
#[macro_use] extern crate lazy_static;
// #[macro_use] extern crate lazy_static;
use std::env;
use persistent::Read;
use rererouter::RouterBuilder;
use iron::prelude::{Iron, Chain};
mod db;
mod cors;
mod router;
mod routes;
fn main() {
let conn_string: String = env::var("DATABASE_URL")
.expect("DATABASE_URL must be set");
let mut chain = Chain::new(router::handler);
let mut router_builder = RouterBuilder::new();
router_builder.get(r"/index.json", routes::index);
router_builder.get(r"/(?P<tileset>[\w|\.]*)\.json", routes::tileset);
router_builder.get(r"/(?P<tileset>[\w|\.]*)/(?P<z>\d*)/(?P<x>\d*)/(?P<y>\d*).pbf", routes::tile);
let router = router_builder.finalize();
let mut chain = Chain::new(router);
println!("Connecting to postgres: {}", conn_string);
match db::setup_connection_pool(&conn_string, 10) {
@ -41,4 +48,4 @@ fn main() {
let bind_addr = format!("0.0.0.0:{}", port);
println!("Server has been started on {}.", bind_addr);
Iron::new(chain).http(bind_addr.as_str()).unwrap();
}
}

View File

@ -1,70 +0,0 @@
use url::Url;
use regex::{Regex, Captures};
use iron::prelude::{Plugin};
use iron::{status, mime, Request, Response, IronResult};
use persistent::Read;
use super::db;
type RouteHandler = fn(&mut Request, Captures) -> IronResult<Response>;
lazy_static! {
static ref ROUTES_VEC: Vec<(Regex, RouteHandler)> = vec![
(Regex::new(r"^/index.json$").unwrap(), index),
(Regex::new(r"^/(?P<tileset>[\w|\.]*)\.json$").unwrap(), tileset),
(Regex::new(r"^/(?P<tileset>[\w|\.]*)/(?P<z>\d*)/(?P<x>\d*)/(?P<y>\d*).pbf$").unwrap(), tile)
];
}
pub fn handler(req: &mut Request) -> IronResult<Response> {
println!("{} {} {}", req.method, req.version, req.url);
let url: Url = req.url.clone().into();
match ROUTES_VEC.clone().into_iter().find(|ref x| x.0.is_match(url.path())) {
Some((re, handler)) => {
let captures = re.captures(url.path()).unwrap();
handler(req, captures)
}
None => Ok(Response::with((status::NotFound)))
}
}
fn index(_req: &mut Request, _caps: Captures) -> IronResult<Response> {
println!("index.json");
Ok(Response::with((status::Ok, "index.json")))
}
fn tileset(_req: &mut Request, _caps: Captures) -> IronResult<Response> {
println!("tileset {:?}", _caps);
Ok(Response::with((status::Ok, "tileset")))
}
fn tile(req: &mut Request, caps: Captures) -> IronResult<Response> {
let tilesets = req.get::<Read<db::Tilesets>>().unwrap();
let tileset = match tilesets.get(&caps["tileset"]) {
Some(tileset) => tileset,
None => return Ok(Response::with((status::NotFound)))
};
let conn = match db::get_connection(req) {
Ok(conn) => conn,
Err(error) => {
eprintln!("Couldn't get a connection to postgres: {}", error);
return Ok(Response::with((status::InternalServerError)));
}
};
let tile = match db::get_tile(conn, &tileset.schema, &tileset.table, &caps["z"], &caps["x"], &caps["y"]) {
Ok(tile) => tile,
Err(error) => {
eprintln!("Couldn't get a tile: {}", error);
return Ok(Response::with((status::InternalServerError)));
}
};
let content_type = "application/x-protobuf".parse::<mime::Mime>().unwrap();
match tile.len() {
0 => Ok(Response::with((content_type, status::NoContent))),
_ => Ok(Response::with((content_type, status::Ok, tile)))
}
}

45
src/routes.rs Normal file
View File

@ -0,0 +1,45 @@
use regex::Captures;
use iron::prelude::{Plugin};
use iron::{status, mime, Request, Response, IronResult};
use persistent::Read;
use super::db;
pub fn index(_req: &mut Request, _caps: Captures) -> IronResult<Response> {
println!("index.json");
Ok(Response::with((status::Ok, "{}")))
}
pub fn tileset(_req: &mut Request, _caps: Captures) -> IronResult<Response> {
Ok(Response::with((status::Ok, "{}")))
}
pub fn tile(req: &mut Request, caps: Captures) -> IronResult<Response> {
let tilesets = req.get::<Read<db::Tilesets>>().unwrap();
let tileset = match tilesets.get(&caps["tileset"]) {
Some(tileset) => tileset,
None => return Ok(Response::with((status::NotFound)))
};
let conn = match db::get_connection(req) {
Ok(conn) => conn,
Err(error) => {
eprintln!("Couldn't get a connection to postgres: {}", error);
return Ok(Response::with((status::InternalServerError)));
}
};
let tile = match db::get_tile(conn, &tileset.schema, &tileset.table, &caps["z"], &caps["x"], &caps["y"]) {
Ok(tile) => tile,
Err(error) => {
eprintln!("Couldn't get a tile: {}", error);
return Ok(Response::with((status::InternalServerError)));
}
};
let content_type = "application/x-protobuf".parse::<mime::Mime>().unwrap();
match tile.len() {
0 => Ok(Response::with((content_type, status::NoContent))),
_ => Ok(Response::with((content_type, status::Ok, tile)))
}
}