summaryrefslogtreecommitdiffstats
path: root/src/tty.rs
blob: f4b911feb5a3b78e941318c3f5eab1f3d49f7815 (plain)
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
use std::io::Read;
use std::io::Cursor;
use byteorder::{BigEndian, ReadBytesExt};

pub struct Tty {
    pub stdout: String,
    pub stderr: String,
}

// https://docs.docker.com/engine/api/v1.26/#operation/ContainerAttach
impl Tty {
    pub fn new(mut stream: Box<Read>) -> Tty {
        let mut stdout: Vec<u8> = vec![];
        let mut stderr: Vec<u8> = vec![];
        loop {
            // 8 byte header [ STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4 ]
            let mut header = [0; 8];
            match stream.read_exact(&mut header) {
                Ok(_) => {
                    let payload_size: Vec<u8> = header[4..8].to_vec();
                    let mut buffer =
                        vec![
                            0;
                            Cursor::new(&payload_size).read_u32::<BigEndian>().unwrap() as usize
                        ];
                    match stream.read_exact(&mut buffer) {
                        Ok(_) => {
                            match header[0] {
                                // stdin, unhandled
                                0 => break,
                                // stdout
                                1 => stdout.append(&mut buffer),
                                // stderr
                                2 => stderr.append(&mut buffer),
                                //unhandled
                                _ => break,
                            }
                        }
                        Err(_) => break,
                    };
                }
                Err(_) => break,
            }
        }
        Tty {
            stdout: String::from_utf8_lossy(&stdout).to_string(),
            stderr: String::from_utf8_lossy(&stderr).to_string(),
        }
    }
}