fix(coderd/aibridged): ignore empty response body writes (#29728)

This commit is contained in:
Michael Suchacz
2026-09-22 19:02:06 +02:00
committed by GitHub
parent 17abc3f093
commit 926e4afc39
2 changed files with 50 additions and 0 deletions
+3
View File
@@ -176,6 +176,9 @@ func (w *pipeResponseWriter) Write(p []byte) (int, error) {
// net/http semantics: an implicit 200 OK on first Write if the handler
// did not call WriteHeader explicitly.
w.WriteHeader(http.StatusOK)
if len(p) == 0 {
return 0, nil
}
return w.body.Write(p)
}
+47
View File
@@ -133,6 +133,53 @@ func TestInMemoryRoundTripper_PassesHeadersAndStatus(t *testing.T) {
require.Equal(t, `{"ok":true}`, string(body))
}
func TestInMemoryRoundTripper_EmptyWrites(t *testing.T) {
t.Parallel()
for _, payload := range [][]byte{nil, {}} {
t.Run(fmt.Sprintf("Nil=%t", payload == nil), func(t *testing.T) {
t.Parallel()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/event-stream")
for _, chunk := range []string{"data: first\n\n", "data: second\n\n", ""} {
for range 128 {
if _, err := w.Write(payload); err != nil {
return
}
}
if _, err := io.WriteString(w, chunk); err != nil {
return
}
}
})
rt, err := aibridged.NewTransportFactory(handler).TransportFor("openai", aibridge.SourceAgents)
require.NoError(t, err)
ctx := aibridge.WithDelegatedAPIKeyID(testutil.Context(t, testutil.WaitShort), "test-key-id")
req, err := http.NewRequestWithContext(ctx, http.MethodPost, "http://aibridge/v1/responses", nil)
require.NoError(t, err)
resp, err := rt.RoundTrip(req)
require.NoError(t, err)
defer resp.Body.Close()
require.Equal(t, http.StatusOK, resp.StatusCode)
require.Equal(t, "text/event-stream", resp.Header.Get("Content-Type"))
reader := bufio.NewReader(resp.Body)
for _, want := range []string{"data: first\n", "\n", "data: second\n", "\n"} {
line, err := reader.ReadString('\n')
require.NoError(t, err)
require.Equal(t, want, line)
}
line, err := reader.ReadString('\n')
require.ErrorIs(t, err, io.EOF)
require.Empty(t, line)
})
}
}
// Verify that response chunks become readable on the client side before the
// handler has finished writing. This is the property SSE/NDJSON streaming
// depends on.