NewWorkspaceProxyReplica will configure a wsproxy.Server with the given options. The new wsproxy replica will register itself with the given coderd.API instance. If a token is not provided, a new workspace proxy region is created using the owner client. If a token is provided, the proxy will become
(t *testing.T, coderdAPI *coderd.API, owner *codersdk.Client, options *ProxyOptions)
| 65 | // owner client. If a token is provided, the proxy will become a replica of the |
| 66 | // existing proxy region. |
| 67 | func NewWorkspaceProxyReplica(t *testing.T, coderdAPI *coderd.API, owner *codersdk.Client, options *ProxyOptions) WorkspaceProxy { |
| 68 | t.Helper() |
| 69 | |
| 70 | ctx, cancelFunc := context.WithCancel(context.Background()) |
| 71 | t.Cleanup(cancelFunc) |
| 72 | |
| 73 | if options == nil { |
| 74 | options = &ProxyOptions{} |
| 75 | } |
| 76 | |
| 77 | // HTTP Server. We have to start this once to get the access URL to start |
| 78 | // the workspace proxy with. The workspace proxy has the handler, so the |
| 79 | // http server will start with a 503 until the proxy is started. |
| 80 | var mutex sync.RWMutex |
| 81 | var handler http.Handler |
| 82 | srv := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
| 83 | mutex.RLock() |
| 84 | defer mutex.RUnlock() |
| 85 | if handler == nil { |
| 86 | http.Error(w, "handler not set", http.StatusServiceUnavailable) |
| 87 | return |
| 88 | } |
| 89 | |
| 90 | handler.ServeHTTP(w, r) |
| 91 | })) |
| 92 | srv.Config.BaseContext = func(_ net.Listener) context.Context { |
| 93 | return ctx |
| 94 | } |
| 95 | if options.TLSCertificates != nil { |
| 96 | srv.TLS = &tls.Config{ |
| 97 | Certificates: options.TLSCertificates, |
| 98 | MinVersion: tls.VersionTLS12, |
| 99 | } |
| 100 | srv.StartTLS() |
| 101 | } else { |
| 102 | srv.Start() |
| 103 | } |
| 104 | t.Cleanup(srv.Close) |
| 105 | |
| 106 | tcpAddr, ok := srv.Listener.Addr().(*net.TCPAddr) |
| 107 | require.True(t, ok) |
| 108 | |
| 109 | serverURL, err := url.Parse(srv.URL) |
| 110 | require.NoError(t, err) |
| 111 | |
| 112 | serverURL.Host = fmt.Sprintf("127.0.0.1:%d", tcpAddr.Port) |
| 113 | |
| 114 | accessURL := options.ProxyURL |
| 115 | if accessURL == nil { |
| 116 | accessURL = serverURL |
| 117 | } |
| 118 | |
| 119 | var appHostnameRegex *regexp.Regexp |
| 120 | if options.AppHostname != "" { |
| 121 | var err error |
| 122 | appHostnameRegex, err = appurl.CompileHostnamePattern(options.AppHostname) |
| 123 | require.NoError(t, err) |
| 124 | } |