| 75 | } |
| 76 | |
| 77 | fn do_exec(exec_id: &str) -> Result<Vec<u8>, String> { |
| 78 | debug!("dispatching exec operation {}", exec_id); |
| 79 | |
| 80 | let mut stream = UnixStream::connect(DOCKER_SOCKET) |
| 81 | .map_err(|e| format!("could not connect to {}: {}", DOCKER_SOCKET, e))?; |
| 82 | |
| 83 | stream |
| 84 | .set_read_timeout(Some(Duration::from_secs(15))) |
| 85 | .map_err(|e| format!("could not set read timeout for {}: {}", DOCKER_SOCKET, e))?; |
| 86 | |
| 87 | stream |
| 88 | .set_write_timeout(Some(Duration::from_secs(15))) |
| 89 | .map_err(|e| format!("could not set write timeout for {}: {}", DOCKER_SOCKET, e))?; |
| 90 | |
| 91 | let content = "{ |
| 92 | \"Detach\": false, |
| 93 | \"Tty\": false |
| 94 | }"; |
| 95 | let request = format!("POST /exec/{}/start HTTP/1.0\r\n", exec_id) |
| 96 | + "Content-Type: application/json\r\n" |
| 97 | + &format!("Content-Length: {}\r\n", content.len()) |
| 98 | + &format!("\r\n{}", content); |
| 99 | |
| 100 | let response = do_request(&request, &mut stream)?; |
| 101 | |
| 102 | debug!("cmd response = {:?}", String::from_utf8_lossy(&response)); |
| 103 | |
| 104 | // split headers and response body |
| 105 | let pattern = "\r\n\r\n".as_bytes(); |
| 106 | let idx = response |
| 107 | .windows(pattern.len()) |
| 108 | .position(|window| window == pattern) |
| 109 | .unwrap() |
| 110 | + pattern.len(); |
| 111 | |
| 112 | Ok(response[idx..].to_vec()) |
| 113 | } |
| 114 | |
| 115 | pub fn exec(container_id: &str, command: &str) -> Result<Vec<u8>, String> { |
| 116 | // HACK: since wget and curl don't have any timeout by default, force it. |