From bd65bf2ed150f9ce9644cc252ab82f35a0c87885 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Tue, 14 Mar 2023 14:15:46 +0100 Subject: [PATCH] system service --log-level=trace: support hijack When the service is running with trace log level it wraps the `http.ResponseWriter` to log extra information. The problem is that the new type does not keep all the functions from the embedded type. Instead we have to implement them ourselves, however only Write() was implemented. Thus `Hijack()`could not be called on the writer. To prevent these issues we would implement all the interfaces that the inner type supports (Header, WriteHeader, Flush, Hijack). Fixes #17749 Signed-off-by: Paul Holzinger --- pkg/api/server/handler_logging.go | 25 +++++++++++++++++++++++++ test/system/251-system-service.bats | 19 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/pkg/api/server/handler_logging.go b/pkg/api/server/handler_logging.go index 38ee8321c1..2f62a28fd3 100644 --- a/pkg/api/server/handler_logging.go +++ b/pkg/api/server/handler_logging.go @@ -1,7 +1,10 @@ package server import ( + "bufio" + "errors" "io" + "net" "net/http" "time" @@ -33,6 +36,28 @@ func (l responseWriter) Write(b []byte) (int, error) { return l.ResponseWriter.Write(b) } +func (l responseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if wrapped, ok := l.ResponseWriter.(http.Hijacker); ok { + return wrapped.Hijack() + } + + return nil, nil, errors.New("ResponseWriter does not support hijacking") +} + +func (l responseWriter) Header() http.Header { + return l.ResponseWriter.Header() +} + +func (l responseWriter) WriteHeader(statusCode int) { + l.ResponseWriter.WriteHeader(statusCode) +} + +func (l responseWriter) Flush() { + if wrapped, ok := l.ResponseWriter.(http.Flusher); ok { + wrapped.Flush() + } +} + func loggingHandler() mux.MiddlewareFunc { return func(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { diff --git a/test/system/251-system-service.bats b/test/system/251-system-service.bats index b4bc6ceaad..7a772e2ef4 100644 --- a/test/system/251-system-service.bats +++ b/test/system/251-system-service.bats @@ -69,3 +69,22 @@ function teardown() { systemctl stop $SERVICE_NAME } + +# Regression test for https://github.com/containers/podman/issues/17749 +@test "podman-system-service --log-level=trace should be able to hijack" { + skip_if_remote "podman system service unavailable over remote" + + port=$(random_free_port) + URL=tcp://127.0.0.1:$port + + systemd-run --unit=$SERVICE_NAME $PODMAN --log-level=trace system service $URL --time=0 + wait_for_port 127.0.0.1 $port + + out=o-$(random_string) + cname=c-$(random_string) + run_podman --url $URL run --name $cname $IMAGE echo $out + assert "$output" == "$out" "service is able to hijack and stream output back" + + run_podman --url $URL rm $cname + systemctl stop $SERVICE_NAME +}