2016-03-22 23:27:12 +00:00
|
|
|
extern crate rocket;
|
|
|
|
|
2017-01-09 02:02:12 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests;
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
use std::env;
|
2019-09-22 22:48:08 +00:00
|
|
|
|
|
|
|
use tokio::fs::File;
|
2016-10-09 03:53:04 +00:00
|
|
|
|
2019-09-11 01:04:34 +00:00
|
|
|
use rocket::{Request, Handler, Route, Data, Catcher, try_outcome};
|
2017-03-31 07:18:58 +00:00
|
|
|
use rocket::http::{Status, RawStr};
|
2018-09-16 10:07:50 +00:00
|
|
|
use rocket::response::{self, Responder, status::Custom};
|
2019-08-27 23:40:23 +00:00
|
|
|
use rocket::handler::{Outcome, HandlerFuture};
|
2017-09-28 21:22:03 +00:00
|
|
|
use rocket::outcome::IntoOutcome;
|
2016-10-04 00:09:13 +00:00
|
|
|
use rocket::http::Method::*;
|
2016-03-22 23:27:12 +00:00
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn forward<'r>(_req: &'r Request, data: Data) -> HandlerFuture<'r> {
|
|
|
|
Box::pin(async move { Outcome::forward(data) })
|
2016-03-22 23:27:12 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn hi<'r>(req: &'r Request, _: Data) -> HandlerFuture<'r> {
|
|
|
|
Box::pin(async move { Outcome::from(req, "Hello!").await })
|
2016-10-08 06:20:49 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn name<'a>(req: &'a Request, _: Data) -> HandlerFuture<'a> {
|
|
|
|
Box::pin(async move {
|
|
|
|
let param = req.get_param::<&'a RawStr>(0)
|
|
|
|
.and_then(|res| res.ok())
|
|
|
|
.unwrap_or("unnamed".into());
|
2018-09-16 10:07:50 +00:00
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
Outcome::from(req, param.as_str()).await
|
|
|
|
})
|
2016-10-07 03:38:13 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn echo_url<'r>(req: &'r Request, _: Data) -> HandlerFuture<'r> {
|
|
|
|
Box::pin(async move {
|
|
|
|
let param_outcome = req.get_param::<&RawStr>(1)
|
|
|
|
.and_then(|res| res.ok())
|
|
|
|
.into_outcome(Status::BadRequest);
|
|
|
|
let param = try_outcome!(param_outcome);
|
|
|
|
Outcome::try_from(req, RawStr::from_str(param).url_decode()).await
|
|
|
|
})
|
2016-10-09 03:53:04 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn upload<'r>(req: &'r Request, data: Data) -> HandlerFuture<'r> {
|
|
|
|
Box::pin(async move {
|
|
|
|
if !req.content_type().map_or(false, |ct| ct.is_plain()) {
|
|
|
|
println!(" => Content-Type of upload must be text/plain. Ignoring.");
|
|
|
|
return Outcome::failure(Status::BadRequest);
|
2016-10-09 03:53:04 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
let file = File::create(env::temp_dir().join("upload.txt")).await;
|
|
|
|
if let Ok(file) = file {
|
2019-08-29 01:32:32 +00:00
|
|
|
if let Ok(n) = data.stream_to(file).await {
|
2019-11-26 16:25:56 +00:00
|
|
|
return Outcome::from(req, format!("OK: {} bytes uploaded.", n)).await;
|
2019-08-27 23:40:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
println!(" => Failed copying.");
|
|
|
|
Outcome::failure(Status::InternalServerError)
|
|
|
|
} else {
|
|
|
|
println!(" => Couldn't open file: {:?}", file.unwrap_err());
|
|
|
|
Outcome::failure(Status::InternalServerError)
|
|
|
|
}
|
|
|
|
})
|
2016-03-22 23:27:12 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn get_upload<'r>(req: &'r Request, _: Data) -> HandlerFuture<'r> {
|
|
|
|
Outcome::from(req, std::fs::File::open(env::temp_dir().join("upload.txt")).ok())
|
2016-12-15 08:47:31 +00:00
|
|
|
}
|
|
|
|
|
2019-08-27 23:40:23 +00:00
|
|
|
fn not_found_handler<'r>(req: &'r Request) -> response::ResultFuture<'r> {
|
2017-05-19 10:29:08 +00:00
|
|
|
let res = Custom(Status::NotFound, format!("Couldn't find: {}", req.uri()));
|
|
|
|
res.respond_to(req)
|
2016-11-05 18:31:50 +00:00
|
|
|
}
|
|
|
|
|
2017-09-28 21:22:03 +00:00
|
|
|
#[derive(Clone)]
|
|
|
|
struct CustomHandler {
|
|
|
|
data: &'static str
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CustomHandler {
|
|
|
|
fn new(data: &'static str) -> Vec<Route> {
|
|
|
|
vec![Route::new(Get, "/<id>", Self { data })]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Handler for CustomHandler {
|
2019-08-27 23:40:23 +00:00
|
|
|
fn handle<'r>(&self, req: &'r Request, data: Data) -> HandlerFuture<'r> {
|
|
|
|
let self_data = self.data;
|
|
|
|
Box::pin(async move {
|
|
|
|
let id_outcome = req.get_param::<&RawStr>(0)
|
|
|
|
.and_then(|res| res.ok())
|
|
|
|
.or_forward(data);
|
|
|
|
|
|
|
|
let id = try_outcome!(id_outcome);
|
2019-11-26 16:25:56 +00:00
|
|
|
Outcome::from(req, format!("{} - {}", self_data, id)).await
|
2019-08-27 23:40:23 +00:00
|
|
|
})
|
2017-09-28 21:22:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 02:02:12 +00:00
|
|
|
fn rocket() -> rocket::Rocket {
|
2016-10-08 06:20:49 +00:00
|
|
|
let always_forward = Route::ranked(1, Get, "/", forward);
|
|
|
|
let hello = Route::ranked(2, Get, "/", hi);
|
|
|
|
|
2018-09-20 04:14:30 +00:00
|
|
|
let echo = Route::new(Get, "/echo/<str>", echo_url);
|
2016-10-08 06:20:49 +00:00
|
|
|
let name = Route::new(Get, "/<name>", name);
|
2016-12-15 08:47:31 +00:00
|
|
|
let post_upload = Route::new(Post, "/", upload);
|
|
|
|
let get_upload = Route::new(Get, "/", get_upload);
|
2016-03-22 23:27:12 +00:00
|
|
|
|
2016-11-05 18:31:50 +00:00
|
|
|
let not_found_catcher = Catcher::new(404, not_found_handler);
|
|
|
|
|
2016-10-04 02:48:33 +00:00
|
|
|
rocket::ignite()
|
2016-12-15 08:47:31 +00:00
|
|
|
.mount("/", vec![always_forward, hello, echo])
|
|
|
|
.mount("/upload", vec![get_upload, post_upload])
|
2016-10-08 06:20:49 +00:00
|
|
|
.mount("/hello", vec![name.clone()])
|
|
|
|
.mount("/hi", vec![name])
|
2017-09-28 21:22:03 +00:00
|
|
|
.mount("/custom", CustomHandler::new("some data here"))
|
2018-09-16 08:47:51 +00:00
|
|
|
.register(vec![not_found_catcher])
|
2017-01-09 02:02:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2019-08-25 02:19:11 +00:00
|
|
|
let _ = rocket().launch();
|
2016-03-22 23:27:12 +00:00
|
|
|
}
|