From 27d286b266fca105aebc8c1502b69b7be0804681 Mon Sep 17 00:00:00 2001
From: Pavel Kirilin <win10@list.ru>
Date: Mon, 20 Dec 2021 21:52:40 +0400
Subject: [PATCH] Updated Dockerfile and added max body size constraint.

Signed-off-by: Pavel Kirilin <win10@list.ru>
---
 Cargo.lock                      | 11 -----------
 Cargo.toml                      |  1 -
 deploy/Dockerfile               |  2 +-
 src/config.rs                   | 15 ++++++++++++---
 src/main.rs                     |  3 ++-
 src/protocol/core/mod.rs        |  3 +++
 src/protocol/core/routes.rs     |  2 +-
 src/protocol/creation/routes.rs |  3 +++
 src/storages/mod.rs             |  5 ++---
 9 files changed, 24 insertions(+), 21 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 9344365..226797f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1139,16 +1139,6 @@ dependencies = [
  "version_check 0.9.3",
 ]
 
-[[package]]
-name = "gethostname"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028"
-dependencies = [
- "libc",
- "winapi 0.3.9",
-]
-
 [[package]]
 name = "getrandom"
 version = "0.1.16"
@@ -2120,7 +2110,6 @@ dependencies = [
  "base64",
  "chrono",
  "derive_more",
- "gethostname",
  "log",
  "sea-orm",
  "serde",
diff --git a/Cargo.toml b/Cargo.toml
index 4d77239..03374cf 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -24,6 +24,5 @@ log = "^0.4.14"
 url = "2.2.2"
 base64 = "^0.13.0"
 simple-logging = { version = "^2.0.2" }
-gethostname = "0.2.1"
 strfmt = "^0.1.6"
 sea-orm = { version = "^0.4.2", features = ["runtime-async-std-rustls", "sqlx-all", "sqlx-chrono"] }
\ No newline at end of file
diff --git a/deploy/Dockerfile b/deploy/Dockerfile
index ebd5b60..596d252 100644
--- a/deploy/Dockerfile
+++ b/deploy/Dockerfile
@@ -13,7 +13,7 @@ RUN cargo chef cook --release --recipe-path recipe.json
 COPY . .
 RUN cargo build --release --bin rustus
 
-FROM debian:buster-20211201-slim AS runtime
+FROM debian:bullseye-20211201-slim AS runtime
 WORKDIR app
 COPY --from=builder /app/target/release/rustus /usr/local/bin/
 ENTRYPOINT ["/usr/local/bin/rustus"]
diff --git a/src/config.rs b/src/config.rs
index 18e3ec9..8040419 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,5 @@
 use std::collections::HashMap;
+use std::env;
 use std::path::PathBuf;
 
 use chrono::{Datelike, Timelike};
@@ -83,6 +84,14 @@ pub struct RustusConf {
     #[structopt(long, default_value = "/files", env = "RUSTUS_URL")]
     pub url: String,
 
+    #[structopt(
+        long,
+        short = "mbs",
+        default_value = "262144",
+        env = "RUSTUS_MAX_BODY_SIZE"
+    )]
+    pub max_body_size: usize,
+
     /// Enabled hooks for http events
     #[structopt(long, default_value = "pre-create,post-finish", env = "RUSTUS_HOOKS")]
     pub enabled_hooks: String,
