update dependencies, urlencode filename

This commit is contained in:
neri 2021-03-09 19:59:10 +01:00
parent f100450796
commit 9e38960f00
4 changed files with 1096 additions and 713 deletions

1736
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,19 +7,19 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = { version = "2.0.0", default-features = false, features = [] }
sqlx = { version = "0.3.5", default-features = false, features = [ "runtime-async-std", "postgres", "chrono" ] }
actix-rt = "1.1.1"
env_logger = "0.7.1"
log = "0.4.8"
actix-files = "0.2.2"
async-std = "1.6.2"
actix-multipart = "0.2.0"
futures = "0.3.5"
rand = "0.7.3"
chrono = "0.4.13"
openssl-sys = "*"
actix-web = "3.3.2"
sqlx = { version = "0.5.1", default-features = false, features = [ "runtime-async-std-rustls", "postgres", "chrono" ] }
env_logger = "0.8.3"
log = "0.4.14"
actix-files = "0.5.0"
async-std = "1.9.0"
actix-multipart = "0.3.0"
futures = "0.3.13"
rand = "0.8.3"
chrono = "0.4.19"
openssl-sys = "0.9.60"
htmlescape = "0.3.1"
urlencoding = "1.1.1"
[features]
vendored = ["openssl-sys/vendored"]

View File

@ -1,18 +1,18 @@
use async_std::{fs, path::PathBuf, sync::Receiver, task};
use async_std::{channel::Receiver, fs, path::PathBuf, task};
use chrono::{prelude::*, Duration};
use futures::future::FutureExt;
use sqlx::{postgres::PgPool, Cursor, Row};
use futures::{TryStreamExt, future::FutureExt};
use sqlx::{postgres::PgPool, Row};
pub(crate) async fn delete_old_files(receiver: Receiver<()>, db: PgPool, files_dir: PathBuf) {
loop {
wait_for_file_expiry(&receiver, &db).await;
let now = Local::now().naive_local();
let mut cursor = sqlx::query("SELECT file_id FROM files WHERE files.valid_till < $1")
let mut rows = sqlx::query("SELECT file_id FROM files WHERE files.valid_till < $1")
.bind(now)
.fetch(&db);
while let Some(row) = cursor.next().await.expect("could not load expired files") {
let file_id: String = row.get("file_id");
while let Some(row) = rows.try_next().await.expect("could not load expired files") {
let file_id: String = row.try_get("file_id").expect("we selected this column");
let mut path = files_dir.clone();
path.push(&file_id);
if path.exists().await {
@ -30,9 +30,9 @@ pub(crate) async fn delete_old_files(receiver: Receiver<()>, db: PgPool, files_d
}
async fn wait_for_file_expiry(receiver: &Receiver<()>, db: &PgPool) {
let mut cursor = sqlx::query("SELECT MIN(valid_till) as min from files").fetch(db);
let row = cursor
.next()
let mut rows = sqlx::query("SELECT MIN(valid_till) as min from files").fetch(db);
let row = rows
.try_next()
.await
.expect("could not fetch expiring files from database")
.expect("postgres min did not return any row");

View File

@ -12,15 +12,16 @@ use actix_web::{
App, Error, FromRequest, HttpRequest, HttpResponse, HttpServer,
};
use async_std::{
channel::{self, Sender},
fs,
path::PathBuf,
sync::{channel, Sender},
task,
};
use file_kind::FileKind;
use futures::TryStreamExt;
use sqlx::{
postgres::{PgPool, PgRow},
Cursor, Row,
postgres::{PgPool, PgPoolOptions, PgRow},
Row,
};
use std::env;
@ -92,10 +93,11 @@ async fn upload(
kind
);
expiry_watch_sender.send(()).await;
expiry_watch_sender.send(()).await.unwrap();
let redirect = if kind == FileKind::BINARY && original_name.is_some() {
format!("/upload/{}/{}", file_id, original_name.as_ref().unwrap())
let encoded_name = urlencoding::encode(original_name.as_ref().unwrap());
format!("/upload/{}/{}", file_id, encoded_name)
} else {
format!("/upload/{}", file_id)
};
@ -113,7 +115,8 @@ fn get_host_url(req: &web::HttpRequest) -> String {
fn get_file_url(req: &web::HttpRequest, id: &str, name: Option<&str>) -> String {
if let Some(name) = name {
format!("{}/file/{}/{}", get_host_url(req), id, name)
let encoded_name = urlencoding::encode(name);
format!("{}/file/{}/{}", get_host_url(req), id, encoded_name)
} else {
format!("{}/file/{}", get_host_url(req), id)
}
@ -135,11 +138,11 @@ async fn download(
config: web::Data<Config>,
) -> Result<HttpResponse, Error> {
let id = req.match_info().query("id");
let mut cursor = sqlx::query("SELECT file_id, file_name, kind from files WHERE file_id = $1")
let mut rows = sqlx::query("SELECT file_id, file_name, kind from files WHERE file_id = $1")
.bind(id)
.fetch(db.as_ref());
let row: PgRow = cursor
.next()
let row: PgRow = rows
.try_next()
.await
.map_err(|_| error::ErrorInternalServerError("could not run select statement"))?
.ok_or_else(|| error::ErrorNotFound("file does not exist or has expired"))?;
@ -204,10 +207,10 @@ async fn setup_db() -> PgPool {
let conn_url = &get_db_url();
log::info!("Using Connection string {}", conn_url);
let pool = PgPool::builder()
.max_size(5)
let pool = PgPoolOptions::new()
.max_connections(5)
.connect_timeout(std::time::Duration::from_secs(5))
.build(conn_url)
.connect(conn_url)
.await
.expect("could not create db pool");
@ -224,7 +227,7 @@ struct Config {
files_dir: PathBuf,
}
#[actix_rt::main]
#[actix_web::main]
async fn main() -> std::io::Result<()> {
if env::var("RUST_LOG").is_err() {
env::set_var("RUST_LOG", "info");
@ -238,7 +241,7 @@ async fn main() -> std::io::Result<()> {
fs::create_dir_all(&config.files_dir)
.await
.expect("could not create directory for storing files");
let (sender, receiver) = channel(8);
let (sender, receiver) = channel::bounded(8);
log::info!("omnomnom");