Fix 2.4.2 upgrade notes formatting refs #19330
[arvados.git] / sdk / go / arvadostest / proxy.go
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: Apache-2.0
4
5 package arvadostest
6
7 import (
8         "crypto/tls"
9         "net"
10         "net/http"
11         "net/http/httptest"
12         "net/http/httputil"
13         "net/url"
14         "time"
15
16         "git.arvados.org/arvados.git/sdk/go/arvados"
17         "gopkg.in/check.v1"
18 )
19
20 type Proxy struct {
21         *httptest.Server
22
23         // URL where the proxy is listening. Same as Server.URL, but
24         // with parsing already done for you.
25         URL *url.URL
26
27         // A dump of each request that has been proxied.
28         RequestDumps [][]byte
29 }
30
31 // NewProxy returns a new Proxy that saves a dump of each reqeust
32 // before forwarding to the indicated service.
33 func NewProxy(c *check.C, svc arvados.Service) *Proxy {
34         var target url.URL
35         c.Assert(svc.InternalURLs, check.HasLen, 1)
36         for u := range svc.InternalURLs {
37                 target = url.URL(u)
38                 break
39         }
40         rp := httputil.NewSingleHostReverseProxy(&target)
41         rp.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
42                 dump, _ := httputil.DumpRequest(r, false)
43                 c.Logf("arvadostest.Proxy ErrorHandler(%s): %s\n%s", r.URL, err, dump)
44                 http.Error(w, err.Error(), http.StatusBadGateway)
45         }
46         rp.Transport = &http.Transport{
47                 DialContext: (&net.Dialer{
48                         Timeout:   30 * time.Second,
49                         KeepAlive: 30 * time.Second,
50                         DualStack: true,
51                 }).DialContext,
52                 MaxIdleConns:          100,
53                 IdleConnTimeout:       90 * time.Second,
54                 TLSHandshakeTimeout:   10 * time.Second,
55                 ExpectContinueTimeout: 1 * time.Second,
56                 TLSClientConfig:       &tls.Config{InsecureSkipVerify: true},
57         }
58         srv := httptest.NewServer(rp)
59         u, err := url.Parse(srv.URL)
60         c.Assert(err, check.IsNil)
61         proxy := &Proxy{
62                 Server: srv,
63                 URL:    u,
64         }
65         rp.Director = func(r *http.Request) {
66                 dump, _ := httputil.DumpRequest(r, true)
67                 proxy.RequestDumps = append(proxy.RequestDumps, dump)
68                 r.URL.Scheme = target.Scheme
69                 r.URL.Host = target.Host
70         }
71         return proxy
72 }