@@ -22,6 +22,8 @@ package grpc
22
22
23
23
import (
24
24
"bufio"
25
+ "encoding/base64"
26
+ "fmt"
25
27
"io"
26
28
"net"
27
29
"net/http"
@@ -53,6 +55,8 @@ type proxyServer struct {
53
55
lis net.Listener
54
56
in net.Conn
55
57
out net.Conn
58
+
59
+ requestCheck func (* http.Request ) error
56
60
}
57
61
58
62
func (p * proxyServer ) run () {
@@ -67,11 +71,11 @@ func (p *proxyServer) run() {
67
71
p .t .Errorf ("failed to read CONNECT req: %v" , err )
68
72
return
69
73
}
70
- if req . Method != http . MethodConnect || req . UserAgent () != grpcUA {
74
+ if err := p . requestCheck ( req ); err != nil {
71
75
resp := http.Response {StatusCode : http .StatusMethodNotAllowed }
72
76
resp .Write (p .in )
73
77
p .in .Close ()
74
- p .t .Errorf ("get wrong CONNECT req: %+v" , req )
78
+ p .t .Errorf ("get wrong CONNECT req: %+v, error: %v " , req , err )
75
79
return
76
80
}
77
81
@@ -97,13 +101,17 @@ func (p *proxyServer) stop() {
97
101
}
98
102
}
99
103
100
- func TestHTTPConnect (t * testing.T ) {
104
+ func testHTTPConnect (t * testing.T , proxyURLModify func ( * url. URL ) * url. URL , proxyReqCheck func ( * http. Request ) error ) {
101
105
defer leakcheck .Check (t )
102
106
plis , err := net .Listen ("tcp" , "localhost:0" )
103
107
if err != nil {
104
108
t .Fatalf ("failed to listen: %v" , err )
105
109
}
106
- p := & proxyServer {t : t , lis : plis }
110
+ p := & proxyServer {
111
+ t : t ,
112
+ lis : plis ,
113
+ requestCheck : proxyReqCheck ,
114
+ }
107
115
go p .run ()
108
116
defer p .stop ()
109
117
@@ -128,7 +136,7 @@ func TestHTTPConnect(t *testing.T) {
128
136
129
137
// Overwrite the function in the test and restore them in defer.
130
138
hpfe := func (req * http.Request ) (* url.URL , error ) {
131
- return & url.URL {Host : plis .Addr ().String ()}, nil
139
+ return proxyURLModify ( & url.URL {Host : plis .Addr ().String ()}) , nil
132
140
}
133
141
defer overwrite (hpfe )()
134
142
@@ -157,6 +165,51 @@ func TestHTTPConnect(t *testing.T) {
157
165
}
158
166
}
159
167
168
+ func TestHTTPConnect (t * testing.T ) {
169
+ testHTTPConnect (t ,
170
+ func (in * url.URL ) * url.URL {
171
+ return in
172
+ },
173
+ func (req * http.Request ) error {
174
+ if req .Method != http .MethodConnect {
175
+ return fmt .Errorf ("unexpected Method %q, want %q" , req .Method , http .MethodConnect )
176
+ }
177
+ if req .UserAgent () != grpcUA {
178
+ return fmt .Errorf ("unexpect user agent %q, want %q" , req .UserAgent (), grpcUA )
179
+ }
180
+ return nil
181
+ },
182
+ )
183
+ }
184
+
185
+ func TestHTTPConnectBasicAuth (t * testing.T ) {
186
+ const (
187
+ user = "notAUser"
188
+ password = "notAPassword"
189
+ )
190
+ testHTTPConnect (t ,
191
+ func (in * url.URL ) * url.URL {
192
+ in .User = url .UserPassword (user , password )
193
+ return in
194
+ },
195
+ func (req * http.Request ) error {
196
+ if req .Method != http .MethodConnect {
197
+ return fmt .Errorf ("unexpected Method %q, want %q" , req .Method , http .MethodConnect )
198
+ }
199
+ if req .UserAgent () != grpcUA {
200
+ return fmt .Errorf ("unexpect user agent %q, want %q" , req .UserAgent (), grpcUA )
201
+ }
202
+ wantProxyAuthStr := base64 .StdEncoding .EncodeToString ([]byte (user + ":" + password ))
203
+ if got := req .Header .Get (proxyAuthHeaderKey ); got != wantProxyAuthStr {
204
+ gotDecoded , _ := base64 .StdEncoding .DecodeString (got )
205
+ wantDecoded , _ := base64 .StdEncoding .DecodeString (wantProxyAuthStr )
206
+ return fmt .Errorf ("unexpected auth %q (%q), want %q (%q)" , got , gotDecoded , wantProxyAuthStr , wantDecoded )
207
+ }
208
+ return nil
209
+ },
210
+ )
211
+ }
212
+
160
213
func TestMapAddressEnv (t * testing.T ) {
161
214
defer leakcheck .Check (t )
162
215
// Overwrite the function in the test and restore them in defer.
@@ -176,7 +229,7 @@ func TestMapAddressEnv(t *testing.T) {
176
229
if err != nil {
177
230
t .Error (err )
178
231
}
179
- if got != envProxyAddr {
232
+ if got . Host != envProxyAddr {
180
233
t .Errorf ("want %v, got %v" , envProxyAddr , got )
181
234
}
182
235
}
0 commit comments