diff --git a/src/runtime/pkg/kata-monitor/pprof.go b/src/runtime/pkg/kata-monitor/pprof.go
index 5dac2da03c..62ed70c2e7 100644
--- a/src/runtime/pkg/kata-monitor/pprof.go
+++ b/src/runtime/pkg/kata-monitor/pprof.go
@@ -10,6 +10,8 @@ import (
"io"
"net"
"net/http"
+ "regexp"
+ "strings"
cdshim "github.com/containerd/containerd/runtime/v2/shim"
@@ -33,7 +35,13 @@ func (km *KataMonitor) composeSocketAddress(r *http.Request) (string, error) {
return shim.SocketAddress(sandbox), nil
}
-func (km *KataMonitor) proxyRequest(w http.ResponseWriter, r *http.Request) {
+func (km *KataMonitor) proxyRequest(w http.ResponseWriter, r *http.Request,
+ proxyResponse func(req *http.Request, w io.Writer, r io.Reader) error) {
+
+ if proxyResponse == nil {
+ proxyResponse = copyResponse
+ }
+
w.Header().Set("X-Content-Type-Options", "nosniff")
socketAddress, err := km.composeSocketAddress(r)
@@ -73,38 +81,68 @@ func (km *KataMonitor) proxyRequest(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Disposition", contentDisposition)
}
- io.Copy(w, output)
+ err = proxyResponse(r, w, output)
+ if err != nil {
+ monitorLog.WithError(err).Errorf("failed proxying %s from %s", uri, socketAddress)
+ serveError(w, http.StatusInternalServerError, "error retrieving resource")
+ }
}
// ExpvarHandler handles other `/debug/vars` requests
func (km *KataMonitor) ExpvarHandler(w http.ResponseWriter, r *http.Request) {
- km.proxyRequest(w, r)
+ km.proxyRequest(w, r, nil)
}
// PprofIndex handles other `/debug/pprof/` requests
func (km *KataMonitor) PprofIndex(w http.ResponseWriter, r *http.Request) {
- km.proxyRequest(w, r)
+ if len(strings.TrimPrefix(r.URL.Path, "/debug/pprof/")) == 0 {
+ km.proxyRequest(w, r, copyResponseAddingSandboxIdToHref)
+ } else {
+ km.proxyRequest(w, r, nil)
+ }
}
// PprofCmdline handles other `/debug/cmdline` requests
func (km *KataMonitor) PprofCmdline(w http.ResponseWriter, r *http.Request) {
- km.proxyRequest(w, r)
+ km.proxyRequest(w, r, nil)
}
// PprofProfile handles other `/debug/profile` requests
func (km *KataMonitor) PprofProfile(w http.ResponseWriter, r *http.Request) {
- km.proxyRequest(w, r)
+ km.proxyRequest(w, r, nil)
}
// PprofSymbol handles other `/debug/symbol` requests
func (km *KataMonitor) PprofSymbol(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
- km.proxyRequest(w, r)
+ km.proxyRequest(w, r, nil)
}
// PprofTrace handles other `/debug/trace` requests
func (km *KataMonitor) PprofTrace(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Content-Disposition", `attachment; filename="trace"`)
- km.proxyRequest(w, r)
+ km.proxyRequest(w, r, nil)
+}
+
+func copyResponse(req *http.Request, w io.Writer, r io.Reader) error {
+ _, err := io.Copy(w, r)
+ return err
+}
+
+func copyResponseAddingSandboxIdToHref(req *http.Request, w io.Writer, r io.Reader) error {
+ sb, err := getSandboxIDFromReq(req)
+ if err != nil {
+ monitorLog.WithError(err).Warning("missing sandbox query in pprof url")
+ return copyResponse(req, w, r)
+ }
+ buf, err := io.ReadAll(r)
+ if err != nil {
+ return err
+ }
+
+ re := regexp.MustCompile(``)
+ outHtml := re.ReplaceAllString(string(buf), fmt.Sprintf("", sb))
+ w.Write([]byte(outHtml))
+ return nil
}
diff --git a/src/runtime/pkg/kata-monitor/pprof_test.go b/src/runtime/pkg/kata-monitor/pprof_test.go
new file mode 100644
index 0000000000..e02dc00b12
--- /dev/null
+++ b/src/runtime/pkg/kata-monitor/pprof_test.go
@@ -0,0 +1,117 @@
+// Copyright (c) 2022 Red Hat Inc.
+//
+// SPDX-License-Identifier: Apache-2.0
+//
+
+package katamonitor
+
+import (
+ "bytes"
+ "net/http"
+ "net/url"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestCopyResponseAddingSandboxIdToHref(t *testing.T) {
+ assert := assert.New(t)
+
+ htmlIn := strings.NewReader(`
+
+
+
+
+Types of profiles available:
+
Count | Profile | +
27 | allocs |
0 | block |
0 | cmdline |
39 | goroutine |
27 | heap |
0 | mutex |
0 | profile |
10 | threadcreate |
0 | trace |
+Profile Descriptions: +
Count | Profile | +
27 | allocs |
0 | block |
0 | cmdline |
39 | goroutine |
27 | heap |
0 | mutex |
0 | profile |
10 | threadcreate |
0 | trace |
+Profile Descriptions: +