diff --git a/Cargo.lock b/Cargo.lock
index 68b610fcb9b923d6743d5f92de1f3728653e748a..3ba626f247e6d231df838d46c1a70c5d182c431e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -90,6 +90,24 @@ dependencies = [
  "syn",
 ]
 
+[[package]]
+name = "actix-multipart"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c9edfb0e7663d7fe18c8d5b668c9c1bcf79176b1dcc9d4da9592503209a6bfb0"
+dependencies = [
+ "actix-utils",
+ "actix-web",
+ "bytes",
+ "derive_more",
+ "futures-core",
+ "httparse",
+ "local-waker",
+ "log",
+ "mime",
+ "twoway",
+]
+
 [[package]]
 name = "actix-router"
 version = "0.5.0"
@@ -700,32 +718,90 @@ version = "1.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394"
 
+[[package]]
+name = "futures"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f21eda599937fba36daeb58a22e8f5cee2d14c4a17b5b7739c7c8e5e3b8230c"
+dependencies = [
+ "futures-channel",
+ "futures-core",
+ "futures-executor",
+ "futures-io",
+ "futures-sink",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-channel"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+]
+
 [[package]]
 name = "futures-core"
-version = "0.3.23"
+version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d2acedae88d38235936c3922476b10fced7b2b68136f5e3c03c2d5be348a1115"
+checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
+
+[[package]]
+name = "futures-executor"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ff63c23854bee61b6e9cd331d523909f238fc7636290b96826e9cfa5faa00ab"
+dependencies = [
+ "futures-core",
+ "futures-task",
+ "futures-util",
+]
+
+[[package]]
+name = "futures-io"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbf4d2a7a308fd4578637c0b17c7e1c7ba127b8f6ba00b29f717e9655d85eb68"
+
+[[package]]
+name = "futures-macro"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
 
 [[package]]
 name = "futures-sink"
-version = "0.3.23"
+version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ca0bae1fe9752cf7fd9b0064c674ae63f97b37bc714d745cbde0afb7ec4e6765"
+checksum = "21b20ba5a92e727ba30e72834706623d94ac93a725410b6a6b6fbc1b07f7ba56"
 
 [[package]]
 name = "futures-task"
-version = "0.3.23"
+version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "842fc63b931f4056a24d59de13fb1272134ce261816e063e634ad0c15cdc5306"
+checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
 
 [[package]]
 name = "futures-util"
-version = "0.3.23"
+version = "0.3.24"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0828a5471e340229c11c77ca80017937ce3c58cb788a17e5f1c2d5c485a9577"
+checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
 dependencies = [
+ "futures-channel",
  "futures-core",
+ "futures-io",
+ "futures-macro",
+ "futures-sink",
  "futures-task",
+ "memchr",
  "pin-project-lite",
  "pin-utils",
  "slab",
@@ -914,11 +990,13 @@ name = "krustacea"
 version = "0.1.0"
 dependencies = [
  "actix-files",
+ "actix-multipart",
  "actix-web",
  "actix-web-lab",
  "dirs",
  "env_logger",
  "fs_extra",
+ "futures",
  "regex",
  "rustls",
  "rustls-pemfile",
@@ -1641,12 +1719,28 @@ dependencies = [
  "once_cell",
 ]
 
+[[package]]
+name = "twoway"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c57ffb460d7c24cd6eda43694110189030a3d1dfe418416d9468fd1c1d290b47"
+dependencies = [
+ "memchr",
+ "unchecked-index",
+]
+
 [[package]]
 name = "typenum"
 version = "1.15.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
 
+[[package]]
+name = "unchecked-index"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeba86d422ce181a719445e51872fa30f1f7413b62becb52e95ec91aa262d85c"
+
 [[package]]
 name = "unicase"
 version = "2.6.0"
diff --git a/Cargo.toml b/Cargo.toml
index c73e84beea9fe3a1bbdc9f05d64bdd071dcdc683..1d59dbcb2a344c6c74fb5af601a84a469a16bcbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,3 +20,5 @@ structopt = "0.3"
 env_logger = "0.9"
 actix-web-lab = "0.17.0"
 actix-files = "0.6.2"
+actix-multipart = "0.4"
+futures = "0.3.24"
diff --git a/src/service/files.rs b/src/service/files.rs
index 4800bfdb6877c7765b7c6c20580946cffd7e56d8..b84f0247d13e8d4521af8f1c416eadb8073b0f54 100644
--- a/src/service/files.rs
+++ b/src/service/files.rs
@@ -1,11 +1,138 @@
-use crate::static_files::StaticFilesManager;
+use crate::static_files::upload::*;
+use crate::website::WebSite;
 use actix_files::NamedFile;
-use actix_web::{get, web, Responder};
+use actix_multipart::Multipart;
+use actix_web::{
+    delete, get, post, web,
+    web::{Data, Path},
+    HttpResponse, Responder,
+};
+use futures::StreamExt;
+use std::{
+    fs::{remove_file, File},
+    io::Write,
+};
 
 #[get("/favicon.ico")]
-pub async fn favicon(
-    static_files_manager: web::Data<std::sync::Mutex<StaticFilesManager>>,
-) -> impl Responder {
-    let static_files_manager = static_files_manager.lock().unwrap();
+pub async fn favicon(website: web::Data<std::sync::Mutex<WebSite>>) -> impl Responder {
+    let static_files_manager = &website.lock().unwrap().static_files_manager;
     NamedFile::open(static_files_manager.dir.join("default").join("favicon.ico"))
 }
+
+fn upload_data_from_multipart_field(
+    field: &actix_multipart::Field,
+) -> Result<UploadFileData, String> {
+    match field.content_disposition().get_filename() {
+        Some(fname) => match file_ext(&fname.to_string()) {
+            Ok(ext) => Ok(UploadFileData {
+                up_type: upload_type_from_file_ext(&ext),
+                filename: fname.to_owned(),
+            }),
+            Err(msg) => return Err(msg),
+        },
+        None => Err("Couldn't retrieve file extension".to_string()),
+    }
+}
+
+async fn write_uploaded_file(
+    website: &WebSite,
+    field: &mut actix_multipart::Field,
+    filename: &String,
+    upload_type: UploadFileType,
+) -> Result<String, String> {
+    let root = &website.static_files_manager.dir;
+    let sub_dir = dirname_from_type(&upload_type);
+    let filepath = root.join(sub_dir).join(&filename);
+
+    match File::create(&filepath) {
+        Err(e) => Err(format!("Error creating file {:?} : {:?}", filepath, e)),
+        Ok(mut f) => {
+            // Field in turn is stream of *Bytes* object
+            while let Some(chunk) = field.next().await {
+                match chunk {
+                    Ok(chunk) => {
+                        if f.write_all(&chunk).is_err() {
+                            remove_file(&filepath).unwrap();
+                            return Err("Error writing chunk".to_string());
+                        }
+                    }
+                    Err(e) => {
+                        return Err(format!("Error writing file {} : {:?}", filename, e));
+                    }
+                }
+            }
+
+            Ok(filepath.into_os_string().into_string().unwrap())
+        }
+    }
+}
+
+#[post("/post-files")]
+pub async fn post_files(
+    website: Data<std::sync::Mutex<WebSite>>,
+    mut payload: Multipart,
+) -> impl Responder {
+    let mut uploaded_filepathes = Vec::new();
+    let mut website = website.lock().unwrap();
+
+    while let Some(item) = payload.next().await {
+        match item {
+            Ok(mut field) => {
+                let up_data = upload_data_from_multipart_field(&field);
+
+                if let Err(msg) = up_data {
+                    return HttpResponse::InternalServerError().body(msg);
+                }
+
+                let up_data = up_data.unwrap();
+
+                match write_uploaded_file(&website, &mut field, &up_data.filename, up_data.up_type)
+                    .await
+                {
+                    Err(msg) => return HttpResponse::InternalServerError().body(msg),
+                    Ok(filepath) => uploaded_filepathes.extend(
+                        website
+                            .static_files_manager
+                            .push_path(std::path::Path::new(&filepath)),
+                    ),
+                }
+            }
+            Err(e) => {
+                return HttpResponse::InternalServerError().body(format!("FIELD ERR {:?}", e))
+            }
+        }
+    }
+
+    HttpResponse::Ok().json(uploaded_filepathes)
+}
+
+#[get("/static-files-index")]
+async fn get_static_files_index(website: Data<std::sync::Mutex<WebSite>>) -> impl Responder {
+    HttpResponse::Ok().json(
+        website
+            .lock()
+            .expect("Couldn't lock website")
+            .static_files_manager
+            .get_index(),
+    )
+}
+
+#[delete("/delete-file/{category}/{filename}")]
+async fn delete_static_file(
+    website: Data<std::sync::Mutex<WebSite>>,
+    fileinfo: Path<(String, String)>,
+) -> impl Responder {
+    let mut website = website.lock().unwrap();
+    let (cat, fname) = fileinfo.into_inner();
+    let fpath = std::path::PathBuf::from(cat).join(fname);
+
+    match remove_file(website.static_files_manager.dir.join(&fpath)) {
+        Ok(_) => {
+            website
+                .static_files_manager
+                .remove_path(fpath.to_string_lossy().into());
+            HttpResponse::Accepted().body("File was deleted")
+        }
+        Err(e) => HttpResponse::InternalServerError().body(format!("Error deleting file {:?}", e)),
+    }
+}
diff --git a/src/static_files/mod.rs b/src/static_files/mod.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b9b5f28e561a28ceb989cdb05ce7395f4535b09a
--- /dev/null
+++ b/src/static_files/mod.rs
@@ -0,0 +1,3 @@
+mod static_files;
+pub mod upload;
+pub use static_files::*;
diff --git a/src/static_files.rs b/src/static_files/static_files.rs
similarity index 85%
rename from src/static_files.rs
rename to src/static_files/static_files.rs
index 0f07dddf6e3eac5b3cfba032bde61c426109f5b2..c4c3bf94ce9dcb4e7199c852b39fadd35a67d129 100644
--- a/src/static_files.rs
+++ b/src/static_files/static_files.rs
@@ -101,10 +101,10 @@ impl StaticFilesManager {
         }
     }
 
-    fn push_path(&mut self, path: &Path) -> Vec<PathBuf> {
+    pub fn push_path(&mut self, path: &Path) -> Vec<PathBuf> {
         if self.validate_path(path) {
             self.index
-                .push(format!("/{}", path.to_str().unwrap().to_owned()));
+                .push(self.clean_relative_path(path).to_str().unwrap().to_owned());
             vec![path.to_path_buf()]
         } else {
             println!(
@@ -129,6 +129,22 @@ impl StaticFilesManager {
         self.rec_read_dir(&self.dir.clone(), &self.dir.clone());
         self.clone()
     }
+
+    pub fn remove_path(&mut self, strpath: String) {
+        println!("REMOVE {}", strpath);
+        println!("current Index {:#?}", self.index);
+        self.index = self
+            .index
+            .iter()
+            .filter(|url| !strpath.eq(*url))
+            .map(|s| s.to_owned())
+            .collect();
+        println!("Updated Index {:#?}", self.index);
+    }
+
+    pub fn get_index(&self) -> Vec<String> {
+        self.index.clone()
+    }
 }
 
 #[cfg(test)]
@@ -173,7 +189,7 @@ mod test_static_files_manager {
         manager = manager.build();
 
         assert!(
-            manager.index.contains(&"/docs/testing.txt".to_string()),
+            manager.index.contains(&"docs/testing.txt".to_string()),
             "Index doesn't contain path /docs/testing.txt\n{:?}",
             remove_test_dir(&test_dir)
         );
@@ -182,7 +198,7 @@ mod test_static_files_manager {
     }
 
     #[test]
-    fn test_push_path() {
+    fn test_pushd_andremove_path() {
         let test_dir = create_test_dir();
         let mut manager = StaticFilesManager::testing_new(&test_dir).unwrap().build();
         let file_pth = test_dir.join("static").join("docs").join("testing.txt");
@@ -198,11 +214,19 @@ mod test_static_files_manager {
         );
 
         assert!(
-            manager.index.contains(&"/docs/testing.txt".to_string()),
+            manager.index.contains(&"docs/testing.txt".to_string()),
             "Index doesn't contain path /docs/testing.txt\n{:?}",
             remove_test_dir(&test_dir)
         );
 
+        manager.remove_path("docs/testing.txt".to_string());
+
+        assert!(
+            !manager.index.contains(&"docs/testing.txt".to_string()),
+            "Path docs/testing.txt should have been removed\n{:?}",
+            remove_test_dir(&test_dir)
+        );
+
         remove_test_dir(&test_dir);
     }
 
@@ -221,9 +245,7 @@ mod test_static_files_manager {
         );
 
         assert!(
-            !manager
-                .index
-                .contains(&"/images/unexisting.png".to_string()),
+            !manager.index.contains(&"images/unexisting.png".to_string()),
             "Index shouldn't container unexisting path\n{:?}",
             remove_test_dir(&test_dir)
         );
diff --git a/src/static_files/upload.rs b/src/static_files/upload.rs
new file mode 100644
index 0000000000000000000000000000000000000000..b532b3b438b85c9e04b266604139971520da6aa0
--- /dev/null
+++ b/src/static_files/upload.rs
@@ -0,0 +1,48 @@
+#[derive(Debug, PartialEq)]
+pub enum UploadFileType {
+    Image,
+    Sound,
+    Video,
+    Doc,
+    Code,
+}
+
+pub struct UploadFileData {
+    pub up_type: UploadFileType,
+    pub filename: String,
+}
+
+pub fn dirname_from_type(upload_type: &UploadFileType) -> String {
+    match upload_type {
+        UploadFileType::Image => String::from("images"),
+        UploadFileType::Sound => String::from("sounds"),
+        UploadFileType::Video => String::from("videos"),
+        UploadFileType::Doc => String::from("docs"),
+        UploadFileType::Code => String::from("source_code"),
+    }
+}
+
+pub fn upload_type_from_file_ext(ext: &String) -> UploadFileType {
+    match &ext[..] {
+        "webp" | "jpg" | "png" | "jpeg" | "bmp" | "gif" => UploadFileType::Image,
+        "mp3" | "ogg" | "wav" | "opus" => UploadFileType::Sound,
+        "mp4" | "webm" | "ogv" => UploadFileType::Video,
+        "js" | "css" | "html" => UploadFileType::Code,
+        _ => UploadFileType::Doc,
+    }
+}
+
+pub fn file_ext(file_name: &String) -> Result<String, String> {
+    let parts = file_name.split(".").collect::<Vec<&str>>();
+
+    let err_msg = format!("Couldn't get extension from filename : {}", file_name);
+
+    if parts.len() < 2 {
+        return Err(err_msg);
+    }
+
+    match parts.last() {
+        Some(ext) => Ok(ext.to_string()),
+        None => Err(err_msg),
+    }
+}