aboutsummaryrefslogtreecommitdiffstats
path: root/teleterm/src/web/disk_session.rs
blob: 423bcd092acab62a481c63708de4ca885544f8b7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
use crate::prelude::*;

use std::io::Write as _;

#[derive(Clone)]
pub struct DiskSession;

impl DiskSession {
    fn file_for_id(
        &self,
        identifier: &gotham::middleware::session::SessionIdentifier,
        should_exist: bool,
    ) -> Option<std::path::PathBuf> {
        let name = format!("web-{}", identifier.value);
        crate::dirs::Dirs::new().data_file(&name, should_exist)
    }
}

impl gotham::middleware::session::NewBackend for DiskSession {
    type Instance = Self;

    fn new_backend(&self) -> std::io::Result<Self::Instance> {
        Ok(Self)
    }
}

impl gotham::middleware::session::Backend for DiskSession {
    fn persist_session(
        &self,
        identifier: gotham::middleware::session::SessionIdentifier,
        content: &[u8],
    ) -> std::result::Result<(), gotham::middleware::session::SessionError>
    {
        let filename = self.file_for_id(&identifier, false).unwrap();
        let mut file = std::fs::File::create(filename).map_err(|e| {
            gotham::middleware::session::SessionError::Backend(format!(
                "{}",
                e
            ))
        })?;
        file.write_all(content).map_err(|e| {
            gotham::middleware::session::SessionError::Backend(format!(
                "{}",
                e
            ))
        })?;
        file.sync_all().map_err(|e| {
            gotham::middleware::session::SessionError::Backend(format!(
                "{}",
                e
            ))
        })?;
        Ok(())
    }

    fn read_session(
        &self,
        identifier: gotham::middleware::session::SessionIdentifier,
    ) -> Box<
        dyn futures::Future<
                Item = Option<Vec<u8>>,
                Error = gotham::middleware::session::SessionError,
            > + Send,
    > {
        if let Some(filename) = self.file_for_id(&identifier, true) {
            Box::new(
                tokio::fs::File::open(filename)
                    .and_then(|file| {
                        let buf = vec![];
                        tokio::io::read_to_end(file, buf)
                    })
                    .map(|(_, v)| Some(v))
                    .map_err(|e| {
                        gotham::middleware::session::SessionError::Backend(
                            format!("{}", e),
                        )
                    }),
            )
        } else {
            Box::new(futures::future::ok(None))
        }
    }

    fn drop_session(
        &self,
        identifier: gotham::middleware::session::SessionIdentifier,
    ) -> std::result::Result<(), gotham::middleware::session::SessionError>
    {
        if let Some(filename) = self.file_for_id(&identifier, true) {
            std::fs::remove_file(filename).map_err(|e| {
                gotham::middleware::session::SessionError::Backend(format!(
                    "{}",
                    e
                ))
            })?;
        }
        Ok(())
    }
}