Skip to content

Commit d8620ea

Browse files
committed
it works
1 parent 6669d6d commit d8620ea

File tree

6 files changed

+49
-42
lines changed

6 files changed

+49
-42
lines changed

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,8 @@ endef
200200
# calling this manually.
201201
$(CODER_ALL_BINARIES): go.mod go.sum \
202202
$(GO_SRC_FILES) \
203-
$(shell find ./examples/templates)
203+
$(shell find ./examples/templates) \
204+
site/static/error.html
204205

205206
$(get-mode-os-arch-ext)
206207
if [[ "$$os" != "windows" ]] && [[ "$$ext" != "" ]]; then

coderd/tailnet.go

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"github.com/coder/coder/v2/coderd/tracing"
2727
"github.com/coder/coder/v2/coderd/workspaceapps"
2828
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
29-
"github.com/coder/coder/v2/codersdk"
3029
"github.com/coder/coder/v2/codersdk/workspacesdk"
3130
"github.com/coder/coder/v2/site"
3231
"github.com/coder/coder/v2/tailnet"
@@ -345,7 +344,7 @@ type ServerTailnet struct {
345344
totalConns *prometheus.CounterVec
346345
}
347346

348-
func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID, app appurl.ApplicationURL) *httputil.ReverseProxy {
347+
func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID, app appurl.ApplicationURL, wildcardHostname string) *httputil.ReverseProxy {
349348
// Rewrite the targetURL's Host to point to the agent's IP. This is
350349
// necessary because due to TCP connection caching, each agent needs to be
351350
// addressed invidivually. Otherwise, all connections get dialed as
@@ -356,31 +355,41 @@ func (s *ServerTailnet) ReverseProxy(targetURL, dashboardURL *url.URL, agentID u
356355

357356
proxy := httputil.NewSingleHostReverseProxy(&tgt)
358357
proxy.ErrorHandler = func(w http.ResponseWriter, r *http.Request, theErr error) {
359-
desc := "Failed to proxy request to application: " + theErr.Error()
360-
additional := ""
358+
var (
359+
desc = "Failed to proxy request to application: " + theErr.Error()
360+
additional = ""
361+
switchLink = ""
362+
switchTarget = ""
363+
)
361364

362365
if strings.Contains(theErr.Error(), "tls:") {
363366
// If the error is due to an HTTP/HTTPS mismatch, we can provide a
364367
// more helpful error message with redirect buttons.
368+
switchURL := url.URL{
369+
Scheme: dashboardURL.Scheme,
370+
}
365371
if app.IsPort() {
366-
if app.Protocol() == codersdk.WorkspaceAgentPortShareProtocolHTTPS {
367-
app.ChangePortProtocol(codersdk.WorkspaceAgentPortShareProtocolHTTP)
372+
if app.Protocol() == "https" {
373+
app.ChangePortProtocol("http")
368374
} else {
369-
app.ChangePortProtocol(codersdk.WorkspaceAgentPortShareProtocolHTTPS)
375+
app.ChangePortProtocol("https")
370376
}
371377

372-
additional += fmt.Sprintf("This error seems to be due to an app protocol mismatch, please try switching to %s.", app.Protocol())
378+
switchURL.Host = fmt.Sprintf("%s%s", app.String(), strings.TrimPrefix(wildcardHostname, "*"))
379+
switchLink = switchURL.String()
380+
switchTarget = app.Protocol()
381+
additional += fmt.Sprintf("This error seems to be due to an app protocol mismatch, try switching to %s.", strings.ToUpper(app.Protocol()))
373382
}
374383
}
375384

376385
site.RenderStaticErrorPage(w, r, site.ErrorPageData{
377386
Status: http.StatusBadGateway,
378-
Title: "Bad Gateway Dood",
387+
Title: "Bad Gateway",
379388
Description: desc,
380389
RetryEnabled: true,
381390
DashboardURL: dashboardURL.String(),
382-
SwitchProtocolLink: app.String(),
383-
SwitchProtocolTarget: string(app.Protocol()),
391+
SwitchProtocolLink: switchLink,
392+
SwitchProtocolTarget: strings.ToUpper(switchTarget),
384393
AdditionalInfo: additional,
385394
})
386395
}

coderd/workspaceapps/appurl/appurl.go

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88
"strconv"
99
"strings"
1010

11-
"github.com/coder/coder/v2/codersdk"
1211
"golang.org/x/xerrors"
1312
)
1413

@@ -90,6 +89,7 @@ func (a ApplicationURL) IsPort() bool {
9089
if strings.HasSuffix(a.AppSlugOrPort, "s") {
9190
trimmed := strings.TrimSuffix(a.AppSlugOrPort, "s")
9291
_, err := strconv.ParseInt(trimmed, 10, 64)
92+
//nolint:gosimple
9393
if err != nil {
9494
return false
9595
}
@@ -99,41 +99,45 @@ func (a ApplicationURL) IsPort() bool {
9999

100100
// check if port at all
101101
_, err := strconv.ParseInt(a.AppSlugOrPort, 10, 64)
102+
//nolint:gosimple
102103
if err != nil {
103104
return false
104105
}
105106

106107
return true
107-
108108
}
109109

110-
func (a ApplicationURL) Protocol() codersdk.WorkspaceAgentPortShareProtocol {
110+
func (a ApplicationURL) Protocol() string {
111111
if strings.HasSuffix(a.AppSlugOrPort, "s") {
112112
trimmed := strings.TrimSuffix(a.AppSlugOrPort, "s")
113113
_, err := strconv.ParseInt(trimmed, 10, 64)
114114
if err == nil {
115-
return codersdk.WorkspaceAgentPortShareProtocolHTTPS
115+
return "https"
116116
}
117117
}
118118

119-
return codersdk.WorkspaceAgentPortShareProtocolHTTP
119+
return "http"
120120
}
121121

122-
func (a ApplicationURL) ChangePortProtocol(target codersdk.WorkspaceAgentPortShareProtocol) error {
123-
if target == codersdk.WorkspaceAgentPortShareProtocolHTTP {
124-
if strings.HasSuffix(a.AppSlugOrPort, "s") {
125-
trimmed := strings.TrimSuffix(a.AppSlugOrPort, "s")
126-
_, err := strconv.ParseInt(trimmed, 10, 64)
127-
if err != nil {
128-
return xerrors.Errorf("invalid port: %s", a.AppSlugOrPort)
129-
}
122+
func (a *ApplicationURL) ChangePortProtocol(target string) {
123+
if target == "http" {
124+
if a.Protocol() == "http" {
125+
return
126+
}
127+
trimmed := strings.TrimSuffix(a.AppSlugOrPort, "s")
128+
_, err := strconv.ParseInt(trimmed, 10, 64)
129+
if err == nil {
130130
a.AppSlugOrPort = trimmed
131131
}
132+
} else {
133+
if a.Protocol() == "https" {
134+
return
135+
}
136+
_, err := strconv.ParseInt(a.AppSlugOrPort, 10, 64)
137+
if err == nil {
138+
a.AppSlugOrPort = fmt.Sprintf("%s%s", a.AppSlugOrPort, "s")
139+
}
132140
}
133-
134-
a.AppSlugOrPort = fmt.Sprintf("%s%s", a.AppSlugOrPort, "s")
135-
136-
return nil
137141
}
138142

139143
// ParseSubdomainAppURL parses an ApplicationURL from the given subdomain. If

coderd/workspaceapps/proxy.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ var nonCanonicalHeaders = map[string]string{
6666
type AgentProvider interface {
6767
// ReverseProxy returns an httputil.ReverseProxy for proxying HTTP requests
6868
// to the specified agent.
69-
ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID, app appurl.ApplicationURL) *httputil.ReverseProxy
69+
ReverseProxy(targetURL, dashboardURL *url.URL, agentID uuid.UUID, app appurl.ApplicationURL, wildcardHost string) *httputil.ReverseProxy
7070

7171
// AgentConn returns a new connection to the specified agent.
7272
AgentConn(ctx context.Context, agentID uuid.UUID) (_ *workspacesdk.AgentConn, release func(), _ error)
@@ -545,16 +545,9 @@ func (s *Server) proxyWorkspaceApp(rw http.ResponseWriter, r *http.Request, appT
545545

546546
r.URL.Path = path
547547
appURL.RawQuery = ""
548+
appURL.Scheme = app.Protocol()
548549

549-
appURL.Scheme = "http"
550-
if strings.HasSuffix(app.AppSlugOrPort, "s") {
551-
_, err = strconv.ParseInt(strings.TrimSuffix(app.AppSlugOrPort, "s"), 10, 64)
552-
if err == nil {
553-
appURL.Scheme = "https"
554-
}
555-
}
556-
557-
proxy := s.AgentProvider.ReverseProxy(appURL, s.DashboardURL, appToken.AgentID, app)
550+
proxy := s.AgentProvider.ReverseProxy(appURL, s.DashboardURL, appToken.AgentID, app, s.Hostname)
558551

559552
proxy.ModifyResponse = func(r *http.Response) error {
560553
r.Header.Del(httpmw.AccessControlAllowOriginHeader)

site/site.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -793,7 +793,7 @@ type ErrorPageData struct {
793793
DashboardURL string
794794
Warnings []string
795795
SwitchProtocolLink string
796-
SwitchProtocolTarget codersdk.WorkspaceAgentPortShareProtocol
796+
SwitchProtocolTarget string
797797
AdditionalInfo string
798798

799799
RenderDescriptionMarkdown bool

site/static/error.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
.container {
3434
--side-padding: 24px;
3535
width: 100%;
36-
max-width: calc(320px + var(--side-padding) * 2);
36+
max-width: calc(460px + var(--side-padding) * 2);
3737
padding: 0 var(--side-padding);
3838
text-align: center;
3939
}
@@ -203,7 +203,7 @@ <h3>Warnings</h3>
203203
<button onclick="window.location.reload()">Retry</button>
204204
{{ end }}
205205
{{- if .Error.SwitchProtocolLink }}
206-
<a href="{{ .Error.SwitchProtocolLink }}">Switch to {{ .ErrorSwitchProtocolTarget }}</a>
206+
<a href="{{ .Error.SwitchProtocolLink }}">Switch to {{ .Error.SwitchProtocolTarget }}</a>
207207
{{ end }}
208208
<a href="{{ .Error.DashboardURL }}">Back to site</a>
209209
</div>

0 commit comments

Comments
 (0)