diff --git a/api/server/middleware/version.go b/api/server/middleware/version.go index ef35c728f150390a754e39885837bf07c7cd0371..32be500b06d6aff25cfd390de98448846b3d070d 100644 --- a/api/server/middleware/version.go +++ b/api/server/middleware/version.go @@ -28,11 +28,14 @@ func NewVersionMiddleware(s, d, m string) VersionMiddleware { } type versionUnsupportedError struct { - version, minVersion string + version, minVersion, maxVersion string } func (e versionUnsupportedError) Error() string { - return fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", e.version, e.minVersion) + if e.minVersion != "" { + return fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", e.version, e.minVersion) + } + return fmt.Sprintf("client version %s is too new. Maximum supported API version is %s", e.version, e.maxVersion) } func (e versionUnsupportedError) InvalidParameter() {} @@ -44,9 +47,11 @@ func (v VersionMiddleware) WrapHandler(handler func(ctx context.Context, w http. if apiVersion == "" { apiVersion = v.defaultVersion } - if versions.LessThan(apiVersion, v.minVersion) { - return versionUnsupportedError{apiVersion, v.minVersion} + return versionUnsupportedError{version: apiVersion, minVersion: v.minVersion} + } + if versions.GreaterThan(apiVersion, v.defaultVersion) { + return versionUnsupportedError{version: apiVersion, maxVersion: v.defaultVersion} } header := fmt.Sprintf("Docker/%s (%s)", v.serverVersion, runtime.GOOS) diff --git a/api/server/middleware/version_test.go b/api/server/middleware/version_test.go index 29787bf4d8e7c151939fc39c5d81c09c6e9e9751..7cd8e8d6d053917b5a3a2c9ac0fe5e9fbecc1c07 100644 --- a/api/server/middleware/version_test.go +++ b/api/server/middleware/version_test.go @@ -31,7 +31,7 @@ func TestVersionMiddleware(t *testing.T) { } } -func TestVersionMiddlewareWithErrors(t *testing.T) { +func TestVersionMiddlewareVersionTooOld(t *testing.T) { handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { if httputils.VersionFromContext(ctx) == "" { t.Fatal("Expected version, got empty string") @@ -55,3 +55,28 @@ func TestVersionMiddlewareWithErrors(t *testing.T) { t.Fatalf("Expected too old client error, got %v", err) } } + +func TestVersionMiddlewareVersionTooNew(t *testing.T) { + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { + if httputils.VersionFromContext(ctx) == "" { + t.Fatal("Expected version, got empty string") + } + return nil + } + + defaultVersion := "1.10.0" + minVersion := "1.2.0" + m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion) + h := m.WrapHandler(handler) + + req, _ := http.NewRequest("GET", "/containers/json", nil) + resp := httptest.NewRecorder() + ctx := context.Background() + + vars := map[string]string{"version": "9999.9999"} + err := h(ctx, resp, req, vars) + + if !strings.Contains(err.Error(), "client version 9999.9999 is too new. Maximum supported API version is 1.10.0") { + t.Fatalf("Expected too new client error, got %v", err) + } +} diff --git a/api/swagger.yaml b/api/swagger.yaml index 2e4615f77f13ca93c1a56278ebcaa2457d3099fd..c3b9c29244f9b1b1f98f1725c3becf2468f9fe51 100644 --- a/api/swagger.yaml +++ b/api/swagger.yaml @@ -50,6 +50,8 @@ info: In previous versions of Docker, it was possible to access the API without providing a version. This behaviour is now deprecated will be removed in a future version of Docker. + If the API version specified in the URL is not supported by the daemon, a HTTP `400 Bad Request` error message is returned. + The API uses an open schema model, which means server may add extra properties to responses. Likewise, the server will ignore any extra query parameters and request body properties. When you write clients, you need to ignore additional properties in responses to ensure they do not break when talking to newer Docker daemons. This documentation is for version 1.34 of the API. Use this table to find documentation for previous versions of the API: diff --git a/docs/api/v1.18.md b/docs/api/v1.18.md index 5543d59d340602483fb9270bf2836f383a1295bd..7ae32ccc93ff707617702f529fa3a340fe5a09b5 100644 --- a/docs/api/v1.18.md +++ b/docs/api/v1.18.md @@ -25,6 +25,11 @@ redirect_from: `stdin` and `stderr`. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.19.md b/docs/api/v1.19.md index 59e4fbe4cc2ed4b78346d18a53050ca1a1cbc4ac..3ecd312c34a55dc50fecf388fa3c1a0e166542c4 100644 --- a/docs/api/v1.19.md +++ b/docs/api/v1.19.md @@ -23,10 +23,13 @@ redirect_from: - The API tends to be REST. However, for some complex commands, like `attach` or `pull`, the HTTP connection is hijacked to transport `stdout`, `stdin` and `stderr`. - - When the client API version is newer than the daemon's, these calls return an HTTP - `400 Bad Request` error message. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.20.md b/docs/api/v1.20.md index 6db64762039c63b797cc0e6f4c974f6f0245cc39..1f94bdaddb6130fe8de01dca6be9b15a521833d4 100644 --- a/docs/api/v1.20.md +++ b/docs/api/v1.20.md @@ -23,10 +23,13 @@ redirect_from: - The API tends to be REST. However, for some complex commands, like `attach` or `pull`, the HTTP connection is hijacked to transport `stdout`, `stdin` and `stderr`. - - When the client API version is newer than the daemon's, these calls return an HTTP - `400 Bad Request` error message. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.21.md b/docs/api/v1.21.md index 202fbb1de06bed4d4465677ac4f0ca8724f1eeb2..a3b79ed8baa500d38dcd7ad8335d1ae51ee9f728 100644 --- a/docs/api/v1.21.md +++ b/docs/api/v1.21.md @@ -23,10 +23,13 @@ redirect_from: - The API tends to be REST. However, for some complex commands, like `attach` or `pull`, the HTTP connection is hijacked to transport `stdout`, `stdin` and `stderr`. - - When the client API version is newer than the daemon's, these calls return an HTTP - `400 Bad Request` error message. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.22.md b/docs/api/v1.22.md index 51c1ab475a6a71f74df91b52c3ae874b953e5f98..a6027bb7608fcb4241cb814393302ebe0dd029ac 100644 --- a/docs/api/v1.22.md +++ b/docs/api/v1.22.md @@ -23,10 +23,13 @@ redirect_from: - The API tends to be REST. However, for some complex commands, like `attach` or `pull`, the HTTP connection is hijacked to transport `stdout`, `stdin` and `stderr`. - - When the client API version is newer than the daemon's, these calls return an HTTP - `400 Bad Request` error message. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.23.md b/docs/api/v1.23.md index a5acfe4321cd34e52ffd2e157750f4257c349d93..19f9e5a96182f16b657712f683d85ada6ff2e96f 100644 --- a/docs/api/v1.23.md +++ b/docs/api/v1.23.md @@ -23,10 +23,13 @@ redirect_from: - The API tends to be REST. However, for some complex commands, like `attach` or `pull`, the HTTP connection is hijacked to transport `stdout`, `stdin` and `stderr`. - - When the client API version is newer than the daemon's, these calls return an HTTP - `400 Bad Request` error message. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Endpoints diff --git a/docs/api/v1.24.md b/docs/api/v1.24.md index b79bbbdb22e460b6a97c04d6c4da0c99f2d77776..6ab5dc24838407b266d1f65e4ab8339f04e69330 100644 --- a/docs/api/v1.24.md +++ b/docs/api/v1.24.md @@ -25,6 +25,11 @@ redirect_from: `stdin` and `stderr`. - A `Content-Length` header should be present in `POST` requests to endpoints that expect a body. + - To lock to a specific version of the API, you prefix the URL with the version + of the API to use. For example, `/v1.18/info`. If no version is included in + the URL, the maximum supported API version is used. + - If the API version specified in the URL is not supported by the daemon, a HTTP + `400 Bad Request` error message is returned. ## 2. Errors