github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/api/server/middleware/version.go (about)

     1  package middleware // import "github.com/docker/docker/api/server/middleware"
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  	"runtime"
     8  
     9  	"github.com/docker/docker/api/server/httputils"
    10  	"github.com/docker/docker/api/types/versions"
    11  )
    12  
    13  // VersionMiddleware is a middleware that
    14  // validates the client and server versions.
    15  type VersionMiddleware struct {
    16  	serverVersion  string
    17  	defaultVersion string
    18  	minVersion     string
    19  }
    20  
    21  // NewVersionMiddleware creates a new VersionMiddleware
    22  // with the default versions.
    23  func NewVersionMiddleware(s, d, m string) VersionMiddleware {
    24  	return VersionMiddleware{
    25  		serverVersion:  s,
    26  		defaultVersion: d,
    27  		minVersion:     m,
    28  	}
    29  }
    30  
    31  type versionUnsupportedError struct {
    32  	version, minVersion, maxVersion string
    33  }
    34  
    35  func (e versionUnsupportedError) Error() string {
    36  	if e.minVersion != "" {
    37  		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)
    38  	}
    39  	return fmt.Sprintf("client version %s is too new. Maximum supported API version is %s", e.version, e.maxVersion)
    40  }
    41  
    42  func (e versionUnsupportedError) InvalidParameter() {}
    43  
    44  // WrapHandler returns a new handler function wrapping the previous one in the request chain.
    45  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 {
    46  	return func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
    47  		w.Header().Set("Server", fmt.Sprintf("Docker/%s (%s)", v.serverVersion, runtime.GOOS))
    48  		w.Header().Set("API-Version", v.defaultVersion)
    49  		w.Header().Set("OSType", runtime.GOOS)
    50  
    51  		apiVersion := vars["version"]
    52  		if apiVersion == "" {
    53  			apiVersion = v.defaultVersion
    54  		}
    55  		if versions.LessThan(apiVersion, v.minVersion) {
    56  			return versionUnsupportedError{version: apiVersion, minVersion: v.minVersion}
    57  		}
    58  		if versions.GreaterThan(apiVersion, v.defaultVersion) {
    59  			return versionUnsupportedError{version: apiVersion, maxVersion: v.defaultVersion}
    60  		}
    61  		ctx = context.WithValue(ctx, httputils.APIVersionKey{}, apiVersion)
    62  		return handler(ctx, w, r, vars)
    63  	}
    64  
    65  }