mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-10-31 13:50:01 +00:00 
			
		
		
		
	godep restore pushd $GOPATH/src/github.com/appc/spec git co master popd go get go4.org/errorutil rm -rf Godeps godep save ./... git add vendor git add -f $(git ls-files --other vendor/) git co -- Godeps/LICENSES Godeps/.license_file_state Godeps/OWNERS
		
			
				
	
	
		
			124 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package restful
 | |
| 
 | |
| // Copyright 2013 Ernest Micklei. All rights reserved.
 | |
| // Use of this source code is governed by a license
 | |
| // that can be found in the LICENSE file.
 | |
| 
 | |
| import (
 | |
| 	"bufio"
 | |
| 	"compress/gzip"
 | |
| 	"compress/zlib"
 | |
| 	"errors"
 | |
| 	"io"
 | |
| 	"net"
 | |
| 	"net/http"
 | |
| 	"strings"
 | |
| )
 | |
| 
 | |
| // OBSOLETE : use restful.DefaultContainer.EnableContentEncoding(true) to change this setting.
 | |
| var EnableContentEncoding = false
 | |
| 
 | |
| // CompressingResponseWriter is a http.ResponseWriter that can perform content encoding (gzip and zlib)
 | |
| type CompressingResponseWriter struct {
 | |
| 	writer     http.ResponseWriter
 | |
| 	compressor io.WriteCloser
 | |
| 	encoding   string
 | |
| }
 | |
| 
 | |
| // Header is part of http.ResponseWriter interface
 | |
| func (c *CompressingResponseWriter) Header() http.Header {
 | |
| 	return c.writer.Header()
 | |
| }
 | |
| 
 | |
| // WriteHeader is part of http.ResponseWriter interface
 | |
| func (c *CompressingResponseWriter) WriteHeader(status int) {
 | |
| 	c.writer.WriteHeader(status)
 | |
| }
 | |
| 
 | |
| // Write is part of http.ResponseWriter interface
 | |
| // It is passed through the compressor
 | |
| func (c *CompressingResponseWriter) Write(bytes []byte) (int, error) {
 | |
| 	if c.isCompressorClosed() {
 | |
| 		return -1, errors.New("Compressing error: tried to write data using closed compressor")
 | |
| 	}
 | |
| 	return c.compressor.Write(bytes)
 | |
| }
 | |
| 
 | |
| // CloseNotify is part of http.CloseNotifier interface
 | |
| func (c *CompressingResponseWriter) CloseNotify() <-chan bool {
 | |
| 	return c.writer.(http.CloseNotifier).CloseNotify()
 | |
| }
 | |
| 
 | |
| // Close the underlying compressor
 | |
| func (c *CompressingResponseWriter) Close() error {
 | |
| 	if c.isCompressorClosed() {
 | |
| 		return errors.New("Compressing error: tried to close already closed compressor")
 | |
| 	}
 | |
| 
 | |
| 	c.compressor.Close()
 | |
| 	if ENCODING_GZIP == c.encoding {
 | |
| 		currentCompressorProvider.ReleaseGzipWriter(c.compressor.(*gzip.Writer))
 | |
| 	}
 | |
| 	if ENCODING_DEFLATE == c.encoding {
 | |
| 		currentCompressorProvider.ReleaseZlibWriter(c.compressor.(*zlib.Writer))
 | |
| 	}
 | |
| 	// gc hint needed?
 | |
| 	c.compressor = nil
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (c *CompressingResponseWriter) isCompressorClosed() bool {
 | |
| 	return nil == c.compressor
 | |
| }
 | |
| 
 | |
| // Hijack implements the Hijacker interface
 | |
| // This is especially useful when combining Container.EnabledContentEncoding
 | |
| // in combination with websockets (for instance gorilla/websocket)
 | |
| func (c *CompressingResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) {
 | |
| 	hijacker, ok := c.writer.(http.Hijacker)
 | |
| 	if !ok {
 | |
| 		return nil, nil, errors.New("ResponseWriter doesn't support Hijacker interface")
 | |
| 	}
 | |
| 	return hijacker.Hijack()
 | |
| }
 | |
| 
 | |
| // WantsCompressedResponse reads the Accept-Encoding header to see if and which encoding is requested.
 | |
| func wantsCompressedResponse(httpRequest *http.Request) (bool, string) {
 | |
| 	header := httpRequest.Header.Get(HEADER_AcceptEncoding)
 | |
| 	gi := strings.Index(header, ENCODING_GZIP)
 | |
| 	zi := strings.Index(header, ENCODING_DEFLATE)
 | |
| 	// use in order of appearance
 | |
| 	if gi == -1 {
 | |
| 		return zi != -1, ENCODING_DEFLATE
 | |
| 	} else if zi == -1 {
 | |
| 		return gi != -1, ENCODING_GZIP
 | |
| 	} else {
 | |
| 		if gi < zi {
 | |
| 			return true, ENCODING_GZIP
 | |
| 		}
 | |
| 		return true, ENCODING_DEFLATE
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // NewCompressingResponseWriter create a CompressingResponseWriter for a known encoding = {gzip,deflate}
 | |
| func NewCompressingResponseWriter(httpWriter http.ResponseWriter, encoding string) (*CompressingResponseWriter, error) {
 | |
| 	httpWriter.Header().Set(HEADER_ContentEncoding, encoding)
 | |
| 	c := new(CompressingResponseWriter)
 | |
| 	c.writer = httpWriter
 | |
| 	var err error
 | |
| 	if ENCODING_GZIP == encoding {
 | |
| 		w := currentCompressorProvider.AcquireGzipWriter()
 | |
| 		w.Reset(httpWriter)
 | |
| 		c.compressor = w
 | |
| 		c.encoding = ENCODING_GZIP
 | |
| 	} else if ENCODING_DEFLATE == encoding {
 | |
| 		w := currentCompressorProvider.AcquireZlibWriter()
 | |
| 		w.Reset(httpWriter)
 | |
| 		c.compressor = w
 | |
| 		c.encoding = ENCODING_DEFLATE
 | |
| 	} else {
 | |
| 		return nil, errors.New("Unknown encoding:" + encoding)
 | |
| 	}
 | |
| 	return c, err
 | |
| }
 |