From 3ebe5a422f9214721dc7ace46265a10ed7cf52b1 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Jul 2023 01:50:38 +0000 Subject: [PATCH 1/5] feat: support localhost apps running https --- coderd/tailnet.go | 18 +++++++++++++++++- coderd/wsconncache/wsconncache.go | 17 ++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/coderd/tailnet.go b/coderd/tailnet.go index bfbfcabdebc19..6d234ade32bbf 100644 --- a/coderd/tailnet.go +++ b/coderd/tailnet.go @@ -3,6 +3,7 @@ package coderd import ( "bufio" "context" + "crypto/tls" "net" "net/http" "net/http/httputil" @@ -214,7 +215,22 @@ type ServerTailnet struct { transport *http.Transport } +func insecureTLSConfig() *tls.Config { + return &tls.Config{ + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: true, + } +} + func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID) (_ *httputil.ReverseProxy, release func(), _ error) { + transport := s.transport + + // We don't verify certificates for localhost applications. + if targetURL.Scheme == "https" { + transport = transport.Clone() + transport.TLSClientConfig = insecureTLSConfig() + } + proxy := httputil.NewSingleHostReverseProxy(targetURL) proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { site.RenderStaticErrorPage(w, r, site.ErrorPageData{ @@ -226,7 +242,7 @@ func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID u }) } proxy.Director = s.director(agentID, proxy.Director) - proxy.Transport = s.transport + proxy.Transport = transport return proxy, func() {}, nil } diff --git a/coderd/wsconncache/wsconncache.go b/coderd/wsconncache/wsconncache.go index 13d1588384954..a6ea04bc9232e 100644 --- a/coderd/wsconncache/wsconncache.go +++ b/coderd/wsconncache/wsconncache.go @@ -4,6 +4,7 @@ package wsconncache import ( "context" + "crypto/tls" "net/http" "net/http/httputil" "net/url" @@ -49,8 +50,15 @@ func (a *AgentProvider) ReverseProxy(targetURL *url.URL, dashboardURL *url.URL, return nil, nil, xerrors.Errorf("acquire agent connection: %w", err) } - proxy.Transport = conn.HTTPTransport() + transport := conn.HTTPTransport() + // We don't verify certificates for localhost applications. + if targetURL.Scheme == "https" { + trans := transport.Clone() + trans.TLSClientConfig = insecureTLSConfig() + } + + proxy.Transport = transport return proxy, release, nil } @@ -211,3 +219,10 @@ func (c *Cache) Close() error { c.closeGroup.Wait() return nil } + +func insecureTLSConfig() *tls.Config { + return &tls.Config{ + MinVersion: tls.VersionTLS12, + InsecureSkipVerify: true, + } +} From 3238edf0542c5c92dec078ce2d1f51122591f558 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Jul 2023 03:11:35 +0000 Subject: [PATCH 2/5] add a test --- coderd/tailnet.go | 2 + coderd/tailnet_test.go | 123 +++++++++++++++++++++++++++-------------- 2 files changed, 82 insertions(+), 43 deletions(-) diff --git a/coderd/tailnet.go b/coderd/tailnet.go index 6d234ade32bbf..ddc0305d4813b 100644 --- a/coderd/tailnet.go +++ b/coderd/tailnet.go @@ -215,6 +215,8 @@ type ServerTailnet struct { transport *http.Transport } +// insureTLSConfig returns a tls config that does not verify +// the server's certificate chain. func insecureTLSConfig() *tls.Config { return &tls.Config{ MinVersion: tls.VersionTLS12, diff --git a/coderd/tailnet_test.go b/coderd/tailnet_test.go index d6341391934a7..1017a041b4dd2 100644 --- a/coderd/tailnet_test.go +++ b/coderd/tailnet_test.go @@ -62,66 +62,103 @@ func TestServerTailnet_AgentConn_Legacy(t *testing.T) { assert.True(t, conn.AwaitReachable(ctx)) } -func TestServerTailnet_ReverseProxy_OK(t *testing.T) { +func TestServerTailnet_ReverseProxy(t *testing.T) { t.Parallel() - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) - defer cancel() + t.Run("OK", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() - // Force a connection through wsconncache using the legacy hardcoded ip. - agentID, _, serverTailnet := setupAgent(t, nil) + agentID, _, serverTailnet := setupAgent(t, nil) - u, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", codersdk.WorkspaceAgentHTTPAPIServerPort)) - require.NoError(t, err) + u, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", codersdk.WorkspaceAgentHTTPAPIServerPort)) + require.NoError(t, err) - rp, release, err := serverTailnet.ReverseProxy(u, u, agentID) - require.NoError(t, err) - defer release() + rp, release, err := serverTailnet.ReverseProxy(u, u, agentID) + require.NoError(t, err) + defer release() - rw := httptest.NewRecorder() - req := httptest.NewRequest( - http.MethodGet, - u.String(), - nil, - ).WithContext(ctx) + rw := httptest.NewRecorder() + req := httptest.NewRequest( + http.MethodGet, + u.String(), + nil, + ).WithContext(ctx) - rp.ServeHTTP(rw, req) - res := rw.Result() - defer res.Body.Close() + rp.ServeHTTP(rw, req) + res := rw.Result() + defer res.Body.Close() - assert.Equal(t, http.StatusOK, res.StatusCode) -} + assert.Equal(t, http.StatusOK, res.StatusCode) + }) -func TestServerTailnet_ReverseProxy_Legacy(t *testing.T) { - t.Parallel() + t.Run("HTTPSProxy", func(t *testing.T) { + t.Parallel() - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) - defer cancel() + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() - // Force a connection through wsconncache using the legacy hardcoded ip. - agentID, _, serverTailnet := setupAgent(t, []netip.Prefix{ - netip.PrefixFrom(codersdk.WorkspaceAgentIP, 128), + agentID, _, serverTailnet := setupAgent(t, nil) + + const expectedResponseCode = 209 + // Test that we can proxy HTTPS traffic. + s := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(expectedResponseCode) + })) + defer s.Close() + + uri, err := url.Parse(s.URL) + require.NoError(t, err) + + rp, release, err := serverTailnet.ReverseProxy(uri, uri, agentID) + require.NoError(t, err) + defer release() + + rw := httptest.NewRecorder() + req := httptest.NewRequest( + http.MethodGet, + uri.String(), + nil, + ).WithContext(ctx) + + rp.ServeHTTP(rw, req) + res := rw.Result() + defer res.Body.Close() + + assert.Equal(t, expectedResponseCode, res.StatusCode) }) - u, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", codersdk.WorkspaceAgentHTTPAPIServerPort)) - require.NoError(t, err) + t.Run("Legacy", func(t *testing.T) { + t.Parallel() - rp, release, err := serverTailnet.ReverseProxy(u, u, agentID) - require.NoError(t, err) - defer release() + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + // Force a connection through wsconncache using the legacy hardcoded ip. + agentID, _, serverTailnet := setupAgent(t, []netip.Prefix{ + netip.PrefixFrom(codersdk.WorkspaceAgentIP, 128), + }) + + u, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d", codersdk.WorkspaceAgentHTTPAPIServerPort)) + require.NoError(t, err) + + rp, release, err := serverTailnet.ReverseProxy(u, u, agentID) + require.NoError(t, err) + defer release() - rw := httptest.NewRecorder() - req := httptest.NewRequest( - http.MethodGet, - u.String(), - nil, - ).WithContext(ctx) + rw := httptest.NewRecorder() + req := httptest.NewRequest( + http.MethodGet, + u.String(), + nil, + ).WithContext(ctx) - rp.ServeHTTP(rw, req) - res := rw.Result() - defer res.Body.Close() + rp.ServeHTTP(rw, req) + res := rw.Result() + defer res.Body.Close() - assert.Equal(t, http.StatusOK, res.StatusCode) + assert.Equal(t, http.StatusOK, res.StatusCode) + }) } func setupAgent(t *testing.T, agentAddresses []netip.Prefix) (uuid.UUID, agent.Agent, *coderd.ServerTailnet) { From 56e2427fb572d4e327ec338d09129812a03781d8 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Jul 2023 22:00:42 +0000 Subject: [PATCH 3/5] add wsconncache tests --- coderd/tailnet.go | 30 ++++---- coderd/tailnet_test.go | 2 +- coderd/workspaceapps/apptest/apptest.go | 93 ++++++++++++++++++++++++- coderd/workspaceapps/apptest/setup.go | 87 +++++++++++------------ coderd/wsconncache/wsconncache.go | 25 ++++--- 5 files changed, 157 insertions(+), 80 deletions(-) diff --git a/coderd/tailnet.go b/coderd/tailnet.go index ddc0305d4813b..c37f583da252e 100644 --- a/coderd/tailnet.go +++ b/coderd/tailnet.go @@ -71,6 +71,17 @@ func NewServerTailnet( tn.transport.DialContext = tn.dialContext tn.transport.MaxIdleConnsPerHost = 10 tn.transport.MaxIdleConns = 0 + // We intentionally don't verify the certificate chain here. + // The connection to the workspace is already established and most + // apps are already going to be accessed over plain HTTP, this config + // simply allows apps being run over HTTPS to be accessed without error -- + // many of which may be using self-signed certs. + tn.transport.TLSClientConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + //nolint:gosec + InsecureSkipVerify: true, + } + agentConn, err := getMultiAgent(ctx) if err != nil { return nil, xerrors.Errorf("get initial multi agent: %w", err) @@ -215,24 +226,7 @@ type ServerTailnet struct { transport *http.Transport } -// insureTLSConfig returns a tls config that does not verify -// the server's certificate chain. -func insecureTLSConfig() *tls.Config { - return &tls.Config{ - MinVersion: tls.VersionTLS12, - InsecureSkipVerify: true, - } -} - func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID) (_ *httputil.ReverseProxy, release func(), _ error) { - transport := s.transport - - // We don't verify certificates for localhost applications. - if targetURL.Scheme == "https" { - transport = transport.Clone() - transport.TLSClientConfig = insecureTLSConfig() - } - proxy := httputil.NewSingleHostReverseProxy(targetURL) proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) { site.RenderStaticErrorPage(w, r, site.ErrorPageData{ @@ -244,7 +238,7 @@ func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID u }) } proxy.Director = s.director(agentID, proxy.Director) - proxy.Transport = transport + proxy.Transport = s.transport return proxy, func() {}, nil } diff --git a/coderd/tailnet_test.go b/coderd/tailnet_test.go index 1017a041b4dd2..084ef2304762c 100644 --- a/coderd/tailnet_test.go +++ b/coderd/tailnet_test.go @@ -105,7 +105,7 @@ func TestServerTailnet_ReverseProxy(t *testing.T) { s := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(expectedResponseCode) })) - defer s.Close() + t.Cleanup(s.Close) uri, err := url.Parse(s.URL) require.NoError(t, err) diff --git a/coderd/workspaceapps/apptest/apptest.go b/coderd/workspaceapps/apptest/apptest.go index 43ca833f9df26..f64ba7c30bf31 100644 --- a/coderd/workspaceapps/apptest/apptest.go +++ b/coderd/workspaceapps/apptest/apptest.go @@ -349,6 +349,51 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) { require.Equal(t, http.StatusOK, resp.StatusCode) }) + t.Run("ProxiesHTTPS", func(t *testing.T) { + t.Parallel() + + appDetails := setupProxyTest(t, &DeploymentOptions{ + ServeHTTPS: true, + }) + + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + u := appDetails.PathAppURL(appDetails.Apps.Owner) + resp, err := requestWithRetries(ctx, t, appDetails.AppClient(t), http.MethodGet, u.String(), nil) + require.NoError(t, err) + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, proxyTestAppBody, string(body)) + require.Equal(t, http.StatusOK, resp.StatusCode) + + var appTokenCookie *http.Cookie + for _, c := range resp.Cookies() { + if c.Name == codersdk.DevURLSignedAppTokenCookie { + appTokenCookie = c + break + } + } + require.NotNil(t, appTokenCookie, "no signed app token cookie in response") + require.Equal(t, appTokenCookie.Path, u.Path, "incorrect path on app token cookie") + + // Ensure the signed app token cookie is valid. + appTokenClient := appDetails.AppClient(t) + appTokenClient.SetSessionToken("") + appTokenClient.HTTPClient.Jar, err = cookiejar.New(nil) + require.NoError(t, err) + appTokenClient.HTTPClient.Jar.SetCookies(u, []*http.Cookie{appTokenCookie}) + + resp, err = requestWithRetries(ctx, t, appTokenClient, http.MethodGet, u.String(), nil) + require.NoError(t, err) + defer resp.Body.Close() + body, err = io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, proxyTestAppBody, string(body)) + require.Equal(t, http.StatusOK, resp.StatusCode) + }) + t.Run("BlocksMe", func(t *testing.T) { t.Parallel() @@ -762,6 +807,50 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) { require.Equal(t, http.StatusOK, resp.StatusCode) }) + t.Run("ProxiesHTTPS", func(t *testing.T) { + t.Parallel() + + appDetails := setupProxyTest(t, &DeploymentOptions{ + ServeHTTPS: true, + }) + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + defer cancel() + + u := appDetails.SubdomainAppURL(appDetails.Apps.Owner) + resp, err := requestWithRetries(ctx, t, appDetails.AppClient(t), http.MethodGet, u.String(), nil) + require.NoError(t, err) + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, proxyTestAppBody, string(body)) + require.Equal(t, http.StatusOK, resp.StatusCode) + + var appTokenCookie *http.Cookie + for _, c := range resp.Cookies() { + if c.Name == codersdk.DevURLSignedAppTokenCookie { + appTokenCookie = c + break + } + } + require.NotNil(t, appTokenCookie, "no signed token cookie in response") + require.Equal(t, appTokenCookie.Path, "/", "incorrect path on signed token cookie") + + // Ensure the signed app token cookie is valid. + appTokenClient := appDetails.AppClient(t) + appTokenClient.SetSessionToken("") + appTokenClient.HTTPClient.Jar, err = cookiejar.New(nil) + require.NoError(t, err) + appTokenClient.HTTPClient.Jar.SetCookies(u, []*http.Cookie{appTokenCookie}) + + resp, err = requestWithRetries(ctx, t, appTokenClient, http.MethodGet, u.String(), nil) + require.NoError(t, err) + defer resp.Body.Close() + body, err = io.ReadAll(resp.Body) + require.NoError(t, err) + require.Equal(t, proxyTestAppBody, string(body)) + require.Equal(t, http.StatusOK, resp.StatusCode) + }) + t.Run("ProxiesPort", func(t *testing.T) { t.Parallel() @@ -928,8 +1017,8 @@ func Run(t *testing.T, appHostIsPrimary bool, factory DeploymentFactory) { forceURLTransport(t, client) // Create workspace. - port := appServer(t, nil) - workspace, _ = createWorkspaceWithApps(t, client, user.OrganizationIDs[0], user, port) + port := appServer(t, nil, false) + workspace, _ = createWorkspaceWithApps(t, client, user.OrganizationIDs[0], user, port, false) // Verify that the apps have the correct sharing levels set. workspaceBuild, err := client.WorkspaceBuild(ctx, workspace.LatestBuild.ID) diff --git a/coderd/workspaceapps/apptest/setup.go b/coderd/workspaceapps/apptest/setup.go index 916b6a09ba068..4245204268391 100644 --- a/coderd/workspaceapps/apptest/setup.go +++ b/coderd/workspaceapps/apptest/setup.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "net/http" + "net/http/httptest" "net/url" "path" "strconv" @@ -48,6 +49,7 @@ type DeploymentOptions struct { DisableSubdomainApps bool DangerousAllowPathAppSharing bool DangerousAllowPathAppSiteOwnerAccess bool + ServeHTTPS bool // The following fields are only used by setupProxyTestWithFactory. noWorkspace bool @@ -185,9 +187,9 @@ func setupProxyTestWithFactory(t *testing.T, factory DeploymentFactory, opts *De } if opts.port == 0 { - opts.port = appServer(t, opts.headers) + opts.port = appServer(t, opts.headers, opts.ServeHTTPS) } - workspace, agnt := createWorkspaceWithApps(t, deployment.SDKClient, deployment.FirstUser.OrganizationID, me, opts.port) + workspace, agnt := createWorkspaceWithApps(t, deployment.SDKClient, deployment.FirstUser.OrganizationID, me, opts.port, opts.ServeHTTPS) details := &Details{ Deployment: deployment, @@ -234,60 +236,53 @@ func setupProxyTestWithFactory(t *testing.T, factory DeploymentFactory, opts *De return details } -func appServer(t *testing.T, headers http.Header) uint16 { - // Start a listener on a random port greater than the minimum app port. - var ( - ln net.Listener - tcpAddr *net.TCPAddr +//nolint:revive +func appServer(t *testing.T, headers http.Header, isHTTPS bool) uint16 { + server := httptest.NewUnstartedServer( + http.HandlerFunc( + func(w http.ResponseWriter, r *http.Request) { + _, err := r.Cookie(codersdk.SessionTokenCookie) + assert.ErrorIs(t, err, http.ErrNoCookie) + w.Header().Set("X-Forwarded-For", r.Header.Get("X-Forwarded-For")) + for name, values := range headers { + for _, value := range values { + w.Header().Add(name, value) + } + } + w.WriteHeader(http.StatusOK) + _, _ = w.Write([]byte(proxyTestAppBody)) + }, + ), ) - for i := 0; i < 32; i++ { - var err error - // #nosec - ln, err = net.Listen("tcp", ":0") - require.NoError(t, err) - var ok bool - tcpAddr, ok = ln.Addr().(*net.TCPAddr) - require.True(t, ok) - if tcpAddr.Port < codersdk.WorkspaceAgentMinimumListeningPort { - _ = ln.Close() - ln = nil - time.Sleep(20 * time.Millisecond) - continue - } - } - require.NotNil(t, ln, "failed to find a free port greater than the minimum app port") - - server := http.Server{ - ReadHeaderTimeout: time.Minute, - Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := r.Cookie(codersdk.SessionTokenCookie) - assert.ErrorIs(t, err, http.ErrNoCookie) - w.Header().Set("X-Forwarded-For", r.Header.Get("X-Forwarded-For")) - for name, values := range headers { - for _, value := range values { - w.Header().Add(name, value) - } - } - w.WriteHeader(http.StatusOK) - _, _ = w.Write([]byte(proxyTestAppBody)) - }), + server.Config.ReadHeaderTimeout = time.Minute + if isHTTPS { + server.StartTLS() + } else { + server.Start() } t.Cleanup(func() { - _ = server.Close() - _ = ln.Close() + server.Close() }) - go func() { - _ = server.Serve(ln) - }() - return uint16(tcpAddr.Port) + _, portStr, err := net.SplitHostPort(server.Listener.Addr().String()) + require.NoError(t, err) + port, err := strconv.ParseUint(portStr, 10, 16) + require.NoError(t, err) + + return uint16(port) } -func createWorkspaceWithApps(t *testing.T, client *codersdk.Client, orgID uuid.UUID, me codersdk.User, port uint16, workspaceMutators ...func(*codersdk.CreateWorkspaceRequest)) (codersdk.Workspace, codersdk.WorkspaceAgent) { +//nolint:revive +func createWorkspaceWithApps(t *testing.T, client *codersdk.Client, orgID uuid.UUID, me codersdk.User, port uint16, serveHTTPS bool, workspaceMutators ...func(*codersdk.CreateWorkspaceRequest)) (codersdk.Workspace, codersdk.WorkspaceAgent) { authToken := uuid.NewString() - appURL := fmt.Sprintf("http://127.0.0.1:%d?%s", port, proxyTestAppQuery) + scheme := "http" + if serveHTTPS { + scheme = "https" + } + + appURL := fmt.Sprintf("%s://127.0.0.1:%d?%s", scheme, port, proxyTestAppQuery) version := coderdtest.CreateTemplateVersion(t, client, orgID, &echo.Responses{ Parse: echo.ParseComplete, ProvisionPlan: echo.ProvisionComplete, diff --git a/coderd/wsconncache/wsconncache.go b/coderd/wsconncache/wsconncache.go index a6ea04bc9232e..2ee8aa5ba400e 100644 --- a/coderd/wsconncache/wsconncache.go +++ b/coderd/wsconncache/wsconncache.go @@ -51,12 +51,6 @@ func (a *AgentProvider) ReverseProxy(targetURL *url.URL, dashboardURL *url.URL, } transport := conn.HTTPTransport() - // We don't verify certificates for localhost applications. - if targetURL.Scheme == "https" { - trans := transport.Clone() - trans.TLSClientConfig = insecureTLSConfig() - - } proxy.Transport = transport return proxy, release, nil @@ -162,6 +156,18 @@ func (c *Cache) Acquire(id uuid.UUID) (*Conn, func(), error) { } transport := defaultTransport.Clone() transport.DialContext = agentConn.DialContext + + // // We intentionally don't verify the certificate chain here. + // // The connection to the workspace is already established and most + // // apps are already going to be accessed over plain HTTP, this config + // // simply allows apps being run over HTTPS to be accessed without error -- + // // many of which may be using self-signed certs. + transport.TLSClientConfig = &tls.Config{ + MinVersion: tls.VersionTLS12, + //nolint:gosec + InsecureSkipVerify: true, + } + conn := &Conn{ WorkspaceAgentConn: agentConn, timeoutCancel: timeoutCancelFunc, @@ -219,10 +225,3 @@ func (c *Cache) Close() error { c.closeGroup.Wait() return nil } - -func insecureTLSConfig() *tls.Config { - return &tls.Config{ - MinVersion: tls.VersionTLS12, - InsecureSkipVerify: true, - } -} From 14e1ccd71c6208de6eedc83e904fd8c3b0dba20a Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Jul 2023 22:13:03 +0000 Subject: [PATCH 4/5] lint --- coderd/tailnet_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/coderd/tailnet_test.go b/coderd/tailnet_test.go index 084ef2304762c..46408179a220d 100644 --- a/coderd/tailnet_test.go +++ b/coderd/tailnet_test.go @@ -66,6 +66,8 @@ func TestServerTailnet_ReverseProxy(t *testing.T) { t.Parallel() t.Run("OK", func(t *testing.T) { + t.Parallel() + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() From bf677191d5c66c21f2674423f652e6792e0e57f2 Mon Sep 17 00:00:00 2001 From: Jon Ayers Date: Wed, 19 Jul 2023 22:17:44 +0000 Subject: [PATCH 5/5] double comment --- coderd/wsconncache/wsconncache.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/coderd/wsconncache/wsconncache.go b/coderd/wsconncache/wsconncache.go index 2ee8aa5ba400e..4ff7f30e049eb 100644 --- a/coderd/wsconncache/wsconncache.go +++ b/coderd/wsconncache/wsconncache.go @@ -157,11 +157,11 @@ func (c *Cache) Acquire(id uuid.UUID) (*Conn, func(), error) { transport := defaultTransport.Clone() transport.DialContext = agentConn.DialContext - // // We intentionally don't verify the certificate chain here. - // // The connection to the workspace is already established and most - // // apps are already going to be accessed over plain HTTP, this config - // // simply allows apps being run over HTTPS to be accessed without error -- - // // many of which may be using self-signed certs. + // We intentionally don't verify the certificate chain here. + // The connection to the workspace is already established and most + // apps are already going to be accessed over plain HTTP, this config + // simply allows apps being run over HTTPS to be accessed without error -- + // many of which may be using self-signed certs. transport.TLSClientConfig = &tls.Config{ MinVersion: tls.VersionTLS12, //nolint:gosec