16 KiB readErrorBodyForLog reads resp.Body for diagnostic logging and restores it with an equivalent reader, so the proxy still forwards the body downstream and the response dumper can read it again. The returned string is truncated to maxLoggedErrorBodyBytes; the restored body is always complete.
(resp *http.Response, logger slog.Logger)
| 1114 | // string is truncated to maxLoggedErrorBodyBytes; the restored body is |
| 1115 | // always complete. |
| 1116 | func (s *Server) readErrorBodyForLog(resp *http.Response, logger slog.Logger) string { |
| 1117 | if resp.Body == nil { |
| 1118 | return "" |
| 1119 | } |
| 1120 | body, err := io.ReadAll(resp.Body) |
| 1121 | _ = resp.Body.Close() |
| 1122 | // Restore the full body even on a read error: the proxy and dumper |
| 1123 | // downstream still expect a readable body, and a partial body is |
| 1124 | // better than a nil one. |
| 1125 | resp.Body = io.NopCloser(bytes.NewReader(body)) |
| 1126 | if err != nil { |
| 1127 | logger.Warn(s.ctx, "failed to read aibridged error response body", slog.Error(err)) |
| 1128 | } |
| 1129 | if len(body) > maxLoggedErrorBodyBytes { |
| 1130 | return string(body[:maxLoggedErrorBodyBytes]) + "...(truncated)" |
| 1131 | } |
| 1132 | return string(body) |
| 1133 | } |
| 1134 | |
| 1135 | // Handler returns an HTTP handler for the AI Bridge Proxy's HTTP endpoints. |
| 1136 | // This is separate from the proxy server itself and is used by coderd to |