@@ -183,8 +192,6 @@ impl RustusConf {
     }
 
     pub fn dir_struct(&self) -> String {
-        let hostname = gethostname::gethostname();
-
         let now = chrono::Utc::now();
         let mut vars: HashMap<String, String> = HashMap::new();
         vars.insert("day".into(), now.day().to_string());
@@ -192,7 +199,9 @@ impl RustusConf {
         vars.insert("year".into(), now.year().to_string());
         vars.insert("hour".into(), now.hour().to_string());
         vars.insert("minute".into(), now.minute().to_string());
-        vars.insert("hostname".into(), hostname.to_string_lossy().into());
+        for (key, value) in env::vars() {
+            vars.insert(format!("env[{}]", key), value);
+        }
         strfmt::strfmt(self.storage_opts.dis_structure.as_str(), &vars)
             .unwrap_or_else(|_| "".into())
     }
diff --git a/src/main.rs b/src/main.rs
index 78f5fec..4870ec3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -64,6 +64,7 @@ pub fn create_server(
             .wrap(
                 middleware::DefaultHeaders::new()
                     .header("Tus-Resumable", "1.0.0")
+                    .header("Tus-Max-Size", app_conf.max_body_size.to_string())
                     .header("Tus-Version", "1.0.0"),
             )
             .wrap(middleware::Logger::new("\"%r\" \"-\" \"%s\" \"%a\" \"%D\""))
@@ -89,7 +90,7 @@ pub fn create_server(
     if let Some(workers_count) = workers {
         server = server.workers(workers_count);
     }
-    server = server.server_hostname("meme");
+
     Ok(server.run())
 }
 
diff --git a/src/protocol/core/mod.rs b/src/protocol/core/mod.rs
index 59a2f84..312ea32 100644
--- a/src/protocol/core/mod.rs
+++ b/src/protocol/core/mod.rs
@@ -1,3 +1,4 @@
+use actix_web::web::PayloadConfig;
 use actix_web::{guard, middleware, web};
 
 use crate::RustusConf;
@@ -26,6 +27,8 @@ pub fn add_extension(web_app: &mut web::ServiceConfig, app_conf: &RustusConf) {
             // PATCH /base/{file_id}
             // Main URL for uploading files.
             web::resource(app_conf.file_url().as_str())
+                // 10 MB chunks
+                .app_data(PayloadConfig::new(app_conf.max_body_size))
                 .name("core:write_bytes")
                 .guard(guard::Patch())
                 .to(routes::write_bytes),
diff --git a/src/protocol/core/routes.rs b/src/protocol/core/routes.rs
index 02da1a0..3620b79 100644
--- a/src/protocol/core/routes.rs
+++ b/src/protocol/core/routes.rs
@@ -48,7 +48,7 @@ pub async fn write_bytes(
     storage: web::Data<Box<dyn Storage + Send + Sync>>,
 ) -> actix_web::Result<HttpResponse> {
     if !check_header(&request, "Content-Type", "application/offset+octet-stream") {
-        return Ok(HttpResponseBuilder::new(StatusCode::UNSUPPORTED_MEDIA_TYPE).body(""));
+        return Ok(HttpResponse::UnsupportedMediaType().body(""));
     }
     let offset = parse_header(&request, "Upload-Offset");
 
diff --git a/src/protocol/creation/routes.rs b/src/protocol/creation/routes.rs
index 7b97ab2..2bd587d 100644
--- a/src/protocol/creation/routes.rs
+++ b/src/protocol/creation/routes.rs
@@ -84,6 +84,9 @@ pub async fn create_file(
         .extensions_vec()
         .contains(&ProtocolExtensions::CreationWithUpload);
     if with_upload && !bytes.is_empty() {
+        if !check_header(&request, "Content-Type", "application/offset+octet-stream") {
+            return Ok(HttpResponse::BadRequest().body(""));
+        }
         // Writing first bytes.
         upload_offset = storage
             .add_bytes(file_id.as_str(), 0, bytes.bytes())
diff --git a/src/storages/mod.rs b/src/storages/mod.rs
index 520e4ac..33bb9b0 100644
--- a/src/storages/mod.rs
+++ b/src/storages/mod.rs
@@ -3,7 +3,6 @@ use std::str::FromStr;
 
 use actix_files::NamedFile;
 use async_trait::async_trait;
-
 use derive_more::{Display, From};
 
 use crate::errors::RustusResult;
@@ -102,8 +101,8 @@ pub trait Storage {
     /// This method is used to generate unique file id, create file and store information about it.
     ///
     /// # Params
-    /// `file_size` - Size of a file. It may be None if size is deffered;
-    /// `metadata` - Optional file metainformation;
+    /// `file_size` - Size of a file. It may be None if size is deferred;
+    /// `metadata` - Optional file meta-information;
     async fn create_file(
         &self,
         file_size: Option<usize>,
-- 
GitLab