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

Method workspaceAgentPTY

coderd/workspaceapps/proxy.go:705–804  ·  view source on GitHub ↗

workspaceAgentPTY spawns a PTY and pipes it over a WebSocket. This is used for the web terminal. @Summary Open PTY to workspace agent @ID open-pty-to-workspace-agent @Security CoderSessionToken @Tags Agents @Param workspaceagent path string true "Workspace agent ID" format(uuid) @Success 101 @Route

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

703// @Success 101
704// @Router /api/v2/workspaceagents/{workspaceagent}/pty [get]
705func (s *Server) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) {
706 ctx, cancel := context.WithCancel(r.Context())
707 defer cancel()
708
709 s.websocketWaitMutex.Lock()
710 s.websocketWaitGroup.Add(1)
711 s.websocketWaitMutex.Unlock()
712 defer s.websocketWaitGroup.Done()
713
714 appToken, ok := ResolveRequest(rw, r, ResolveRequestOptions{
715 Logger: s.Logger,
716 Cookies: s.cookies,
717 CookieCfg: s.CookiesConfig,
718 SignedTokenProvider: s.SignedTokenProvider,
719 DashboardURL: s.DashboardURL,
720 PathAppBaseURL: s.AccessURL,
721 AppHostname: s.Hostname,
722 AppRequest: Request{
723 AccessMethod: AccessMethodTerminal,
724 BasePath: r.URL.Path,
725 AgentNameOrID: chi.URLParam(r, "workspaceagent"),
726 },
727 AppPath: "",
728 AppQuery: "",
729 })
730 if !ok {
731 return
732 }
733 log := s.Logger.With(slog.F("agent_id", appToken.AgentID))
734 log.Debug(ctx, "resolved PTY request")
735
736 values := r.URL.Query()
737 parser := httpapi.NewQueryParamParser()
738 reconnect := parser.RequiredNotEmpty("reconnect").UUID(values, uuid.New(), "reconnect")
739 height := parser.UInt(values, 80, "height")
740 width := parser.UInt(values, 80, "width")
741 container := parser.String(values, "", "container")
742 containerUser := parser.String(values, "", "container_user")
743 backendType := parser.String(values, "", "backend_type")
744 if len(parser.Errors) > 0 {
745 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
746 Message: "Invalid query parameters.",
747 Validations: parser.Errors,
748 })
749 return
750 }
751
752 conn, err := websocket.Accept(rw, r, &websocket.AcceptOptions{
753 CompressionMode: websocket.CompressionDisabled,
754 // Always allow websockets from the primary dashboard URL.
755 // Terminals are opened there and connect to the proxy.
756 OriginPatterns: []string{
757 s.DashboardURL.Host,
758 s.AccessURL.Host,
759 },
760 })
761 if err != nil {
762 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{

Callers

nothing calls this directly

Calls 15

RequiredNotEmptyMethod · 0.95
UIntMethod · 0.95
StringMethod · 0.95
collectStatsMethod · 0.95
NewQueryParamParserFunction · 0.92
WriteFunction · 0.92
HeartbeatCloseFunction · 0.92
WebsocketCloseSprintfFunction · 0.92
NowFunction · 0.92
BicopyFunction · 0.92
ResolveRequestFunction · 0.85

Tested by

no test coverage detected