@@ -12,75 +12,54 @@ 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
16
-
17
- fn valid_length ( length : usize ) -> bool {
18
- length > 0 && length <= BUFFER_SIZE
19
- }
20
-
21
- // Read a header (message size) from stdin (e.g.: from the browser).
22
- fn read_header ( ) -> Result < usize > {
23
- let stdin = stdin ( ) ;
24
- let mut buf = vec ! [ 0 ; 4 ] ;
25
- let mut handle = stdin. lock ( ) ;
26
-
27
- handle. read_exact ( & mut buf) ?;
15
+ // > The maximum size of a single message from the application is 1 MB.
16
+ //
17
+ // From: https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_messaging#app_side
18
+ const BUFFER_SIZE : usize = 1024 * 1024 ;
28
19
29
- NativeEndian :: read_u32 ( & buf)
30
- . try_into ( )
31
- . map_err ( |err| Error :: new ( ErrorKind :: InvalidData , err) )
32
- }
20
+ fn stdin_to_socket < T : Read + Write > ( socket : & mut ProxySocket < T > ) -> Result < ( ) > {
21
+ let mut handle = stdin ( ) . lock ( ) ;
22
+ let mut len = vec ! [ 0 ; std:: mem:: size_of:: <u32 >( ) ] ;
33
23
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 < ( ) > {
39
- let mut buffer = vec ! [ 0 ; length] ;
40
- let stdin = stdin ( ) ;
41
- let mut handle = stdin. lock ( ) ;
24
+ loop {
25
+ handle. read_exact ( & mut len) ?;
26
+ let length: usize = NativeEndian :: read_u32 ( & len)
27
+ . try_into ( )
28
+ . map_err ( |err| Error :: new ( ErrorKind :: InvalidData , err) ) ?;
42
29
43
- handle. read_exact ( & mut buffer) ?;
30
+ let mut buffer = vec ! [ 0 ; length] ;
31
+ handle. read_exact ( & mut buffer) ?;
44
32
45
- if valid_length ( length) {
46
33
socket. write_all ( & buffer) ?;
47
34
socket. flush ( ) ?;
48
- read_response ( socket) ?;
49
35
}
50
-
51
- Ok ( ( ) )
52
36
}
53
37
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 < ( ) > {
56
- let mut buf = vec ! [ 0 ; BUFFER_SIZE ] ;
57
- if let Ok ( len) = socket. read ( & mut buf) {
58
- write_response ( & buf[ 0 ..len] ) ?;
38
+ /// Reads from the socket and writes to stdout.
39
+ /// Returns when the socket is closed.
40
+ fn socket_to_stdout < T : Read + Write > ( socket : & mut ProxySocket < T > ) -> Result < ( ) > {
41
+ let mut out = stdout ( ) . lock ( ) ;
42
+ let mut buf = [ 0 ; BUFFER_SIZE ] ;
43
+
44
+ while let Ok ( len) = socket. read ( & mut buf) {
45
+ // If a message is larger than the maximum, ignore it entirely. These are disallowed
46
+ // by the browser anyway, so sending one would be a protocol violation.
47
+ if len <= BUFFER_SIZE {
48
+ out. write_u32 :: < NativeEndian > ( len as u32 ) ?;
49
+ out. write_all ( & buf[ ..len] ) ?;
50
+ out. flush ( ) ?;
51
+ }
59
52
}
60
53
61
54
Ok ( ( ) )
62
55
}
63
56
64
- // Write a response to stdout (e.g.: to the browser).
65
- fn write_response ( buf : & [ u8 ] ) -> Result < ( ) > {
66
- let stdout = stdout ( ) ;
67
- let mut out = stdout. lock ( ) ;
57
+ fn main ( ) -> Result < ( ) > {
58
+ let mut socket = proxy_socket:: connect ( BUFFER_SIZE ) ?;
59
+ let mut socket_clone = socket. try_clone ( ) ?;
68
60
69
- out. write_u32 :: < NativeEndian > ( buf. len ( ) as u32 ) ?;
70
- out. write_all ( buf) ?;
71
- out. flush ( ) ?;
61
+ thread:: spawn ( move || stdin_to_socket ( & mut socket) ) ;
62
+ socket_to_stdout ( & mut socket_clone) ?;
72
63
73
64
Ok ( ( ) )
74
65
}
75
-
76
- fn main ( ) {
77
- let mut socket = proxy_socket:: connect ( BUFFER_SIZE ) . unwrap ( ) ;
78
-
79
- // Start thread for user input reading
80
- let ui = thread:: spawn ( move || loop {
81
- let length = read_header ( ) . unwrap ( ) ;
82
- read_body ( length, & mut socket) . unwrap ( ) ;
83
- } ) ;
84
-
85
- let _ui_res = ui. join ( ) . unwrap ( ) ;
86
- }
0 commit comments