MCPcopy Index your code
hub / github.com/coder/coder / HandleSubdomain

Method HandleSubdomain

coderd/workspaceapps/proxy.go:427–499  ·  view source on GitHub ↗

HandleSubdomain handles subdomain-based application proxy requests (aka. DevURLs in Coder V1). There are a lot of paths here: 1. If api.Hostname is not set then we pass on. 2. If we can't read the request hostname then we return a 400. 3. If the request hostname matches api.AccessURL then we pass o

(middlewares ...func(http.Handler) http.Handler)

Source from the content-addressed store, hash-verified

425// purposes regarding re-authentication and application proxy session
426// tokens.
427func (s *Server) HandleSubdomain(middlewares ...func(http.Handler) http.Handler) func(http.Handler) http.Handler {
428 return func(next http.Handler) http.Handler {
429 return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
430 ctx := r.Context()
431
432 // Step 1: Pass on if subdomain-based application proxying is not
433 // configured.
434 if s.Hostname == "" || s.HostnameRegex == nil {
435 next.ServeHTTP(rw, r)
436 return
437 }
438
439 // Step 2: Get the request Host.
440 host := httpmw.EffectiveHost(s.RealIPConfig, r)
441 if host == "" {
442 if r.URL.Path == "/derp" {
443 // The /derp endpoint is used by wireguard clients to tunnel
444 // through coderd. For some reason these requests don't set
445 // a Host header properly sometimes in tests (no idea how),
446 // which causes this path to get hit.
447 next.ServeHTTP(rw, r)
448 return
449 }
450
451 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
452 Message: "Could not determine request Host.",
453 })
454 return
455 }
456
457 // Steps 3-6: Parse application from subdomain.
458 app, ok := s.parseHostname(rw, r, next, host)
459 if !ok {
460 return
461 }
462
463 if !s.handleAPIKeySmuggling(rw, r, AccessMethodSubdomain) {
464 return
465 }
466
467 // Generate a signed token for the request.
468 token, ok := ResolveRequest(rw, r, ResolveRequestOptions{
469 Logger: s.Logger,
470 Cookies: s.cookies,
471 CookieCfg: s.CookiesConfig,
472 SignedTokenProvider: s.SignedTokenProvider,
473 DashboardURL: s.DashboardURL,
474 PathAppBaseURL: s.AccessURL,
475 AppHostname: s.Hostname,
476 AppRequest: Request{
477 AccessMethod: AccessMethodSubdomain,
478 BasePath: "/",
479 Prefix: app.Prefix,
480 UsernameOrID: app.Username,
481 WorkspaceNameOrID: app.WorkspaceName,
482 AgentNameOrID: app.AgentName,
483 AppSlugOrPort: app.AppSlugOrPort,
484 },

Callers 3

NewFunction · 0.80
NewFunction · 0.80

Calls 11

parseHostnameMethod · 0.95
handleAPIKeySmugglingMethod · 0.95
determineCORSBehaviorMethod · 0.95
proxyWorkspaceAppMethod · 0.95
EffectiveHostFunction · 0.92
WriteFunction · 0.92
ResolveRequestFunction · 0.85
WithContextMethod · 0.80
ContextMethod · 0.65
ServeHTTPMethod · 0.45
HandlerMethod · 0.45