fix(api): increase Docker agent report size limit from 512KB to 2MB

Users with 100+ containers were hitting the payload size limit,
causing "Failed to decode request body" 400 errors. This aligns
the Docker agent limit with the Kubernetes agent limit (2MB).

Fixes #1104
This commit is contained in:
rcourtman
2026-01-14 12:20:39 +00:00
parent 038b57ee43
commit 3e74e689cd
3 changed files with 60 additions and 44 deletions
+20 -11
View File
@@ -444,27 +444,36 @@ func (h *AIHandler) HandleOpenCodeUI(w http.ResponseWriter, r *http.Request) {
}
}
// Rewrite asset paths in HTML responses
// Rewrite asset paths in HTML and CSS responses
// OpenCode uses absolute paths like /assets/... which need to be /opencode/assets/...
contentType := resp.Header.Get("Content-Type")
if strings.Contains(contentType, "text/html") && resp.Body != nil {
if resp.Body != nil && (strings.Contains(contentType, "text/html") || strings.Contains(contentType, "text/css")) {
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
return err
}
// Rewrite absolute paths to include /opencode/ prefix
html := string(body)
// Rewrite src="/..." and href="/..." to src="/opencode/..." and href="/opencode/..."
// Be careful not to rewrite already-prefixed paths or external URLs
html = strings.ReplaceAll(html, `src="/`, `src="/opencode/`)
html = strings.ReplaceAll(html, `href="/`, `href="/opencode/`)
content := string(body)
if strings.Contains(contentType, "text/html") {
// Rewrite src="/..." and href="/..." to src="/opencode/..." and href="/opencode/..."
// Be careful not to rewrite already-prefixed paths or external URLs
content = strings.ReplaceAll(content, `src="/`, `src="/opencode/`)
content = strings.ReplaceAll(content, `href="/`, `href="/opencode/`)
}
if strings.Contains(contentType, "text/css") {
// Rewrite url(/...) and url("/...") and url('/...') in CSS for fonts and other assets
content = strings.ReplaceAll(content, `url(/`, `url(/opencode/`)
content = strings.ReplaceAll(content, `url("/`, `url("/opencode/`)
content = strings.ReplaceAll(content, `url('/`, `url('/opencode/`)
}
// Update response body
resp.Body = io.NopCloser(strings.NewReader(html))
resp.ContentLength = int64(len(html))
resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(html)))
resp.Body = io.NopCloser(strings.NewReader(content))
resp.ContentLength = int64(len(content))
resp.Header.Set("Content-Length", fmt.Sprintf("%d", len(content)))
}
return nil
+3 -2
View File
@@ -72,8 +72,9 @@ func (h *DockerAgentHandlers) HandleReport(w http.ResponseWriter, r *http.Reques
return
}
// Limit request body to 512KB to prevent memory exhaustion
r.Body = http.MaxBytesReader(w, r.Body, 512*1024)
// Limit request body to 2MB to prevent memory exhaustion
// (512KB was too small for users with 100+ containers)
r.Body = http.MaxBytesReader(w, r.Body, 2*1024*1024)
defer r.Body.Close()
var report agentsdocker.Report
+37 -31
View File
@@ -1412,24 +1412,29 @@ func (r *Router) setupRoutes() {
// OpenCode API proxy - these routes are used by OpenCode's frontend
// When embedded in iframe, OpenCode's JS makes requests to window.location.origin
// We proxy these to OpenCode's backend so the iframe works correctly
openCodeAPIPaths := []string{
"/global/",
"/session/",
"/tui/",
"/config/",
"/file/",
"/find/",
"/instance/",
"/mcp/",
"/permission/",
"/project/",
"/provider/",
"/pty/",
"/question/",
"/experimental/",
// NOTE: Register both /path and /path/ because Go's ServeMux treats them differently:
// - /path/ matches any path starting with /path/
// - /path (no trailing slash) matches exactly /path
openCodeAPIBases := []string{
"/global",
"/session",
"/tui",
"/config",
"/file",
"/find",
"/instance",
"/mcp",
"/permission",
"/project",
"/provider",
"/pty",
"/question",
"/experimental",
}
for _, path := range openCodeAPIPaths {
r.mux.HandleFunc(path, RequireAuth(r.config, r.aiHandler.HandleOpenCodeAPI))
for _, base := range openCodeAPIBases {
// Register both exact match and prefix match
r.mux.HandleFunc(base, RequireAuth(r.config, r.aiHandler.HandleOpenCodeAPI))
r.mux.HandleFunc(base+"/", RequireAuth(r.config, r.aiHandler.HandleOpenCodeAPI))
}
// Agent WebSocket for AI command execution
@@ -2449,20 +2454,21 @@ func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
strings.HasPrefix(req.URL.Path, "/download/") ||
strings.HasPrefix(req.URL.Path, "/opencode") ||
// OpenCode API paths - proxied to OpenCode backend for iframe embedding
strings.HasPrefix(req.URL.Path, "/global/") ||
strings.HasPrefix(req.URL.Path, "/session/") ||
strings.HasPrefix(req.URL.Path, "/tui/") ||
strings.HasPrefix(req.URL.Path, "/config/") ||
strings.HasPrefix(req.URL.Path, "/file/") ||
strings.HasPrefix(req.URL.Path, "/find/") ||
strings.HasPrefix(req.URL.Path, "/instance/") ||
strings.HasPrefix(req.URL.Path, "/mcp/") ||
strings.HasPrefix(req.URL.Path, "/permission/") ||
strings.HasPrefix(req.URL.Path, "/project/") ||
strings.HasPrefix(req.URL.Path, "/provider/") ||
strings.HasPrefix(req.URL.Path, "/pty/") ||
strings.HasPrefix(req.URL.Path, "/question/") ||
strings.HasPrefix(req.URL.Path, "/experimental/") ||
// Note: Use "/path" (not "/path/") to match both exact and prefix paths
strings.HasPrefix(req.URL.Path, "/global") ||
strings.HasPrefix(req.URL.Path, "/session") ||
strings.HasPrefix(req.URL.Path, "/tui") ||
strings.HasPrefix(req.URL.Path, "/config") ||
strings.HasPrefix(req.URL.Path, "/file") ||
strings.HasPrefix(req.URL.Path, "/find") ||
strings.HasPrefix(req.URL.Path, "/instance") ||
strings.HasPrefix(req.URL.Path, "/mcp") ||
strings.HasPrefix(req.URL.Path, "/permission") ||
strings.HasPrefix(req.URL.Path, "/project") ||
strings.HasPrefix(req.URL.Path, "/provider") ||
strings.HasPrefix(req.URL.Path, "/pty") ||
strings.HasPrefix(req.URL.Path, "/question") ||
strings.HasPrefix(req.URL.Path, "/experimental") ||
req.URL.Path == "/simple-stats" ||
req.URL.Path == "/install-docker-agent.sh" ||
req.URL.Path == "/install-container-agent.sh" ||