diff options
author | Kjetil Orbekk <kjetil.orbekk@gmail.com> | 2017-06-18 12:41:14 -0400 |
---|---|---|
committer | Kjetil Orbekk <kjetil.orbekk@gmail.com> | 2017-06-18 12:41:14 -0400 |
commit | 0b6e7c0ff2e67624a842125a3992b07cd4769e17 (patch) | |
tree | 0066febfa7305cd999ad0f0e9df97f647075858e /src/server.rs | |
parent | 96cd53ca31da2eedf3ef38124cd8f07a79443c00 (diff) |
Support base_url.
Diffstat (limited to 'src/server.rs')
-rw-r--r-- | src/server.rs | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/src/server.rs b/src/server.rs index c0e9028..4e5b6f3 100644 --- a/src/server.rs +++ b/src/server.rs @@ -16,19 +16,26 @@ use router::Router; use staticfile::Static; use systemd::journal; use systemd::unit; -use persistent::Write; +use persistent::{Read, Write}; use rusqlite::Connection; use db; use auth; +use url; #[derive(Debug)] pub struct Context { pub base_url: String, - pub conn: Connection, } impl iron::typemap::Key for Context { type Value = Context; } +#[derive(Debug)] +pub struct State { + pub conn: Connection, +} +impl iron::typemap::Key for State { + type Value = State; +} #[derive(Default, Debug, Clone)] struct Login { @@ -47,6 +54,22 @@ impl iron_sessionstorage::Value for Login { } } +// Construct an absolute url from base_url if provided, or the request url +// otherwise. +fn url_for(r: &mut Request, path: &str) -> Url { + let context = r.get::<Read<Context>>().unwrap(); + match context.base_url.as_ref() { + "" => { + let mut url: url::Url = r.url.clone().into(); + url.set_path(path); + Url::from_generic_url(url).unwrap() + }, + base_url => { + Url::parse(&format!("{}{}", base_url, path)).unwrap() + } + } +} + fn overview(r: &mut Request) -> IronResult<Response> { let mut _value = try!(r.session().get::<Login>()); @@ -139,16 +162,16 @@ fn authenticate(r: &mut Request) -> IronResult<Response> { }; let hash = { - let mutex = r.get::<Write<Context>>().unwrap(); - let context = mutex.lock().unwrap(); - db::lookup_user(&context.conn, &user).unwrap() + let mutex = r.get::<Write<State>>().unwrap(); + let state = mutex.lock().unwrap(); + db::lookup_user(&state.conn, &user).unwrap() }; if let Some(true) = hash.map(|h| auth::validate(&password, &h)) { let login = Login { user: user.to_string() }; // TODO Make a validated login type info!("User logged in: {:?}", login); r.session().set(login)?; - let url = url_for!(r, "root"); + let url = url_for(r, ""); Ok(Response::with((status::Found, Redirect(url)))) } else { login(r) @@ -157,14 +180,17 @@ fn authenticate(r: &mut Request) -> IronResult<Response> { fn logout(r: &mut Request) -> IronResult<Response> { r.session().set::<Login>(Default::default()); - let url = url_for!(r, "root"); + let url = url_for(r, ""); Ok(Response::with((status::Found, Redirect(url)))) } fn make_renderer(r: &mut Request) -> IronResult<render::Renderer> { let user = get_logged_in_user(r)?.map(|u| u.user); - let base_url = format!("{}", url_for!(r, "root")); - Ok(render::Renderer { base_url: base_url, user: user }) + let context = r.get::<Read<Context>>().unwrap(); + Ok(render::Renderer { + base_url: context.base_url.to_string(), + user: user + }) } fn static_file(r: &mut Request) -> IronResult<Response> { @@ -180,7 +206,7 @@ fn static_file(r: &mut Request) -> IronResult<Response> { }) } -pub fn serve(context: Context, port: u16) -> HttpResult<Listening> { +pub fn serve(context: Context, state: State, port: u16) -> HttpResult<Listening> { // TODO: Use a real secret. let secret = b"secret2".to_vec(); let router = router!( @@ -194,7 +220,8 @@ pub fn serve(context: Context, port: u16) -> HttpResult<Listening> { ); let mut chain = Chain::new(router); chain.link_around(SessionStorage::new(SignedCookieBackend::new(secret))); - chain.link(Write::<Context>::both(context)); + chain.link(Read::<Context>::both(context)); + chain.link(Write::<State>::both(state)); let bind_address = format!("{}:{}", "::", port); Iron::new(chain).http(bind_address.as_str()) } |