@@ -4,11 +4,14 @@ import (
4
4
"bufio"
5
5
"context"
6
6
"crypto/tls"
7
+ "fmt"
7
8
"net"
8
9
"net/http"
9
10
"net/http/httputil"
10
11
"net/netip"
11
12
"net/url"
13
+ "strconv"
14
+ "strings"
12
15
"sync"
13
16
"sync/atomic"
14
17
"time"
@@ -23,6 +26,8 @@ import (
23
26
"cdr.dev/slog"
24
27
"github.com/coder/coder/v2/coderd/tracing"
25
28
"github.com/coder/coder/v2/coderd/workspaceapps"
29
+ "github.com/coder/coder/v2/coderd/workspaceapps/appurl"
30
+ "github.com/coder/coder/v2/codersdk"
26
31
"github.com/coder/coder/v2/codersdk/workspacesdk"
27
32
"github.com/coder/coder/v2/site"
28
33
"github.com/coder/coder/v2/tailnet"
@@ -351,13 +356,49 @@ func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID u
351
356
tgt .Host = net .JoinHostPort (tailnet .IPFromUUID (agentID ).String (), port )
352
357
353
358
proxy := httputil .NewSingleHostReverseProxy (& tgt )
354
- proxy .ErrorHandler = func (w http.ResponseWriter , r * http.Request , err error ) {
359
+ proxy .ErrorHandler = func (w http.ResponseWriter , r * http.Request , theErr error ) {
360
+ var (
361
+ switchProtoScheme codersdk.WorkspaceAgentPortShareProtocol
362
+ switchProtoLink = ""
363
+ )
364
+ au , err := appurl .ParseSubdomainAppURL (tgt .String ())
365
+ if err != nil {
366
+ site .RenderStaticErrorPage (w , r , site.ErrorPageData {
367
+ Status : http .StatusBadGateway ,
368
+ Title : "Bad Gateway" ,
369
+ Description : "Failed to proxy request to application: " + err .Error (),
370
+ RetryEnabled : true ,
371
+ DashboardURL : dashboardURL .String (),
372
+ })
373
+ return
374
+ }
375
+ if strings .HasSuffix (au .AppSlugOrPort , "s" ) {
376
+ p := strings .TrimSuffix (au .AppSlugOrPort , "s" )
377
+ _ , err = strconv .ParseInt (p , 10 , 64 )
378
+ if err == nil {
379
+ au .AppSlugOrPort = p
380
+ switchProtoLink = au .String ()
381
+ switchProtoScheme = codersdk .WorkspaceAgentPortShareProtocolHTTP
382
+ }
383
+ } else {
384
+ au .AppSlugOrPort += "s"
385
+ switchProtoLink = au .String ()
386
+ switchProtoScheme = codersdk .WorkspaceAgentPortShareProtocolHTTPS
387
+ }
388
+
389
+ desc := "Failed to proxy request to application: " + theErr .Error ()
390
+ if strings .Contains (theErr .Error (), "tls:" ) {
391
+ desc = fmt .Sprintf ("This error seems to be due to a protocol mistake, please try switching to %s. \n %s" , switchProtoScheme , theErr .Error ())
392
+ }
393
+
355
394
site .RenderStaticErrorPage (w , r , site.ErrorPageData {
356
- Status : http .StatusBadGateway ,
357
- Title : "Bad Gateway" ,
358
- Description : "Failed to proxy request to application: " + err .Error (),
359
- RetryEnabled : true ,
360
- DashboardURL : dashboardURL .String (),
395
+ Status : http .StatusBadGateway ,
396
+ Title : "Bad Gateway" ,
397
+ Description : desc ,
398
+ RetryEnabled : true ,
399
+ DashboardURL : dashboardURL .String (),
400
+ SwitchProtocolLink : switchProtoLink ,
401
+ SwitchProtocolTarget : switchProtoScheme ,
361
402
})
362
403
}
363
404
proxy .Director = s .director (agentID , proxy .Director )
0 commit comments