5 * Copyright 2017 gRPC authors.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
32 "golang.org/x/net/context"
33 "google.golang.org/grpc/test/leakcheck"
37 envTestAddr = "1.2.3.4:8080"
38 envProxyAddr = "2.3.4.5:7687"
41 // overwriteAndRestore overwrite function httpProxyFromEnvironment and
42 // returns a function to restore the default values.
43 func overwrite(hpfe func(req *http.Request) (*url.URL, error)) func() {
44 backHPFE := httpProxyFromEnvironment
45 httpProxyFromEnvironment = hpfe
47 httpProxyFromEnvironment = backHPFE
51 type proxyServer struct {
58 func (p *proxyServer) run() {
59 in, err := p.lis.Accept()
65 req, err := http.ReadRequest(bufio.NewReader(in))
67 p.t.Errorf("failed to read CONNECT req: %v", err)
70 if req.Method != http.MethodConnect || req.UserAgent() != grpcUA {
71 resp := http.Response{StatusCode: http.StatusMethodNotAllowed}
74 p.t.Errorf("get wrong CONNECT req: %+v", req)
78 out, err := net.Dial("tcp", req.URL.Host)
80 p.t.Errorf("failed to dial to server: %v", err)
83 resp := http.Response{StatusCode: http.StatusOK, Proto: "HTTP/1.0"}
86 go io.Copy(p.in, p.out)
87 go io.Copy(p.out, p.in)
90 func (p *proxyServer) stop() {
100 func TestHTTPConnect(t *testing.T) {
101 defer leakcheck.Check(t)
102 plis, err := net.Listen("tcp", "localhost:0")
104 t.Fatalf("failed to listen: %v", err)
106 p := &proxyServer{t: t, lis: plis}
110 blis, err := net.Listen("tcp", "localhost:0")
112 t.Fatalf("failed to listen: %v", err)
115 msg := []byte{4, 3, 5, 2}
116 recvBuf := make([]byte, len(msg), len(msg))
117 done := make(chan struct{})
119 in, err := blis.Accept()
121 t.Errorf("failed to accept: %v", err)
129 // Overwrite the function in the test and restore them in defer.
130 hpfe := func(req *http.Request) (*url.URL, error) {
131 return &url.URL{Host: plis.Addr().String()}, nil
133 defer overwrite(hpfe)()
135 // Dial to proxy server.
136 dialer := newProxyDialer(func(ctx context.Context, addr string) (net.Conn, error) {
137 if deadline, ok := ctx.Deadline(); ok {
138 return net.DialTimeout("tcp", addr, deadline.Sub(time.Now()))
140 return net.Dial("tcp", addr)
142 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
144 c, err := dialer(ctx, blis.Addr().String())
146 t.Fatalf("http connect Dial failed: %v", err)
150 // Send msg on the connection.
154 // Check received msg.
155 if string(recvBuf) != string(msg) {
156 t.Fatalf("received msg: %v, want %v", recvBuf, msg)
160 func TestMapAddressEnv(t *testing.T) {
161 defer leakcheck.Check(t)
162 // Overwrite the function in the test and restore them in defer.
163 hpfe := func(req *http.Request) (*url.URL, error) {
164 if req.URL.Host == envTestAddr {
172 defer overwrite(hpfe)()
174 // envTestAddr should be handled by ProxyFromEnvironment.
175 got, err := mapAddress(context.Background(), envTestAddr)
179 if got != envProxyAddr {
180 t.Errorf("want %v, got %v", envProxyAddr, got)