package api import ( "bytes" _ "embed" "io" "net/http" "strconv" "strings" ) //go:embed scripts/inspector.js var inspectorScript string // stripIframeSecurityHeaders removes headers that prevent iframe embedding // or block injected inline scripts from running. func stripIframeSecurityHeaders(h http.Header) { h.Del("Content-Security-Policy") h.Del("Content-Security-Policy-Report-Only") h.Del("X-Frame-Options") } // injectInspectorScript inserts the inspector " pos := strings.LastIndex(strings.ToLower(s), "") if pos >= 0 { return []byte(s[:pos] + tag + s[pos:]) } return append(html, []byte(tag)...) } // injectScriptsIntoResponse modifies an HTML response in-place: strips // iframe-blocking headers and injects the inspector script. Assumes the // caller cleared the outbound Accept-Encoding header so net/http.Transport // auto-decompresses any upstream gzip before this runs. func injectScriptsIntoResponse(resp *http.Response) error { stripIframeSecurityHeaders(resp.Header) body, err := io.ReadAll(resp.Body) if closeErr := resp.Body.Close(); closeErr != nil && err == nil { err = closeErr } if err != nil { return err } modified := injectInspectorScript(body) resp.Body = io.NopCloser(bytes.NewReader(modified)) resp.Header.Del("Content-Encoding") resp.Header.Set("Content-Length", strconv.Itoa(len(modified))) resp.ContentLength = int64(len(modified)) return nil }