git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server

subrepo:
  subdir:   "metrics-server"
  merged:   "92d8412"
upstream:
  origin:   "https://github.com/kubernetes-incubator/metrics-server.git"
  branch:   "master"
  commit:   "92d8412"
git-subrepo:
  version:  "0.4.0"
  origin:   "???"
  commit:   "???"
diff --git a/metrics-server/vendor/k8s.io/apiserver/pkg/server/filters/compression.go b/metrics-server/vendor/k8s.io/apiserver/pkg/server/filters/compression.go
new file mode 100644
index 0000000..625cd5c
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/apiserver/pkg/server/filters/compression.go
@@ -0,0 +1,181 @@
+/*
+Copyright 2017 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package filters
+
+import (
+	"compress/gzip"
+	"compress/zlib"
+	"errors"
+	"fmt"
+	"io"
+	"net/http"
+	"strings"
+
+	"github.com/emicklei/go-restful"
+
+	"k8s.io/apimachinery/pkg/util/runtime"
+	"k8s.io/apiserver/pkg/endpoints/request"
+)
+
+// Compressor is an interface to compression writers
+type Compressor interface {
+	io.WriteCloser
+	Flush() error
+}
+
+const (
+	headerAcceptEncoding  = "Accept-Encoding"
+	headerContentEncoding = "Content-Encoding"
+
+	encodingGzip    = "gzip"
+	encodingDeflate = "deflate"
+)
+
+// WithCompression wraps an http.Handler with the Compression Handler
+func WithCompression(handler http.Handler) http.Handler {
+	return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+		wantsCompression, encoding := wantsCompressedResponse(req)
+		w.Header().Set("Vary", "Accept-Encoding")
+		if wantsCompression {
+			compressionWriter, err := NewCompressionResponseWriter(w, encoding)
+			if err != nil {
+				handleError(w, req, err)
+				runtime.HandleError(fmt.Errorf("failed to compress HTTP response: %v", err))
+				return
+			}
+			compressionWriter.Header().Set("Content-Encoding", encoding)
+			handler.ServeHTTP(compressionWriter, req)
+			compressionWriter.(*compressionResponseWriter).Close()
+		} else {
+			handler.ServeHTTP(w, req)
+		}
+	})
+}
+
+// wantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.
+func wantsCompressedResponse(req *http.Request) (bool, string) {
+	// don't compress watches
+	ctx := req.Context()
+	info, ok := request.RequestInfoFrom(ctx)
+	if !ok {
+		return false, ""
+	}
+	if !info.IsResourceRequest {
+		return false, ""
+	}
+	if info.Verb == "watch" {
+		return false, ""
+	}
+	header := req.Header.Get(headerAcceptEncoding)
+	gi := strings.Index(header, encodingGzip)
+	zi := strings.Index(header, encodingDeflate)
+	// use in order of appearance
+	switch {
+	case gi == -1:
+		return zi != -1, encodingDeflate
+	case zi == -1:
+		return gi != -1, encodingGzip
+	case gi < zi:
+		return true, encodingGzip
+	default:
+		return true, encodingDeflate
+	}
+}
+
+type compressionResponseWriter struct {
+	writer     http.ResponseWriter
+	compressor Compressor
+	encoding   string
+}
+
+// NewCompressionResponseWriter returns wraps w with a compression ResponseWriter, using the given encoding
+func NewCompressionResponseWriter(w http.ResponseWriter, encoding string) (http.ResponseWriter, error) {
+	var compressor Compressor
+	switch encoding {
+	case encodingGzip:
+		compressor = gzip.NewWriter(w)
+	case encodingDeflate:
+		compressor = zlib.NewWriter(w)
+	default:
+		return nil, fmt.Errorf("%s is not a supported encoding type", encoding)
+	}
+	return &compressionResponseWriter{
+		writer:     w,
+		compressor: compressor,
+		encoding:   encoding,
+	}, nil
+}
+
+// compressionResponseWriter implements http.Responsewriter Interface
+var _ http.ResponseWriter = &compressionResponseWriter{}
+
+func (c *compressionResponseWriter) Header() http.Header {
+	return c.writer.Header()
+}
+
+// compress data according to compression method
+func (c *compressionResponseWriter) Write(p []byte) (int, error) {
+	if c.compressorClosed() {
+		return -1, errors.New("compressing error: tried to write data using closed compressor")
+	}
+	c.Header().Set(headerContentEncoding, c.encoding)
+	defer c.compressor.Flush()
+	return c.compressor.Write(p)
+}
+
+func (c *compressionResponseWriter) WriteHeader(status int) {
+	c.writer.WriteHeader(status)
+}
+
+// CloseNotify is part of http.CloseNotifier interface
+func (c *compressionResponseWriter) CloseNotify() <-chan bool {
+	return c.writer.(http.CloseNotifier).CloseNotify()
+}
+
+// Close the underlying compressor
+func (c *compressionResponseWriter) Close() error {
+	if c.compressorClosed() {
+		return errors.New("Compressing error: tried to close already closed compressor")
+	}
+
+	c.compressor.Close()
+	c.compressor = nil
+	return nil
+}
+
+func (c *compressionResponseWriter) Flush() {
+	if c.compressorClosed() {
+		return
+	}
+	c.compressor.Flush()
+}
+
+func (c *compressionResponseWriter) compressorClosed() bool {
+	return nil == c.compressor
+}
+
+// RestfulWithCompression wraps WithCompression to be compatible with go-restful
+func RestfulWithCompression(function restful.RouteFunction) restful.RouteFunction {
+	return restful.RouteFunction(func(request *restful.Request, response *restful.Response) {
+		handler := WithCompression(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
+			response.ResponseWriter = w
+			request.Request = req
+			function(request, response)
+		}))
+		handler.ServeHTTP(response.ResponseWriter, request.Request)
+	})
+}