|
1 | 1 | extern crate byteorder;
|
2 |
| -extern crate nix; |
3 | 2 | #[cfg(windows)]
|
4 | 3 | extern crate named_pipe;
|
| 4 | +extern crate nix; |
5 | 5 |
|
| 6 | +use byteorder::{ByteOrder, NativeEndian, WriteBytesExt}; |
6 | 7 | use std::convert::TryInto;
|
7 |
| -use std::io::{self, Read, Write}; |
| 8 | +use std::io::{stdin, stdout, Error, ErrorKind, Read, Result, Write}; |
8 | 9 | use std::thread;
|
9 |
| -use byteorder::{ByteOrder, NativeEndian, WriteBytesExt}; |
10 | 10 |
|
11 | 11 | mod proxy_socket;
|
12 | 12 |
|
13 | 13 | use proxy_socket::ProxySocket;
|
14 | 14 |
|
15 |
| -const BUFFER_SIZE: usize = 1024 ^ 2; // 1024 ^ 2 is the maximum |
| 15 | +const BUFFER_SIZE: usize = 1024 ^ 2; // 1024 ^ 2 is the maximum |
16 | 16 |
|
17 | 17 | fn valid_length(length: usize) -> bool {
|
18 | 18 | length > 0 && length <= BUFFER_SIZE
|
19 | 19 | }
|
20 | 20 |
|
21 |
| -fn read_header() -> usize { |
22 |
| - let stdin = io::stdin(); |
| 21 | +// Read a header (message size) from stdin (e.g.: from the browser). |
| 22 | +fn read_header() -> Result<usize> { |
| 23 | + let stdin = stdin(); |
23 | 24 | let mut buf = vec![0; 4];
|
24 | 25 | let mut handle = stdin.lock();
|
25 | 26 |
|
26 |
| - handle.read_exact(&mut buf).unwrap(); |
27 |
| - NativeEndian::read_u32(&buf).try_into().unwrap() |
| 27 | + handle.read_exact(&mut buf)?; |
| 28 | + |
| 29 | + NativeEndian::read_u32(&buf) |
| 30 | + .try_into() |
| 31 | + .map_err(|err| Error::new(ErrorKind::InvalidData, err)) |
28 | 32 | }
|
29 | 33 |
|
30 |
| -fn read_body<T: Read + Write>(length: usize, socket: &mut ProxySocket<T>) { |
| 34 | +// Handle a whole request/response cycle |
| 35 | +// |
| 36 | +// Read a message body from stdin (e.g.: from the browser), and echo it back to the browser's |
| 37 | +// socket. Then await a response from the socket and relay that back to the browser. |
| 38 | +fn read_body<T: Read + Write>(length: usize, socket: &mut ProxySocket<T>) -> Result<()> { |
31 | 39 | let mut buffer = vec![0; length];
|
32 |
| - let stdin = io::stdin(); |
| 40 | + let stdin = stdin(); |
33 | 41 | let mut handle = stdin.lock();
|
34 | 42 |
|
35 |
| - if handle.read_exact(&mut buffer).is_ok() && valid_length(length) { |
36 |
| - socket.write_all(&buffer).unwrap(); |
37 |
| - socket.flush().unwrap(); |
38 |
| - read_response(socket); |
| 43 | + handle.read_exact(&mut buffer)?; |
| 44 | + |
| 45 | + if valid_length(length) { |
| 46 | + socket.write_all(&buffer)?; |
| 47 | + socket.flush()?; |
| 48 | + read_response(socket)?; |
39 | 49 | }
|
| 50 | + |
| 51 | + Ok(()) |
40 | 52 | }
|
41 | 53 |
|
42 |
| -fn read_response<T: Read>(socket: &mut ProxySocket<T>) { |
| 54 | +// Read a response (from KP's socket) and echo it back to the browser. |
| 55 | +fn read_response<T: Read>(socket: &mut ProxySocket<T>) -> Result<()>{ |
43 | 56 | let mut buf = vec![0; BUFFER_SIZE];
|
44 | 57 | if let Ok(len) = socket.read(&mut buf) {
|
45 |
| - write_response(&buf[0..len]); |
| 58 | + write_response(&buf[0..len])?; |
46 | 59 | }
|
| 60 | + |
| 61 | + Ok(()) |
47 | 62 | }
|
48 | 63 |
|
49 |
| -fn write_response(buf: &[u8]) { |
50 |
| - let stdout = io::stdout(); |
| 64 | +// Write a response to stdout (e.g.: to the browser). |
| 65 | +fn write_response(buf: &[u8]) -> Result<()> { |
| 66 | + let stdout = stdout(); |
51 | 67 | let mut out = stdout.lock();
|
52 | 68 |
|
53 |
| - out.write_u32::<NativeEndian>(buf.len() as u32).unwrap(); |
54 |
| - out.write_all(buf).unwrap(); |
55 |
| - out.flush().unwrap(); |
| 69 | + out.write_u32::<NativeEndian>(buf.len() as u32)?; |
| 70 | + out.write_all(buf)?; |
| 71 | + out.flush()?; |
| 72 | + |
| 73 | + Ok(()) |
56 | 74 | }
|
57 | 75 |
|
58 | 76 | fn main() {
|
59 | 77 | let mut socket = proxy_socket::connect(BUFFER_SIZE).unwrap();
|
60 | 78 |
|
61 | 79 | // Start thread for user input reading
|
62 |
| - let ui = thread::spawn(move || { |
63 |
| - loop { |
64 |
| - let length = read_header(); |
65 |
| - read_body(length, &mut socket); |
66 |
| - } |
| 80 | + let ui = thread::spawn(move || loop { |
| 81 | + let length = read_header().unwrap(); |
| 82 | + read_body(length, &mut socket).unwrap(); |
67 | 83 | });
|
68 | 84 |
|
69 | 85 | let _ui_res = ui.join().unwrap();
|
|
0 commit comments