From e53cd07fcc3f5ea89b7806b84600f23bd6563301 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Fri, 27 Jun 2025 18:03:47 +0200 Subject: [PATCH] client: remove getDockerOS utility in favor of "Ostype" header This utility was added in 83b5729f6452de6b40719b9485947eea0bd0eedd to replace httputils.ParseServerHeader, which was added to print a warning on Windows in 126529c6d0a20675de8f50939c57f23259d3e763. At the time, the only available option to detect the daemon's OS was to parse the `Server` header, which contained the version of Docker as well as the OS. However, 7199522ea2e77c77bf931474eca92aa502ce0031 introduced an `OSType` ("Ostype") header that's included on all responses, and a later commit e9dac5ef5e8a4b0ecce0c89d337fea90f2c6aef3 changed that to also be included when producing an error for unsupported API versions. Note that the casing in the midddleware was changed from `OSType` to `Ostype` (normalized form) in 76a5ca1d4d97ad313b8f1f0deb1ae5563a158a40, but headers are case-insensitive, and `header.Get()` should handle either case in the response. In short; every API response contains an "Ostype" header, which already contains the OS ("windows" or "linux") that doesn't require any parsing, so let's put that header to use. Signed-off-by: Sebastiaan van Stijn (cherry picked from commit fcf3ff1b2f04035ccdd5c53fd510f088f0784a13) Signed-off-by: Sebastiaan van Stijn --- client/container_stats.go | 4 ++-- client/image_build.go | 2 +- client/image_build_test.go | 14 +------------- client/utils.go | 13 ------------- 4 files changed, 4 insertions(+), 29 deletions(-) diff --git a/client/container_stats.go b/client/container_stats.go index 2244e0f4b9..076954f4c3 100644 --- a/client/container_stats.go +++ b/client/container_stats.go @@ -28,7 +28,7 @@ func (cli *Client) ContainerStats(ctx context.Context, containerID string, strea return container.StatsResponseReader{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } @@ -51,6 +51,6 @@ func (cli *Client) ContainerStatsOneShot(ctx context.Context, containerID string return container.StatsResponseReader{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } diff --git a/client/image_build.go b/client/image_build.go index 66ca75e4af..1ed0878bfd 100644 --- a/client/image_build.go +++ b/client/image_build.go @@ -40,7 +40,7 @@ func (cli *Client) ImageBuild(ctx context.Context, buildContext io.Reader, optio return build.ImageBuildResponse{ Body: resp.Body, - OSType: getDockerOS(resp.Header.Get("Server")), + OSType: resp.Header.Get("Ostype"), }, nil } diff --git a/client/image_build_test.go b/client/image_build_test.go index 5610391fdf..76c514962d 100644 --- a/client/image_build_test.go +++ b/client/image_build_test.go @@ -191,7 +191,7 @@ func TestImageBuild(t *testing.T) { } headers := http.Header{} - headers.Add("Server", "Docker/v1.23 (MyOS)") + headers.Add("Ostype", "MyOS") return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewReader([]byte("body"))), @@ -208,15 +208,3 @@ func TestImageBuild(t *testing.T) { assert.Check(t, is.Equal(string(response), "body")) } } - -func TestGetDockerOS(t *testing.T) { - cases := map[string]string{ - "Docker/v1.22 (linux)": "linux", - "Docker/v1.22 (windows)": "windows", - "Foo/v1.22 (bar)": "", - } - for header, os := range cases { - g := getDockerOS(header) - assert.Check(t, is.Equal(g, os)) - } -} diff --git a/client/utils.go b/client/utils.go index 67e1e6934b..7b82f185ac 100644 --- a/client/utils.go +++ b/client/utils.go @@ -8,12 +8,9 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/internal/lazyregexp" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) -var headerRegexp = lazyregexp.New(`\ADocker/.+\s\((.+)\)\z`) - type emptyIDError string func (e emptyIDError) InvalidParameter() {} @@ -31,16 +28,6 @@ func trimID(objType, id string) (string, error) { return id, nil } -// getDockerOS returns the operating system based on the server header from the daemon. -func getDockerOS(serverHeader string) string { - var osType string - matches := headerRegexp.FindStringSubmatch(serverHeader) - if len(matches) > 0 { - osType = matches[1] - } - return osType -} - // getFiltersQuery returns a url query with "filters" query term, based on the // filters provided. func getFiltersQuery(f filters.Args) (url.Values, error) {