@@ -12,75 +12,64 @@ 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
+ /// Reads from stdin and writes to the socket.
21
+ /// Returns on error.
22
+ fn stdin_to_socket < T : Read + Write > ( socket : & mut ProxySocket < T > ) -> Result < ( ) > {
23
+ let mut handle = stdin ( ) . lock ( ) ;
24
+ let mut len = vec ! [ 0 ; std:: mem:: size_of:: <u32 >( ) ] ;
33
25
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 ( ) ;
26
+ loop {
27
+ handle. read_exact ( & mut len) ?;
28
+ let length: usize = NativeEndian :: read_u32 ( & len)
29
+ . try_into ( )
30
+ . map_err ( |err| Error :: new ( ErrorKind :: InvalidData , err) ) ?;
42
31
43
- handle. read_exact ( & mut buffer) ?;
32
+ let mut buffer = vec ! [ 0 ; length] ;
33
+ handle. read_exact ( & mut buffer) ?;
44
34
45
- if valid_length ( length) {
46
35
socket. write_all ( & buffer) ?;
47
36
socket. flush ( ) ?;
48
- read_response ( socket) ?;
49
37
}
50
-
51
- Ok ( ( ) )
52
38
}
53
39
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] ) ?;
40
+ /// Reads from the socket and writes to stdout.
41
+ /// Returns on error.
42
+ fn socket_to_stdout < T : Read + Write > ( socket : & mut ProxySocket < T > ) -> Result < ( ) > {
43
+ let mut out = stdout ( ) . lock ( ) ;
44
+ let mut buf = [ 0 ; BUFFER_SIZE ] ;
45
+
46
+ loop {
47
+ if let Ok ( len) = socket. read ( & mut buf) {
48
+ // If a message is larger than the maximum, ignore it entirely. These are disallowed
49
+ // by the browser anyway, so sending one would be a protocol violation.
50
+ if len <= BUFFER_SIZE {
51
+ out. write_u32 :: < NativeEndian > ( len as u32 ) ?;
52
+ out. write_all ( & buf[ ..len] ) ?;
53
+ out. flush ( ) ?;
54
+ } ;
55
+ } else {
56
+ // TOOD: is the socket is closed, we should try to reconnect.
57
+
58
+ return Err ( Error :: from ( ErrorKind :: BrokenPipe ) ) ;
59
+ }
59
60
}
60
-
61
- Ok ( ( ) )
62
61
}
63
62
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 ( ) ;
68
-
69
- out. write_u32 :: < NativeEndian > ( buf. len ( ) as u32 ) ?;
70
- out. write_all ( buf) ?;
71
- out. flush ( ) ?;
63
+ fn main ( ) -> Result < ( ) > {
64
+ let mut socket = proxy_socket:: connect ( BUFFER_SIZE ) ?;
65
+ let mut socket_clone = socket. try_clone ( ) ?;
72
66
73
- Ok ( ( ) )
74
- }
67
+ thread:: spawn ( move || socket_to_stdout ( & mut socket_clone) . unwrap ( ) ) ;
75
68
76
- fn main ( ) {
77
- let mut socket = proxy_socket:: connect ( BUFFER_SIZE ) . unwrap ( ) ;
69
+ // If stdin is closed, that means that Firefox has exited, so we exit too.
70
+ // If the socket is closed, this will (eventually) fail too, however, this can later be
71
+ // refactored to reconnect the underlying ProxySocket.
72
+ stdin_to_socket ( & mut socket) . unwrap ( ) ;
78
73
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 ( ) ;
74
+ Ok ( ( ) )
86
75
}
0 commit comments