1
- use tokio:: io;
2
1
use tokio:: io:: AsyncWriteExt ;
2
+ use tokio:: io:: { self , AsyncReadExt } ;
3
3
use tokio:: net:: { TcpListener , TcpStream } ;
4
4
5
5
use futures:: FutureExt ;
@@ -10,17 +10,19 @@ pub struct Server {
10
10
}
11
11
12
12
impl Server {
13
+ // start server
13
14
pub async fn run ( & self ) -> Result < ( ) , Box < dyn Error > > {
14
15
let listen_addr = "127.0.0.1:" . to_string ( ) + & self . port . to_string ( ) ;
15
16
16
17
log:: info!( "Listening on: {}" , listen_addr) ;
17
18
18
19
let listener = TcpListener :: bind ( listen_addr) . await ?;
19
20
21
+ // listener loop that passes off to handler
20
22
while let Ok ( ( inbound, _) ) = listener. accept ( ) . await {
21
23
let handler = handle ( inbound) . map ( |r| {
22
24
if let Err ( e) = r {
23
- log:: error!( "Failed to proxy ; error={}" , e) ;
25
+ log:: error!( "Failed to handle request ; error={}" , e) ;
24
26
}
25
27
} ) ;
26
28
@@ -30,6 +32,32 @@ impl Server {
30
32
}
31
33
}
32
34
35
+ // request handler
36
+ async fn handle ( mut inbound : TcpStream ) -> Result < ( ) , Box < dyn Error > > {
37
+ let mut buf = vec ! [ 0 ; 1024 ] ;
38
+ inbound. read ( & mut buf) . await . unwrap ( ) ;
39
+ let mut headers = [ httparse:: EMPTY_HEADER ; 16 ] ;
40
+ let mut r = httparse:: Request :: new ( & mut headers) ;
41
+
42
+ r. parse ( & buf) . unwrap ( ) ;
43
+
44
+ let p = headers. iter ( ) . position ( |& h| h. name == "Host" ) . unwrap ( ) ;
45
+ let host = String :: from_utf8_lossy ( headers[ p] . value ) ;
46
+
47
+ log:: info!( "{}" , host) ;
48
+
49
+ let proxy = proxy ( inbound, host. to_string ( ) ) . map ( |r| {
50
+ if let Err ( e) = r {
51
+ log:: error!( "Failed to proxy; error={}" , e) ;
52
+ }
53
+ } ) ;
54
+
55
+ tokio:: spawn ( proxy) ;
56
+
57
+ Ok ( ( ) )
58
+ }
59
+
60
+ // proxy a tcp stream
33
61
async fn proxy ( mut inbound : TcpStream , proxy_addr : String ) -> Result < ( ) , Box < dyn Error > > {
34
62
let mut outbound = TcpStream :: connect ( proxy_addr) . await ?;
35
63
@@ -50,31 +78,3 @@ async fn proxy(mut inbound: TcpStream, proxy_addr: String) -> Result<(), Box<dyn
50
78
51
79
Ok ( ( ) )
52
80
}
53
-
54
- async fn handle ( inbound : TcpStream ) -> Result < ( ) , Box < dyn Error > > {
55
- let server_addr = "127.0.0.1:8080" . to_string ( ) ;
56
-
57
- let transfer = proxy ( inbound, server_addr. clone ( ) ) . map ( |r| {
58
- if let Err ( e) = r {
59
- log:: error!( "Failed to proxy; error={}" , e) ;
60
- }
61
- } ) ;
62
-
63
- tokio:: spawn ( transfer) ;
64
-
65
- Ok ( ( ) )
66
- }
67
-
68
- fn gethost ( ) -> Result < ( ) , Box < dyn Error > > {
69
- let mut headers = [ httparse:: EMPTY_HEADER ; 64 ] ;
70
- let mut req = httparse:: Request :: new ( & mut headers) ;
71
-
72
- let buf = b"GET /index.html HTTP/1.1\r \n Host" ;
73
- assert ! ( req. parse( buf) ?. is_partial( ) ) ;
74
-
75
- // a partial request, so we try again once we have more data
76
-
77
- let buf = b"GET /index.html HTTP/1.1\r \n Host: example.domain\r \n \r \n " ;
78
- assert ! ( req. parse( buf) ?. is_complete( ) ) ;
79
- Ok ( ( ) )
80
- }
0 commit comments