Skip to content

Commit

Permalink
Merge branch 'release/0.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
s3rius committed Jun 14, 2022
2 parents 5e09de3 + 869a409 commit 6c8d4fe
Show file tree
Hide file tree
Showing 28 changed files with 485 additions and 652 deletions.
654 changes: 283 additions & 371 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rustus"
version = "0.4.13"
version = "0.5.0"
edition = "2021"
description = "TUS protocol implementation written in Rust."
keywords = [
Expand All @@ -23,15 +23,17 @@ name = "rustus"
[dependencies]
async-trait = "^0.1.52"
base64 = "^0.13.0"
lazy_static = "^1.4.0"
log = "^0.4.14"
serde_json = "^1"
strfmt = "^0.1.6"
thiserror = "^1.0"
url = "^2.2.2"
bytes = "^1.1.0"
prometheus = "^0.13.0"
actix-web-prom = "^0.6.0"
dyn-clone = "^1.0.5"
actix-cors = "0.6.1"
wildmatch = "2.1.0"


[dependencies.digest]
version = "0.10.3"
Expand Down Expand Up @@ -66,7 +68,7 @@ features = ["vendored"]
version = "^0.6.0-beta.13"

[dependencies.actix-web]
version = "^4.0.0-rc.3"
version = "^4.0.1"

[dependencies.chrono]
features = ["serde"]
Expand Down Expand Up @@ -113,7 +115,7 @@ version = "^0.3"

[dependencies.strum]
features = ["derive"]
version = "^0.23"
version = "0.24.0"

[dependencies.tokio]
features = ["time", "process", "fs", "io-std", "io-util", "rt-multi-thread", "bytes", "rt", "macros"]
Expand Down
19 changes: 10 additions & 9 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ Also you can configure number of actix `workers` that handle connections.

`--workers` by default is euqal to number of physical CPU cores. Edit it carefully.

`--cors` is a list of allowed hosts with wildcards separated by commas. By default all hosts are allowed.
You can define which hosts are allowed for your particular application.

For example if you add `--cors "*.staging.domain,*.prod.domain"`, it allows all origins
like `my.staging.domain` or `my.prod.domain`, but it will refuse to serve other origins.

=== "CLI"

``` bash
Expand All @@ -30,6 +36,7 @@ Also you can configure number of actix `workers` that handle connections.
--max-body-size 1000000 \
--url "/files" \
--log-level "INFO"
--cors "my.*.domain.com,your.*.domain.com"
```

=== "ENV"
Expand All @@ -41,6 +48,7 @@ Also you can configure number of actix `workers` that handle connections.
export RUSTUS_MAX_BODY_SIZE="1000000"
export RUSTUS_URL="/files"
export RUSTUS_LOG_LEVEL="INFO"
export RUSTUS_CORS="my.*.domain.com,your.*.domain.com"

rustus
```
Expand Down Expand Up @@ -70,20 +78,13 @@ Available variables:
* `{day}` - current day number from 1 to 31;
* `{hour}` - hour number from 0 to 23;
* `{minute}` - minute number from 0 to 59;
* `{env[ENV_NAME]}` - environment variable where `ENV_NAME` is name of your variable.

!!! note

All environment variables are saved in memory during rustus startup.
So you cannot change variable dynamically. Even if you change env used in
structure pattern it won't change.

For example if you use `{env[HOSTNAME]}/{year}/{month}/{day}` as your dir-structure, rustus stores files like:
For example if you use `files/{year}/{month}/{day}` as your dir-structure, rustus stores files like:

``` bash
$ tree data
data
└── rtus-68cb5b8746-5mgw9
└── files
└── 2022
└── 1
└── 8
Expand Down
6 changes: 6 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,12 @@ pub struct RustusConf {
#[structopt(long, default_value = "/files", env = "RUSTUS_URL")]
pub url: String,

/// Allowed hosts for CORS protocol.
///
/// By default all hosts are allowed.
#[structopt(long, env = "RUSTUS_CORS", use_delimiter = true)]
pub cors: Vec<String>,

/// Maximum payload size.
///
/// This limit used to reduce amount of consumed memory.
Expand Down
2 changes: 2 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ pub enum RustusError {
WrongHeaderValue,
#[error("Metrics error: {0}")]
PrometheusError(#[from] prometheus::Error),
#[error("Blocking error: {0}")]
BlockingError(#[from] actix_web::error::BlockingError),
}

/// This conversion allows us to use `RustusError` in the `main` function.
Expand Down
7 changes: 4 additions & 3 deletions src/info_storages/db_info_storage.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::time::Duration;
use std::{sync::Arc, time::Duration};

use async_trait::async_trait;
use rbatis::{crud::CRUD, crud_table, db::DBPoolOptions, rbatis::Rbatis};
Expand All @@ -25,8 +25,9 @@ impl TryFrom<&FileInfo> for DbModel {
}
}

#[derive(Clone)]
pub struct DBInfoStorage {
db: Rbatis,
db: Arc<Rbatis>,
}

impl DBInfoStorage {
Expand All @@ -35,7 +36,7 @@ impl DBInfoStorage {
let mut opts = DBPoolOptions::new();
opts.connect_timeout = Duration::new(2, 0);
db.link_opt(dsn, opts).await?;
Ok(Self { db })
Ok(Self { db: Arc::new(db) })
}
}

Expand Down
1 change: 1 addition & 0 deletions src/info_storages/file_info_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::{
info_storages::{FileInfo, InfoStorage},
};

#[derive(Clone)]
pub struct FileInfoStorage {
info_dir: PathBuf,
}
Expand Down
5 changes: 4 additions & 1 deletion src/info_storages/models/info_store.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use crate::{errors::RustusResult, info_storages::FileInfo};
use async_trait::async_trait;
use dyn_clone::DynClone;

/// Trait for every info storage.
///
/// This trait defines required functions
/// for building your own info storage.
#[async_trait]
pub trait InfoStorage {
pub trait InfoStorage: DynClone {
/// Prepare storage for storing files.
///
/// In this function you can prepare
Expand Down Expand Up @@ -39,3 +40,5 @@ pub trait InfoStorage {
/// associated with the given `file_id`.
async fn remove_info(&self, file_id: &str) -> RustusResult<()>;
}

dyn_clone::clone_trait_object!(InfoStorage);
1 change: 1 addition & 0 deletions src/info_storages/redis_info_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
info_storages::{FileInfo, InfoStorage},
};

#[derive(Clone)]
pub struct RedisStorage {
pool: Pool<RedisConnectionManager>,
}
Expand Down
44 changes: 41 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![cfg_attr(coverage, feature(no_coverage))]

use std::{str::FromStr, sync::Arc};
use std::str::FromStr;

use actix_cors::Cors;
use actix_web::{
dev::{Server, Service},
http::Method,
Expand All @@ -14,6 +15,7 @@ use fern::{
use log::{error, LevelFilter};

use config::RustusConf;
use wildmatch::WildMatch;

use crate::{
errors::{RustusError, RustusResult},
Expand Down Expand Up @@ -61,6 +63,41 @@ fn greeting(app_conf: &RustusConf) {
eprintln!();
}

/// Create CORS rules for the server.
///
/// CORS rules are applied to every handler.
///
/// If the origins vector is empty all origins are
/// welcome, otherwise it will create a wildcard match for
/// every host.
fn create_cors(origins: Vec<String>) -> Cors {
let mut cors = Cors::default()
.allowed_methods(vec!["OPTIONS", "GET", "HEAD", "POST", "PATCH", "DELETE"])
.allowed_headers(vec![
"Content-Type",
"Upload-Offset",
"Upload-Checksum",
"Upload-Length",
"Upload-Metadata",
"Upload-Concat",
"Upload-Defer-Length",
]);

// We allow any origin by default if no origin is specified.
if origins.is_empty() {
return cors.allow_any_origin();
}

// Adding origins.
for origin in origins {
cors = cors.allowed_origin_fn(move |request_origin, _| {
WildMatch::new(origin.clone().as_str()) == request_origin.to_str().unwrap_or_default()
});
}

cors
}

/// Creates Actix server.
///
/// This function is parametrized with
Expand All @@ -78,8 +115,8 @@ fn greeting(app_conf: &RustusConf) {
pub fn create_server(state: State) -> RustusResult<Server> {
let host = state.config.host.clone();
let port = state.config.port;
let cors_hosts = state.config.cors.clone();
let workers = state.config.workers;
let state_data: web::Data<State> = web::Data::from(Arc::new(state));
let metrics = actix_web_prom::PrometheusMetricsBuilder::new("")
.endpoint("/metrics")
.build()
Expand All @@ -104,9 +141,10 @@ pub fn create_server(state: State) -> RustusResult<Server> {
App::new()
.app_data(web::Data::new(active_uploads.clone()))
.app_data(web::Data::new(file_sizes.clone()))
.configure(rustus_service(state_data.clone()))
.configure(rustus_service(state.clone()))
.wrap(metrics.clone())
.wrap(middleware::Logger::new("\"%r\" \"-\" \"%s\" \"%a\" \"%D\""))
.wrap(create_cors(cors_hosts.clone()))
// Middleware that overrides method of a request if
// "X-HTTP-Method-Override" header is provided.
.wrap_fn(|mut req, srv| {
Expand Down
2 changes: 2 additions & 0 deletions src/notifiers/amqp_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,15 @@ use strum::IntoEnumIterator;
use tokio_amqp::LapinTokioExt;

#[allow(clippy::struct_excessive_bools)]
#[derive(Clone)]
pub struct DeclareOptions {
pub declare_exchange: bool,
pub durable_exchange: bool,
pub declare_queues: bool,
pub durable_queues: bool,
}

#[derive(Clone)]
pub struct AMQPNotifier {
exchange_name: String,
pool: Pool<RMQConnectionManager>,
Expand Down
1 change: 1 addition & 0 deletions src/notifiers/dir_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use log::debug;
use std::path::PathBuf;
use tokio::process::Command;

#[derive(Clone)]
pub struct DirNotifier {
pub dir: PathBuf,
}
Expand Down
1 change: 1 addition & 0 deletions src/notifiers/file_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use async_trait::async_trait;
use log::debug;
use tokio::process::Command;

#[derive(Clone)]
pub struct FileNotifier {
pub command: String,
}
Expand Down
1 change: 1 addition & 0 deletions src/notifiers/http_notifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use log::debug;
use reqwest::Client;
use std::time::Duration;

#[derive(Clone)]
pub struct HttpNotifier {
urls: Vec<String>,
client: Client,
Expand Down
Loading

0 comments on commit 6c8d4fe

Please sign in to comment.