diff --git a/src/main.rs b/src/main.rs
index 80a3b6123f817a7e91ce3aff296596f445c6208a..b05a51bf48a5110c010348f297fb62b0cc0e5214 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,7 @@ use log::LevelFilter;
 use crate::errors::RustusResult;
 use crate::info_storages::InfoStorage;
 use crate::notifiers::models::notification_manager::NotificationManager;
+use crate::state::State;
 use config::RustusConf;
 
 use crate::storages::Storage;
@@ -23,6 +24,7 @@ mod info_storages;
 mod notifiers;
 mod protocol;
 mod routes;
+mod state;
 mod storages;
 mod utils;
 
@@ -64,35 +66,22 @@ fn greeting(app_conf: &RustusConf) {
 /// This function may throw an error
 /// if the server can't be bound to the
 /// given address.
-pub fn create_server(
-    storage: Box<dyn Storage + Send + Sync>,
-    info_storage: Box<dyn InfoStorage + Send + Sync>,
-    app_conf: RustusConf,
-    notification_manager: NotificationManager,
-) -> Result<Server, std::io::Error> {
-    let host = app_conf.host.clone();
-    let port = app_conf.port;
-    let workers = app_conf.workers;
-    let app_conf_data = web::Data::new(app_conf.clone());
-    let info_storage_data: web::Data<Box<dyn InfoStorage + Send + Sync>> =
-        web::Data::from(Arc::new(info_storage));
-    let storage_data: web::Data<Box<dyn Storage + Send + Sync>> =
-        web::Data::from(Arc::new(storage));
-    let manager_data: web::Data<Box<NotificationManager>> =
-        web::Data::from(Arc::new(Box::new(notification_manager)));
+pub fn create_server(state: State) -> Result<Server, std::io::Error> {
+    let host = state.config.host.clone();
+    let port = state.config.port;
+    let config = state.config.clone();
+    let workers = state.config.workers;
+    let state_data: web::Data<State> = web::Data::from(Arc::new(state));
     let mut server = HttpServer::new(move || {
         App::new()
-            .app_data(app_conf_data.clone())
-            .app_data(storage_data.clone())
-            .app_data(manager_data.clone())
-            .app_data(info_storage_data.clone())
+            .app_data(state_data.clone())
             // Adds all routes.
-            .configure(protocol::setup(app_conf.clone()))
+            .configure(protocol::setup(config.clone()))
             // Main middleware that appends TUS headers.
             .wrap(
                 middleware::DefaultHeaders::new()
                     .add(("Tus-Resumable", "1.0.0"))
-                    .add(("Tus-Max-Size", app_conf.max_body_size.to_string()))
+                    .add(("Tus-Max-Size", config.max_body_size.to_string()))
                     .add(("Tus-Version", "1.0.0")),
             )
             .wrap(middleware::Logger::new("\"%r\" \"-\" \"%s\" \"%a\" \"%D\""))
@@ -176,6 +165,11 @@ async fn main() -> std::io::Result<()> {
     let notification_manager = NotificationManager::new(&app_conf).await?;
 
     // Creating actual server and running it.
-    let server = create_server(storage, info_storage, app_conf, notification_manager)?;
+    let server = create_server(State::new(
+        app_conf.clone(),
+        storage,
+        info_storage,
+        notification_manager,
+    ))?;
     server.await
 }
diff --git a/src/protocol/core/routes.rs b/src/protocol/core/routes.rs
index f9f282db5896bcede50652a7e037a8b785bffc73..72fb39ecaaa06b966b2d31dbb25af8986655819b 100644
--- a/src/protocol/core/routes.rs
+++ b/src/protocol/core/routes.rs
@@ -4,7 +4,7 @@ use crate::errors::RustusError;
 use crate::notifiers::Hook;
 use crate::protocol::extensions::Extensions;
 use crate::utils::headers::{check_header, parse_header};
-use crate::{InfoStorage, NotificationManager, RustusConf, Storage};
+use crate::{RustusConf, State};
 
 #[allow(clippy::needless_pass_by_value)]
 pub fn server_info(app_conf: web::Data<RustusConf>) -> HttpResponse {
@@ -20,8 +20,7 @@ pub fn server_info(app_conf: web::Data<RustusConf>) -> HttpResponse {
 }
 
 pub async fn get_file_info(
-    info_storage: web::Data<Box<dyn InfoStorage + Send + Sync>>,
-    storage: web::Data<Box<dyn Storage + Send + Sync>>,
+    state: web::Data<State>,
     request: HttpRequest,
 ) -> actix_web::Result<HttpResponse> {
     // Getting file id from URL.
@@ -31,8 +30,8 @@ pub async fn get_file_info(
     let file_id = request.match_info().get("file_id").unwrap();
 
     // Getting file info from info_storage.
-    let file_info = info_storage.get_info(file_id).await?;
-    if file_info.storage != storage.to_string() {
+    let file_info = state.info_storage.get_info(file_id).await?;
+    if file_info.storage != state.data_storage.to_string() {
         return Ok(HttpResponse::NotFound().body(""));
     }
     let mut builder = HttpResponse::Ok();
@@ -54,10 +53,7 @@ pub async fn get_file_info(
 pub async fn write_bytes(
     request: HttpRequest,
     bytes: Bytes,
-    storage: web::Data<Box<dyn Storage + Send + Sync>>,
-    info_storage: web::Data<Box<dyn InfoStorage + Send + Sync>>,
-    notification_manager: web::Data<Box<NotificationManager>>,
-    app_conf: web::Data<RustusConf>,
+    state: web::Data<State>,
 ) -> actix_web::Result<HttpResponse> {
     // Checking if request has required headers.
     if !check_header(&request, "Content-Type", "application/offset+octet-stream") {
@@ -76,7 +72,8 @@ pub async fn write_bytes(
 
     // New upload length.
     // Parses header `Upload-Length` only if the creation-defer-length extension is enabled.
-    let updated_len = if app_conf
+    let updated_len = if state
+        .config
         .extensions_vec()
         .contains(&Extensions::CreationDeferLength)
     {
@@ -87,10 +84,10 @@ pub async fn write_bytes(
 
     let file_id = request.match_info().get("file_id").unwrap();
     // Getting file info.
-    let mut file_info = info_storage.get_info(file_id).await?;
+    let mut file_info = state.info_storage.get_info(file_id).await?;
 
     // Checking if file was stored in the same storage.
-    if file_info.storage != storage.to_string() {
+    if file_info.storage != state.data_storage.to_string() {
         return Ok(HttpResponse::NotFound().body(""));
     }
     // Checking if offset from request is the same as the real offset.
@@ -125,24 +122,29 @@ pub async fn write_bytes(
     }
 
     // Appending bytes to file.
-    storage.add_bytes(&file_info, bytes.as_ref()).await?;
+    state
+        .data_storage
+        .add_bytes(&file_info, bytes.as_ref())
+        .await?;
     // Updating offset.
     file_info.offset += bytes.len();
     // Saving info to info storage.
-    info_storage.set_info(&file_info, false).await?;
+    state.info_storage.set_info(&file_info, false).await?;
 
     let mut hook = Hook::PostReceive;
     if file_info.length == Some(file_info.offset) {
         hook = Hook::PostFinish;
     }
-    if app_conf.hook_is_active(hook) {
-        let message = app_conf
+    if state.config.hook_is_active(hook) {
+        let message = state
+            .config
             .notification_opts
             .hooks_format
             .format(&request, &file_info)?;
         let headers = request.headers().clone();
         tokio::spawn(async move {
-            notification_manager
+            state
+                .notification_manager
                 .send_message(message, hook, &headers)
                 .await
         });
diff --git a/src/protocol/creation/routes.rs b/src/protocol/creation/routes.rs
index 61bbdca8f54e698b888d1683da499d7c82075176..0e8a30a40ec0f8590c0ca81536a641cfdb4d844c 100644
--- a/src/protocol/creation/routes.rs
+++ b/src/protocol/creation/routes.rs
@@ -7,7 +7,7 @@ use crate::info_storages::FileInfo;
 use crate::notifiers::Hook;
 use crate::protocol::extensions::Extensions;
 use crate::utils::headers::{check_header, parse_header};
-use crate::{InfoStorage, NotificationManager, RustusConf, Storage};
+use crate::State;
 
 /// Get metadata info from request.
 ///
@@ -58,10 +58,7 @@ fn get_metadata(request: &HttpRequest) -> Option<HashMap<String, String>> {
 /// you can upload first bytes if creation-with-upload
 /// extension is enabled.
 pub async fn create_file(
-    storage: web::Data<Box<dyn Storage + Send + Sync>>,
-    info_storage: web::Data<Box<dyn InfoStorage + Send + Sync>>,
-    notification_manager: web::Data<Box<NotificationManager>>,
-    app_conf: web::Data<RustusConf>,
+    state: web::Data<State>,
     request: HttpRequest,
     bytes: Bytes,
 ) -> actix_web::Result<HttpResponse> {
@@ -71,7 +68,8 @@ pub async fn create_file(
     let defer_size = check_header(&request, "Upload-Defer-Length", "1");
 
     // Indicator that creation-defer-length is enabled.
-    let defer_ext = app_conf
+    let defer_ext = state
+        .config
         .extensions_vec()
         .contains(&Extensions::CreationDeferLength);
 
@@ -89,29 +87,32 @@ pub async fn create_file(
         file_id.as_str(),
         length,
         None,
-        storage.to_string(),
+        state.data_storage.to_string(),
         meta.clone(),
     );
 
-    if app_conf.hook_is_active(Hook::PreCreate) {
-        let message = app_conf
+    if state.config.hook_is_active(Hook::PreCreate) {
+        let message = state
+            .config
             .notification_opts
             .hooks_format
             .format(&request, &file_info)?;
         let headers = request.headers();
-        notification_manager
+        state
+            .notification_manager
             .send_message(message, Hook::PreCreate, headers)
             .await?;
     }
 
     // Create file and get the it's path.
-    file_info.path = Some(storage.create_file(&file_info).await?);
+    file_info.path = Some(state.data_storage.create_file(&file_info).await?);
 
     // Create upload URL for this file.
     let upload_url = request.url_for("core:write_bytes", &[file_info.id.clone()])?;
 
     // Checking if creation-with-upload extension is enabled.
-    let with_upload = app_conf
+    let with_upload = state
+        .config
         .extensions_vec()
         .contains(&Extensions::CreationWithUpload);
     if with_upload && !bytes.is_empty() {
@@ -119,14 +120,18 @@ pub async fn create_file(
             return Ok(HttpResponse::BadRequest().body(""));
         }
         // Writing first bytes.
-        storage.add_bytes(&file_info, bytes.as_ref()).await?;
+        state
+            .data_storage
+            .add_bytes(&file_info, bytes.as_ref())
+            .await?;
         file_info.offset += bytes.len();
     }
 
-    info_storage.set_info(&file_info, true).await?;
+    state.info_storage.set_info(&file_info, true).await?;
 
-    if app_conf.hook_is_active(Hook::PostCreate) {
-        let message = app_conf
+    if state.config.hook_is_active(Hook::PostCreate) {
+        let message = state
+            .config
             .notification_opts
             .hooks_format
             .format(&request, &file_info)?;
@@ -134,7 +139,8 @@ pub async fn create_file(
         // Adding send_message task to tokio reactor.
         // Thin function would be executed in background.
         tokio::spawn(async move {
-            notification_manager
+            state
+                .notification_manager
                 .send_message(message, Hook::PostCreate, &headers)
                 .await
         });
diff --git a/src/protocol/getting/routes.rs b/src/protocol/getting/routes.rs
index 44186c81c6bbb64727aaad6a82444edeb550c741..97af31a183dba4a927d2b064c5abb9098d75aad8 100644
--- a/src/protocol/getting/routes.rs
+++ b/src/protocol/getting/routes.rs
@@ -1,23 +1,19 @@
 use actix_web::{web, HttpRequest, Responder};
 
 use crate::errors::RustusError;
-use crate::{InfoStorage, Storage};
+use crate::State;
 
 /// Retrieve actual file.
 ///
 /// This method allows you to download files directly from storage.
-pub async fn get_file(
-    request: HttpRequest,
-    storage: web::Data<Box<dyn Storage + Send + Sync>>,
-    info_storage: web::Data<Box<dyn InfoStorage + Send + Sync>>,
-) -> impl Responder {
+pub async fn get_file(request: HttpRequest, state: web::Data<State>) -> impl Responder {
     let file_id_opt = request.match_info().get("file_id").map(String::from);
     if let Some(file_id) = file_id_opt {
-        let file_info = info_storage.get_info(file_id.as_str()).await?;
-        if file_info.storage != storage.to_string() {
+        let file_info = state.info_storage.get_info(file_id.as_str()).await?;
+        if file_info.storage != state.data_storage.to_string() {
             return Err(RustusError::FileNotFound);
         }
-        storage.get_contents(&file_info).await
+        state.data_storage.get_contents(&file_info).await
     } else {
         Err(RustusError::FileNotFound)
     }
diff --git a/src/protocol/termination/routes.rs b/src/protocol/termination/routes.rs
index 16d809406a955c404a8ae0d19383b5b1fb171114..dd302e8d05012d4bfb629473dc21ba0fd5fb8424 100644
--- a/src/protocol/termination/routes.rs
+++ b/src/protocol/termination/routes.rs
@@ -2,35 +2,34 @@ use actix_web::{web, HttpRequest, HttpResponse};
 
 use crate::errors::RustusResult;
 use crate::notifiers::Hook;
-use crate::{InfoStorage, NotificationManager, RustusConf, Storage};
+use crate::State;
 
 /// Terminate uploading.
 ///
 /// This method will remove all data by id.
 /// It removes info and actual data.
 pub async fn terminate(
-    storage: web::Data<Box<dyn Storage + Send + Sync>>,
-    info_storage: web::Data<Box<dyn InfoStorage + Send + Sync>>,
     request: HttpRequest,
-    notification_manager: web::Data<Box<NotificationManager>>,
-    app_conf: web::Data<RustusConf>,
+    state: web::Data<State>,
 ) -> RustusResult<HttpResponse> {
     let file_id_opt = request.match_info().get("file_id").map(String::from);
     if let Some(file_id) = file_id_opt {
-        let file_info = info_storage.get_info(file_id.as_str()).await?;
-        if file_info.storage != storage.to_string() {
+        let file_info = state.info_storage.get_info(file_id.as_str()).await?;
+        if file_info.storage != state.data_storage.to_string() {
             return Ok(HttpResponse::NotFound().body(""));
         }
-        info_storage.remove_info(file_id.as_str()).await?;
-        storage.remove_file(&file_info).await?;
-        if app_conf.hook_is_active(Hook::PostTerminate) {
-            let message = app_conf
+        state.info_storage.remove_info(file_id.as_str()).await?;
+        state.data_storage.remove_file(&file_info).await?;
+        if state.config.hook_is_active(Hook::PostTerminate) {
+            let message = state
+                .config
                 .notification_opts
                 .hooks_format
                 .format(&request, &file_info)?;
             let headers = request.headers().clone();
             tokio::spawn(async move {
-                notification_manager
+                state
+                    .notification_manager
                     .send_message(message, Hook::PostTerminate, &headers)
                     .await
             });
diff --git a/src/state.rs b/src/state.rs
new file mode 100644
index 0000000000000000000000000000000000000000..16bc4f24ab2bab10450226a85b8e6c2d8c7faef8
--- /dev/null
+++ b/src/state.rs
@@ -0,0 +1,24 @@
+use crate::{InfoStorage, NotificationManager, RustusConf, Storage};
+
+pub struct State {
+    pub config: RustusConf,
+    pub data_storage: Box<dyn Storage + Send + Sync>,
+    pub info_storage: Box<dyn InfoStorage + Send + Sync>,
+    pub notification_manager: NotificationManager,
+}
+
+impl State {
+    pub fn new(
+        config: RustusConf,
+        data_storage: Box<dyn Storage + Send + Sync>,
+        info_storage: Box<dyn InfoStorage + Send + Sync>,
+        notification_manager: NotificationManager,
+    ) -> Self {
+        Self {
+            config,
+            data_storage,
+            info_storage,
+            notification_manager,
+        }
+    }
+}