Skip to content

Commit

Permalink
system service --log-level=trace: support hijack
Browse files Browse the repository at this point in the history
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 containers#17749

Signed-off-by: Paul Holzinger <[email protected]>
  • Loading branch information
Luap99 committed Mar 14, 2023
1 parent 519cfa8 commit 7d8d3e8
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
25 changes: 25 additions & 0 deletions pkg/api/server/handler_logging.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package server

import (
"bufio"
"errors"
"io"
"net"
"net/http"
"time"

Expand Down Expand Up @@ -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) {
Expand Down
19 changes: 19 additions & 0 deletions test/system/251-system-service.bats
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 7d8d3e8

Please sign in to comment.