]>
Commit | Line | Data |
---|---|---|
c8402f1c | 1 | use std::path::{Path, PathBuf}; |
d1df2e73 | 2 | |
c8402f1c SW |
3 | const DATA_PATH: &str = "/var/lib/voter"; |
4 | ||
5 | fn validate_path(path: &str) -> Result<PathBuf, cgi::Response> { | |
6 | let invalid_path = || cgi::text_response(404, "Invalid path"); | |
7 | if path == "/" { | |
8 | return Err(cgi::text_response(404, "(This is the voting place. You should have been given a more specific URL for the specific thing you've been invited to vote on.)")); | |
9 | } | |
10 | if path.contains("..") || !path.starts_with("/") { | |
11 | return Err(invalid_path()); | |
12 | } | |
13 | let dir = Path::new(&format!("{DATA_PATH}{path}")).to_path_buf(); | |
14 | if !dir | |
15 | .canonicalize() | |
16 | .map_err(|_| invalid_path())? | |
17 | .starts_with(DATA_PATH) | |
18 | { | |
19 | return Err(invalid_path()); | |
20 | } | |
21 | if !dir.is_dir() { | |
22 | return Err(invalid_path()); | |
23 | } | |
24 | Ok(dir) | |
25 | } | |
26 | ||
27 | fn prompt_for_vote(dir: PathBuf, request: cgi::Request) -> Result<cgi::Response, cgi::Response> { | |
28 | Err(cgi::text_response(503, "Not Implemented")) | |
29 | } | |
30 | ||
31 | fn record_vote(dir: PathBuf, request: cgi::Request) -> Result<cgi::Response, cgi::Response> { | |
32 | Err(cgi::text_response(503, "Not Implemented")) | |
33 | } | |
34 | ||
35 | fn respond(request: cgi::Request) -> Result<cgi::Response, cgi::Response> { | |
36 | let dir = validate_path(request.uri().path())?; | |
37 | match request.method() { | |
38 | &cgi::http::Method::GET => prompt_for_vote(dir, request), | |
39 | &cgi::http::Method::POST => record_vote(dir, request), | |
40 | _ => Err(cgi::text_response(405, "Huh?")), | |
41 | } | |
42 | } | |
43 | ||
44 | fn respond_or_report_error(request: cgi::Request) -> cgi::Response { | |
45 | match respond(request) { | |
46 | Ok(result) => result, | |
47 | Err(error) => error, | |
48 | } | |
d1df2e73 SW |
49 | } |
50 | ||
c8402f1c | 51 | cgi::cgi_main! { respond_or_report_error } |