If a 400 error is returned due to an API version mismatch, no
version and server-identification headers were returned by the API.
All information in these headers is "static", so there is no
reason to omit the information in case of an error being
returned.
This patch updates the version middleware to always
return the headers.
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
| ... | ... |
@@ -43,6 +43,10 @@ func (e versionUnsupportedError) InvalidParameter() {}
|
| 43 | 43 |
// WrapHandler returns a new handler function wrapping the previous one in the request chain. |
| 44 | 44 |
func (v VersionMiddleware) WrapHandler(handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error) func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 45 | 45 |
return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| 46 |
+ w.Header().Set("Server", fmt.Sprintf("Docker/%s (%s)", v.serverVersion, runtime.GOOS))
|
|
| 47 |
+ w.Header().Set("API-Version", v.defaultVersion)
|
|
| 48 |
+ w.Header().Set("OSType", runtime.GOOS)
|
|
| 49 |
+ |
|
| 46 | 50 |
apiVersion := vars["version"] |
| 47 | 51 |
if apiVersion == "" {
|
| 48 | 52 |
apiVersion = v.defaultVersion |
| ... | ... |
@@ -53,11 +57,6 @@ func (v VersionMiddleware) WrapHandler(handler func(ctx context.Context, w http. |
| 53 | 53 |
if versions.GreaterThan(apiVersion, v.defaultVersion) {
|
| 54 | 54 |
return versionUnsupportedError{version: apiVersion, maxVersion: v.defaultVersion}
|
| 55 | 55 |
} |
| 56 |
- |
|
| 57 |
- header := fmt.Sprintf("Docker/%s (%s)", v.serverVersion, runtime.GOOS)
|
|
| 58 |
- w.Header().Set("Server", header)
|
|
| 59 |
- w.Header().Set("API-Version", v.defaultVersion)
|
|
| 60 |
- w.Header().Set("OSType", runtime.GOOS)
|
|
| 61 | 56 |
// nolint: golint |
| 62 | 57 |
ctx = context.WithValue(ctx, "api-version", apiVersion) |
| 63 | 58 |
return handler(ctx, w, r, vars) |
| ... | ... |
@@ -3,10 +3,12 @@ package middleware |
| 3 | 3 |
import ( |
| 4 | 4 |
"net/http" |
| 5 | 5 |
"net/http/httptest" |
| 6 |
+ "runtime" |
|
| 6 | 7 |
"strings" |
| 7 | 8 |
"testing" |
| 8 | 9 |
|
| 9 | 10 |
"github.com/docker/docker/api/server/httputils" |
| 11 |
+ "github.com/stretchr/testify/assert" |
|
| 10 | 12 |
"golang.org/x/net/context" |
| 11 | 13 |
) |
| 12 | 14 |
|
| ... | ... |
@@ -80,3 +82,31 @@ func TestVersionMiddlewareVersionTooNew(t *testing.T) {
|
| 80 | 80 |
t.Fatalf("Expected too new client error, got %v", err)
|
| 81 | 81 |
} |
| 82 | 82 |
} |
| 83 |
+ |
|
| 84 |
+func TestVersionMiddlewareWithErrorsReturnsHeaders(t *testing.T) {
|
|
| 85 |
+ handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
|
| 86 |
+ if httputils.VersionFromContext(ctx) == "" {
|
|
| 87 |
+ t.Fatal("Expected version, got empty string")
|
|
| 88 |
+ } |
|
| 89 |
+ return nil |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ defaultVersion := "1.10.0" |
|
| 93 |
+ minVersion := "1.2.0" |
|
| 94 |
+ m := NewVersionMiddleware(defaultVersion, defaultVersion, minVersion) |
|
| 95 |
+ h := m.WrapHandler(handler) |
|
| 96 |
+ |
|
| 97 |
+ req, _ := http.NewRequest("GET", "/containers/json", nil)
|
|
| 98 |
+ resp := httptest.NewRecorder() |
|
| 99 |
+ ctx := context.Background() |
|
| 100 |
+ |
|
| 101 |
+ vars := map[string]string{"version": "0.1"}
|
|
| 102 |
+ err := h(ctx, resp, req, vars) |
|
| 103 |
+ |
|
| 104 |
+ assert.Error(t, err) |
|
| 105 |
+ hdr := resp.Result().Header |
|
| 106 |
+ assert.Contains(t, hdr.Get("Server"), "Docker/"+defaultVersion)
|
|
| 107 |
+ assert.Contains(t, hdr.Get("Server"), runtime.GOOS)
|
|
| 108 |
+ assert.Equal(t, hdr.Get("API-Version"), defaultVersion)
|
|
| 109 |
+ assert.Equal(t, hdr.Get("OSType"), runtime.GOOS)
|
|
| 110 |
+} |