github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/engine/client/ping.go (about) 1 package client // import "github.com/docker/docker/client" 2 3 import ( 4 "context" 5 "net/http" 6 "path" 7 8 "github.com/docker/docker/api/types" 9 "github.com/docker/docker/errdefs" 10 ) 11 12 // Ping pings the server and returns the value of the "Docker-Experimental", 13 // "Builder-Version", "OS-Type" & "API-Version" headers. It attempts to use 14 // a HEAD request on the endpoint, but falls back to GET if HEAD is not supported 15 // by the daemon. 16 func (cli *Client) Ping(ctx context.Context) (types.Ping, error) { 17 var ping types.Ping 18 19 // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() 20 // because ping requests are used during API version negotiation, so we want 21 // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping 22 req, err := cli.buildRequest(http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil) 23 if err != nil { 24 return ping, err 25 } 26 serverResp, err := cli.doRequest(ctx, req) 27 if err == nil { 28 defer ensureReaderClosed(serverResp) 29 switch serverResp.statusCode { 30 case http.StatusOK, http.StatusInternalServerError: 31 // Server handled the request, so parse the response 32 return parsePingResponse(cli, serverResp) 33 } 34 } else if IsErrConnectionFailed(err) { 35 return ping, err 36 } 37 38 req, err = cli.buildRequest(http.MethodGet, path.Join(cli.basePath, "/_ping"), nil, nil) 39 if err != nil { 40 return ping, err 41 } 42 serverResp, err = cli.doRequest(ctx, req) 43 defer ensureReaderClosed(serverResp) 44 if err != nil { 45 return ping, err 46 } 47 return parsePingResponse(cli, serverResp) 48 } 49 50 func parsePingResponse(cli *Client, resp serverResponse) (types.Ping, error) { 51 var ping types.Ping 52 if resp.header == nil { 53 err := cli.checkResponseErr(resp) 54 return ping, errdefs.FromStatusCode(err, resp.statusCode) 55 } 56 ping.APIVersion = resp.header.Get("API-Version") 57 ping.OSType = resp.header.Get("OSType") 58 if resp.header.Get("Docker-Experimental") == "true" { 59 ping.Experimental = true 60 } 61 if bv := resp.header.Get("Builder-Version"); bv != "" { 62 ping.BuilderVersion = types.BuilderVersion(bv) 63 } 64 err := cli.checkResponseErr(resp) 65 return ping, errdefs.FromStatusCode(err, resp.statusCode) 66 }