From 12b2012fd10b625337af0170168ef49115f09ee6 Mon Sep 17 00:00:00 2001 From: Paul Holzinger Date: Thu, 15 Dec 2022 18:32:55 +0100 Subject: [PATCH] libpod: fix header length in http attach with logs When we read logs there can be full or partial lines, when it is full we need to append a newline, thus the message length must be incremented by one. Fixes #16856 Signed-off-by: Paul Holzinger --- libpod/oci_conmon_common.go | 4 +++ .../python/rest_api/test_v2_0_0_container.py | 33 +++++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go index b82d2e7638ad..b4740842eadf 100644 --- a/libpod/oci_conmon_common.go +++ b/libpod/oci_conmon_common.go @@ -594,6 +594,10 @@ func (r *ConmonOCIRuntime) HTTPAttach(ctr *Container, req *http.Request, w http. device := logLine.Device var header []byte headerLen := uint32(len(logLine.Msg)) + if !logLine.Partial() { + // we append and extra newline in this case so we need to increment the len as well + headerLen++ + } logSize += len(logLine.Msg) switch strings.ToLower(device) { case "stdin": diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py index 25596a9b7bbb..3a6a077e691f 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_container.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py @@ -131,9 +131,36 @@ def test_resize(self): self.assertEqual(r.text, "", r.text) def test_attach(self): - self.skipTest("FIXME: Test timeouts") - r = requests.post(self.uri(self.resolve_container("/containers/{}/attach?logs=true")), timeout=5) - self.assertIn(r.status_code, (101, 500), r.text) + r = requests.post( + self.podman_url + "/v1.40/containers/create?name=topcontainer", + json={"Cmd": ["sh", "-c", "echo podman; sleep 100"], "Image": "alpine:latest"}, + ) + self.assertEqual(r.status_code, 201, r.text) + payload = r.json() + + r = requests.post( + self.podman_url + + f"/v1.40/containers/{payload['Id']}/start" + ) + self.assertEqual(r.status_code, 204, r.text) + + r = requests.post( + self.podman_url + + f"/v1.40/containers/{payload['Id']}/attach?logs=true&stream=false" + ) + self.assertIn(r.status_code, (101, 200), r.text) + # see the attach format docs, stdout = 1, length = 7, message = podman\n + self.assertEqual(r.content, b"\x01\x00\x00\x00\x00\x00\x00\x07podman\n", r.text) + + r = requests.post( + self.podman_url + + f"/v1.40/containers/{payload['Id']}/stop?t=0" + ) + self.assertEqual(r.status_code, 204, r.text) + + requests.delete( + self.podman_url + f"/v1.40/containers/{payload['Id']}?force=true" + ) def test_logs(self): r = requests.get(self.uri(self.resolve_container("/containers/{}/logs?stdout=true")))