mirror of
https://codeberg.org/icewind/shelve.git
synced 2026-06-03 12:04:09 +02:00
update to rocket 0.5-rc1
This commit is contained in:
parent
b49d7bb3a9
commit
c359239d27
5 changed files with 1661 additions and 848 deletions
2499
Cargo.lock
generated
2499
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
24
Cargo.toml
24
Cargo.toml
|
|
@ -6,16 +6,16 @@ edition = "2018"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rocket = "0.4.2"
|
rocket = "0.5.0-rc.1"
|
||||||
priority-queue = "0.6.0"
|
priority-queue = "1"
|
||||||
hyper = "0.12"
|
hyper = "0.14"
|
||||||
futures = "0.1.29"
|
dotenv = "0.15"
|
||||||
dotenv = "0.15.0"
|
err-derive = "0.3"
|
||||||
err-derive = "0.2.1"
|
rand = "0.8"
|
||||||
rand = "0.7.2"
|
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
rust-embed = "5.2.0"
|
rust-embed = "5"
|
||||||
rocket_upload = "0.1.0"
|
rocket_upload = "0.1"
|
||||||
serde = "1.0.104"
|
serde = "1"
|
||||||
serde_json = "1.0.45"
|
serde_json = "1"
|
||||||
multipart = "0.16.1"
|
multipart = "0.18"
|
||||||
|
async-trait = "0.1"
|
||||||
61
src/main.rs
61
src/main.rs
|
|
@ -1,12 +1,11 @@
|
||||||
#![feature(proc_macro_hygiene, decl_macro)]
|
|
||||||
|
|
||||||
use crate::expire_queue::{ExpireQueue, InvalidUploadIdError, UploadId};
|
use crate::expire_queue::{ExpireQueue, InvalidUploadIdError, UploadId};
|
||||||
use crate::token::{UploadToken, ValidTokens};
|
use crate::token::{UploadToken, ValidTokens};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use rocket::http::{ContentType, RawStr};
|
use rocket::data::ToByteUnit;
|
||||||
|
use rocket::fs::NamedFile;
|
||||||
use rocket::request::FromParam;
|
use rocket::request::FromParam;
|
||||||
use rocket::response::{NamedFile, Redirect, Responder};
|
use rocket::response::Redirect;
|
||||||
use rocket::*;
|
use rocket::{get, launch, post, put, routes, Data, Responder, State};
|
||||||
use rust_embed::RustEmbed;
|
use rust_embed::RustEmbed;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
@ -14,7 +13,6 @@ use std::collections::HashMap;
|
||||||
use std::env::{self, current_dir};
|
use std::env::{self, current_dir};
|
||||||
use std::fs::{create_dir, read_dir, remove_dir_all, File};
|
use std::fs::{create_dir, read_dir, remove_dir_all, File};
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::Cursor;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::thread::{sleep, spawn, JoinHandle};
|
use std::thread::{sleep, spawn, JoinHandle};
|
||||||
|
|
@ -28,10 +26,8 @@ mod upload;
|
||||||
impl<'r> FromParam<'r> for UploadId {
|
impl<'r> FromParam<'r> for UploadId {
|
||||||
type Error = InvalidUploadIdError;
|
type Error = InvalidUploadIdError;
|
||||||
|
|
||||||
fn from_param(param: &'r RawStr) -> Result<Self, Self::Error> {
|
fn from_param(param: &'r str) -> Result<Self, Self::Error> {
|
||||||
let param = param.url_decode()?;
|
UploadId::new(param)
|
||||||
|
|
||||||
UploadId::new(¶m)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,23 +35,10 @@ impl<'r> FromParam<'r> for UploadId {
|
||||||
#[folder = "templates/"]
|
#[folder = "templates/"]
|
||||||
struct Templates;
|
struct Templates;
|
||||||
|
|
||||||
|
#[derive(Responder)]
|
||||||
|
#[response(content_type = "html")]
|
||||||
struct HtmlResponse(Cow<'static, [u8]>);
|
struct HtmlResponse(Cow<'static, [u8]>);
|
||||||
|
|
||||||
impl<'r> Responder<'r> for HtmlResponse {
|
|
||||||
fn respond_to(self, _: &Request) -> response::Result<'r> {
|
|
||||||
match self.0 {
|
|
||||||
Cow::Borrowed(s) => Response::build()
|
|
||||||
.header(ContentType::HTML)
|
|
||||||
.sized_body(Cursor::new(s))
|
|
||||||
.ok(),
|
|
||||||
Cow::Owned(s) => Response::build()
|
|
||||||
.header(ContentType::HTML)
|
|
||||||
.sized_body(Cursor::new(s))
|
|
||||||
.ok(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
fn home() -> HtmlResponse {
|
fn home() -> HtmlResponse {
|
||||||
HtmlResponse(Templates::get("index.html").unwrap_or(Cow::Borrowed(b"Template not found")))
|
HtmlResponse(Templates::get("index.html").unwrap_or(Cow::Borrowed(b"Template not found")))
|
||||||
|
|
@ -72,13 +55,13 @@ fn now() -> u64 {
|
||||||
const THOUSAND_YEARS: u64 = 1000 * 356 * 24 * 60 * 60;
|
const THOUSAND_YEARS: u64 = 1000 * 356 * 24 * 60 * 60;
|
||||||
|
|
||||||
#[put("/upload?<expire>&<name>", data = "<data>")]
|
#[put("/upload?<expire>&<name>", data = "<data>")]
|
||||||
fn upload(
|
async fn put_upload(
|
||||||
data: Data,
|
data: Data<'_>,
|
||||||
expire: Option<u64>,
|
expire: Option<u64>,
|
||||||
name: String,
|
name: String,
|
||||||
_token: UploadToken,
|
_token: UploadToken,
|
||||||
basedir: State<PathBuf>,
|
basedir: &State<PathBuf>,
|
||||||
expire_queue: State<ExpireQueue>,
|
expire_queue: &State<ExpireQueue>,
|
||||||
) -> io::Result<String> {
|
) -> io::Result<String> {
|
||||||
let id = UploadId::generate(now() + expire.unwrap_or(THOUSAND_YEARS));
|
let id = UploadId::generate(now() + expire.unwrap_or(THOUSAND_YEARS));
|
||||||
expire_queue.push(id);
|
expire_queue.push(id);
|
||||||
|
|
@ -87,7 +70,7 @@ fn upload(
|
||||||
create_dir(&path)?;
|
create_dir(&path)?;
|
||||||
path.push(name);
|
path.push(name);
|
||||||
|
|
||||||
data.stream_to_file(path)?;
|
data.open(2.gibibytes()).into_file(path).await?;
|
||||||
Ok(id.as_string())
|
Ok(id.as_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -107,9 +90,9 @@ struct UploadData {
|
||||||
#[post("/upload", data = "<data>")]
|
#[post("/upload", data = "<data>")]
|
||||||
fn post_upload(
|
fn post_upload(
|
||||||
data: MultipartDatas,
|
data: MultipartDatas,
|
||||||
accepted_tokens: State<ValidTokens>,
|
accepted_tokens: &State<ValidTokens>,
|
||||||
basedir: State<PathBuf>,
|
basedir: &State<PathBuf>,
|
||||||
expire_queue: State<ExpireQueue>,
|
expire_queue: &State<ExpireQueue>,
|
||||||
) -> UploadResponse {
|
) -> UploadResponse {
|
||||||
let mut fields: HashMap<String, String> = data
|
let mut fields: HashMap<String, String> = data
|
||||||
.texts
|
.texts
|
||||||
|
|
@ -181,16 +164,17 @@ fn post_upload(
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/<id>/<name..>")]
|
#[get("/<id>/<name..>")]
|
||||||
fn download(id: UploadId, name: PathBuf, basedir: State<PathBuf>) -> Option<NamedFile> {
|
async fn download(id: UploadId, name: PathBuf, basedir: &State<PathBuf>) -> Option<NamedFile> {
|
||||||
if id.is_expired(now()) {
|
if id.is_expired(now()) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let path = basedir.join(id.as_string()).join(name);
|
let path = basedir.join(id.as_string()).join(name);
|
||||||
NamedFile::open(path).ok()
|
NamedFile::open(path).await.ok()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
#[launch]
|
||||||
|
fn rockert() -> _ {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
|
|
||||||
let mut env: HashMap<_, _> = env::vars().collect();
|
let mut env: HashMap<_, _> = env::vars().collect();
|
||||||
|
|
@ -209,12 +193,11 @@ fn main() {
|
||||||
|
|
||||||
expire_job(basedir.clone(), expire_queue.clone());
|
expire_job(basedir.clone(), expire_queue.clone());
|
||||||
|
|
||||||
rocket::ignite()
|
rocket::build()
|
||||||
.manage(tokens)
|
.manage(tokens)
|
||||||
.manage(basedir.clone())
|
.manage(basedir.clone())
|
||||||
.manage(expire_queue)
|
.manage(expire_queue)
|
||||||
.mount("/", routes![home, upload, post_upload, download])
|
.mount("/", routes![home, put_upload, post_upload, download])
|
||||||
.launch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expire_job(expire_basedir: PathBuf, expire_queue: ExpireQueue) -> JoinHandle<()> {
|
fn expire_job(expire_basedir: PathBuf, expire_queue: ExpireQueue) -> JoinHandle<()> {
|
||||||
|
|
|
||||||
|
|
@ -37,12 +37,14 @@ pub enum UploadTokenError {
|
||||||
Invalid,
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for UploadToken {
|
#[async_trait::async_trait]
|
||||||
|
impl<'r> FromRequest<'r> for UploadToken {
|
||||||
type Error = UploadTokenError;
|
type Error = UploadTokenError;
|
||||||
|
|
||||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
|
async fn from_request(request: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
|
||||||
let accepted_tokens = request
|
let accepted_tokens = request
|
||||||
.guard::<State<ValidTokens>>()
|
.guard::<&State<ValidTokens>>()
|
||||||
|
.await
|
||||||
.expect("No tokens configured");
|
.expect("No tokens configured");
|
||||||
let keys: Vec<_> = request.headers().get("x-upload-token").collect();
|
let keys: Vec<_> = request.headers().get("x-upload-token").collect();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ use std::fs::{self, File};
|
||||||
use std::io::{Cursor, Read, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use rocket::data::{self, FromDataSimple};
|
use rocket::data::{self, FromData, Outcome, ToByteUnit};
|
||||||
use rocket::{Data, Outcome, Request};
|
use rocket::{Data, Request};
|
||||||
|
|
||||||
use multipart::server::Multipart;
|
use multipart::server::Multipart;
|
||||||
|
|
||||||
|
|
@ -41,10 +41,14 @@ impl Drop for FilePart {
|
||||||
|
|
||||||
const TMP_PATH: &str = "/tmp/rust_upload/";
|
const TMP_PATH: &str = "/tmp/rust_upload/";
|
||||||
|
|
||||||
impl<'t> FromDataSimple for MultipartDatas {
|
#[async_trait::async_trait]
|
||||||
|
impl<'r> FromData<'r> for MultipartDatas {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
fn from_data(request: &Request, data: Data) -> data::Outcome<Self, String> {
|
async fn from_data(
|
||||||
|
request: &'r Request<'_>,
|
||||||
|
data: Data<'r>,
|
||||||
|
) -> data::Outcome<'r, Self, String> {
|
||||||
let ct = request
|
let ct = request
|
||||||
.headers()
|
.headers()
|
||||||
.get_one("Content-Type")
|
.get_one("Content-Type")
|
||||||
|
|
@ -53,7 +57,10 @@ impl<'t> FromDataSimple for MultipartDatas {
|
||||||
let boundary = &ct[(idx + "boundary=".len())..];
|
let boundary = &ct[(idx + "boundary=".len())..];
|
||||||
|
|
||||||
let mut d = Vec::new();
|
let mut d = Vec::new();
|
||||||
data.stream_to(&mut d).expect("Unable to read");
|
data.open(2.gibibytes())
|
||||||
|
.stream_to(&mut d)
|
||||||
|
.await
|
||||||
|
.expect("Unable to read");
|
||||||
|
|
||||||
let mut mp = Multipart::with_body(Cursor::new(d), boundary);
|
let mut mp = Multipart::with_body(Cursor::new(d), boundary);
|
||||||
let mut texts = Vec::new();
|
let mut texts = Vec::new();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue