14 | 14 |
use std::path::Path;
|
15 | 15 |
|
16 | 16 |
use error::{AloysError,aloys_error};
|
17 | |
use helper::with_file_contents;
|
| 17 |
use matching::do_match;
|
| 18 |
use helper::{path_for,with_file};
|
18 | 19 |
|
19 | 20 |
#[derive(Debug, Clone)]
|
20 | 21 |
enum Delegate {
|
|
30 | 31 |
|
31 | 32 |
#[derive(Debug, Clone)]
|
32 | 33 |
struct RouteSpec {
|
| 34 |
conf_at: String,
|
33 | 35 |
for_path: Option<String>,
|
34 | 36 |
for_domain: Option<String>,
|
35 | 37 |
delegate_to: Delegate,
|
|
63 | 65 |
for d in self.routes.iter() {
|
64 | 66 |
let mut matches = true;
|
65 | 67 |
if let Some(ref d) = d.for_domain {
|
66 | |
println!("Matching against {:?}", d);
|
| 68 |
// matches = matches && do_match(d, domain_for(req));
|
67 | 69 |
}
|
68 | 70 |
if let Some(ref p) = d.for_path {
|
69 | |
println!("Matching against {:?}", p);
|
| 71 |
if let Some(req_path) = path_for(req) {
|
| 72 |
matches = matches && do_match(p, req_path);
|
| 73 |
} else {
|
| 74 |
matches = false;
|
| 75 |
}
|
70 | 76 |
}
|
71 | |
return Some(&d.delegate_to);
|
| 77 |
if matches {
|
| 78 |
return Some(&d.delegate_to);
|
| 79 |
}
|
72 | 80 |
}
|
73 | 81 |
return None;
|
74 | 82 |
}
|
|
82 | 90 |
|
83 | 91 |
impl RouteSpec {
|
84 | 92 |
fn from_path(dir: &Path) -> Result<RouteSpec,AloysError> {
|
85 | |
let path = with_file_contents(&dir.join("path"), None, |s| Some(s));
|
86 | |
let domain = with_file_contents(&dir.join("domain"), None, |s| Some(s));
|
87 | |
let mode = with_file_contents(&dir.join("mode"), "http".to_string(), |s| s);
|
88 | |
if mode == "http" {
|
89 | |
aloys_error("Unimplemented".to_string())
|
90 | |
} else if mode == "alyos" {
|
91 | |
let fwd = with_file_contents(&dir.join("conf"),
|
92 | |
"/dev/null".to_string(),
|
93 | |
|s| s);
|
94 | |
let rts = try!(Routes::load_paths(Path::new(&fwd)));
|
95 | |
Ok(RouteSpec { for_path: path,
|
96 | |
for_domain: domain,
|
97 | |
delegate_to: Delegate::Defer(rts) })
|
98 | |
} else {
|
99 | |
aloys_error(format!("Unknown mode `{:?}` in `{:?}", mode, dir))
|
100 | |
}
|
| 93 |
let path = with_file(&dir.join("path"),
|
| 94 |
None,
|
| 95 |
|s| Some(s));
|
| 96 |
let domain = with_file(&dir.join("domain"),
|
| 97 |
None,
|
| 98 |
|s| Some(s));
|
| 99 |
let mode = with_file(&dir.join("mode"),
|
| 100 |
"http".to_string(),
|
| 101 |
|s| s);
|
| 102 |
let delegate =
|
| 103 |
if mode == "http" {
|
| 104 |
let domn = with_file(&dir.join("host"),
|
| 105 |
"localhost".to_string(),
|
| 106 |
|s| s);
|
| 107 |
let port = with_file(&dir.join("port"),
|
| 108 |
Ok(80),
|
| 109 |
|s| s.trim().parse::<u32>() );
|
| 110 |
let port_num = match port {
|
| 111 |
Ok(n) => n,
|
| 112 |
Err(e) => return aloys_error(format!("Bad port number in `{:?}: {:?}`", dir, e)),
|
| 113 |
};
|
| 114 |
Delegate::Forward(HTTPForward { domn: domn,
|
| 115 |
port: port_num })
|
| 116 |
} else if mode == "aloys" {
|
| 117 |
let fwd = with_file(&dir.join("conf"),
|
| 118 |
"/dev/null".to_string(),
|
| 119 |
|s| s);
|
| 120 |
let rts = try!(Routes::load_paths(Path::new(&fwd)));
|
| 121 |
Delegate::Defer(rts)
|
| 122 |
} else {
|
| 123 |
return aloys_error(format!("Unknown mode `{:?}` in `{:?}", mode, dir))
|
| 124 |
};
|
| 125 |
Ok(RouteSpec {
|
| 126 |
conf_at: dir.to_string_lossy().to_string(),
|
| 127 |
for_path: path,
|
| 128 |
for_domain: domain,
|
| 129 |
delegate_to: delegate
|
| 130 |
})
|
101 | 131 |
}
|
102 | 132 |
}
|
103 | 133 |
|
|
116 | 146 |
|
117 | 147 |
|
118 | 148 |
fn run_server() -> Result<(), AloysError> {
|
119 | |
if let Some(target_dir) = args().next() {
|
| 149 |
if let Some(target_dir) = args().skip(1).next() {
|
120 | 150 |
println!("switching to directory {:}", target_dir);
|
121 | 151 |
try!(set_current_dir(Path::new(&target_dir)));
|
122 | 152 |
}
|
123 | 153 |
let cwd = try!(current_dir());
|
124 | 154 |
let paths = try!(Routes::load_paths(cwd.as_path()));
|
| 155 |
println!("Read routes: {:?}", paths);
|
125 | 156 |
let srv = try!(Server::http("127.0.0.1:8080"));
|
126 | 157 |
let _ = srv.handle(paths);
|
127 | 158 |
Ok(())
|