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 <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2023-03-14 14:15:46 +01:00
parent 519cfa81f6
commit 7d8d3e810f
2 changed files with 44 additions and 0 deletions

View File

@@ -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) {

View File

@@ -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
}