@@ -2,7 +2,7 @@ use async_std::io::{self, Read};
2
2
use async_std:: prelude:: * ;
3
3
use async_std:: task:: { Context , Poll } ;
4
4
use http_types:: format_err;
5
- use http_types:: Request ;
5
+ use http_types:: { Method , Request } ;
6
6
7
7
use std:: pin:: Pin ;
8
8
@@ -41,6 +41,17 @@ impl Encoder {
41
41
url. push_str ( query) ;
42
42
}
43
43
44
+ // A client sending a CONNECT request MUST consists of only the host
45
+ // name and port number of the tunnel destination, separated by a colon.
46
+ // See: https://tools.ietf.org/html/rfc7231#section-4.3.6
47
+ if req. method ( ) == Method :: Connect {
48
+ let host = req. url ( ) . host_str ( ) ;
49
+ let host = host. ok_or_else ( || format_err ! ( "Missing hostname" ) ) ?;
50
+ let port = req. url ( ) . port_or_known_default ( ) ;
51
+ let port = port. ok_or_else ( || format_err ! ( "Missing port" ) ) ?;
52
+ url = format ! ( "{}:{}" , host, port) ;
53
+ }
54
+
44
55
let val = format ! ( "{} {} HTTP/1.1\r \n " , req. method( ) , url) ;
45
56
log:: trace!( "> {}" , & val) ;
46
57
buf. write_all ( val. as_bytes ( ) ) . await ?;
@@ -58,6 +69,13 @@ impl Encoder {
58
69
log:: trace!( "> {}" , & val) ;
59
70
buf. write_all ( val. as_bytes ( ) ) . await ?;
60
71
72
+ // Insert Proxy-Connection header when method is CONNECT
73
+ if req. method ( ) == Method :: Connect {
74
+ let val = "proxy-connection: keep-alive\r \n " . to_owned ( ) ;
75
+ log:: trace!( "> {}" , & val) ;
76
+ buf. write_all ( val. as_bytes ( ) ) . await ?;
77
+ }
78
+
61
79
// If the body isn't streaming, we can set the content-length ahead of time. Else we need to
62
80
// send all items in chunks.
63
81
if let Some ( len) = req. len ( ) {
0 commit comments