(ctx context.Context)
| 106 | } |
| 107 | |
| 108 | func (cli *Client) ping(ctx context.Context) (PingResult, error) { |
| 109 | // Using cli.buildRequest() + cli.doRequest() instead of cli.sendRequest() |
| 110 | // because ping requests are used during API version negotiation, so we want |
| 111 | // to hit the non-versioned /_ping endpoint, not /v1.xx/_ping |
| 112 | req, err := cli.buildRequest(ctx, http.MethodHead, path.Join(cli.basePath, "/_ping"), nil, nil) |
| 113 | if err != nil { |
| 114 | return PingResult{}, err |
| 115 | } |
| 116 | resp, err := cli.doRequest(req) |
| 117 | defer ensureReaderClosed(resp) |
| 118 | if err == nil && resp.StatusCode == http.StatusOK { |
| 119 | // Fast-path; successfully connected using a HEAD request and |
| 120 | // we got a "OK" (200) status. For non-200 status-codes, we fall |
| 121 | // back to doing a GET request, as a HEAD request won't have a |
| 122 | // response-body to get error details from. |
| 123 | return newPingResult(resp), nil |
| 124 | } |
| 125 | // close to allow reusing connection. |
| 126 | ensureReaderClosed(resp) |
| 127 | |
| 128 | // HEAD failed or returned a non-OK status; fallback to GET. |
| 129 | req2, err := cli.buildRequest(ctx, http.MethodGet, path.Join(cli.basePath, "/_ping"), nil, nil) |
| 130 | if err != nil { |
| 131 | return PingResult{}, err |
| 132 | } |
| 133 | resp, err = cli.doRequest(req2) |
| 134 | defer ensureReaderClosed(resp) |
| 135 | if err != nil { |
| 136 | // Failed to connect. |
| 137 | return PingResult{}, err |
| 138 | } |
| 139 | |
| 140 | // GET request succeeded but may have returned a non-200 status. |
| 141 | // Return a Ping response, together with any error returned by |
| 142 | // the API server. |
| 143 | return newPingResult(resp), checkResponseErr(resp) |
| 144 | } |
| 145 | |
| 146 | func newPingResult(resp *http.Response) PingResult { |
| 147 | if resp == nil { |
no test coverage detected