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

Method handleProcessOutput

agent/agentproc/api.go:152–217  ·  view source on GitHub ↗

handleProcessOutput returns the output of a process.

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

Source from the content-addressed store, hash-verified

150
151// handleProcessOutput returns the output of a process.
152func (api *API) handleProcessOutput(rw http.ResponseWriter, r *http.Request) {
153 ctx := r.Context()
154 logger := api.logger.With(agentchat.Fields(ctx)...)
155
156 id := chi.URLParam(r, "id")
157 proc, ok := api.manager.get(id)
158 if !ok {
159 httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
160 Message: fmt.Sprintf("Process %q not found.", id),
161 })
162 return
163 }
164
165 // Enforce chat ID isolation. If the request carries
166 // a chat context, only allow access to processes
167 // belonging to that chat.
168 if chatContext, ok := agentchat.FromContext(ctx); ok {
169 if proc.chatID != "" && proc.chatID != chatContext.ID.String() {
170 httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{
171 Message: fmt.Sprintf("Process %q not found.", id),
172 })
173 return
174 }
175 }
176
177 // Check for blocking mode via query params.
178 waitStr := r.URL.Query().Get("wait")
179 wantWait := waitStr == "true"
180
181 if wantWait {
182 // Extend the write deadline so the HTTP server's
183 // WriteTimeout does not kill the connection while
184 // we block.
185 rc := http.NewResponseController(rw)
186 // Add headroom beyond the wait timeout so there's time to
187 // write the response after the blocking wait completes.
188 if err := rc.SetWriteDeadline(time.Now().Add(maxWaitDuration + 30*time.Second)); err != nil {
189 logger.Error(ctx, "extend write deadline for blocking process output",
190 slog.Error(err),
191 )
192 }
193
194 // Cap the wait at maxWaitDuration regardless of
195 // client-supplied timeout.
196 waitCtx, waitCancel := context.WithTimeout(ctx, maxWaitDuration)
197 defer waitCancel()
198
199 _ = proc.waitForOutput(waitCtx)
200 // Fall through to read snapshot below.
201 }
202
203 // Read info before output to avoid a TOCTOU race. The exit
204 // goroutine completes all buffer writes (cmd.Wait) before
205 // setting running=false, so if info reports the process as
206 // exited, the subsequent output read is guaranteed to reflect
207 // the final buffer state.
208 info := proc.info()
209 output, truncated := proc.output()

Callers

nothing calls this directly

Calls 13

FieldsFunction · 0.92
WriteFunction · 0.92
FromContextFunction · 0.92
getMethod · 0.80
SetWriteDeadlineMethod · 0.80
waitForOutputMethod · 0.80
infoMethod · 0.80
outputMethod · 0.80
ContextMethod · 0.65
GetMethod · 0.65
AddMethod · 0.65
StringMethod · 0.45

Tested by

no test coverage detected