Skip to content

Commit

Permalink
optimize test && update doc
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidCai1111 committed Nov 26, 2016
1 parent 01d59d4 commit 36abc82
Show file tree
Hide file tree
Showing 7 changed files with 285 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ _testmain.go
*.exe
*.test
*.prof
*.coverprofile
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sudo: false
language: go
go:
- 1.7
before_install:
- go get -t -v ./...
- go get github.com/mattn/goveralls
script:
- go test -coverprofile=compress.coverprofile
- goveralls -coverprofile=compress.coverprofile -service=travis-ci
8 changes: 8 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
test:
go test -v

cover:
rm -rf *.coverprofile
go test -coverprofile=compress.coverprofile
gover
go tool cover -html=compress.coverprofile
33 changes: 32 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,32 @@
# compress
# compress
[![Build Status](https://travis-ci.org/go-http-utils/compress.svg?branch=master)](https://travis-ci.org/go-http-utils/compress)
[![Coverage Status](https://coveralls.io/repos/github/go-http-utils/compress/badge.svg?branch=master)](https://coveralls.io/github/go-http-utils/compress?branch=master)

Compress middleware for Go.

## Installation

```
go get -u github.com/go-http-utils/compress
```

## Documentation

API documentation can be found here: https://godoc.org/github.com/go-http-utils/compress

## go

```go
import (
"github.com/go-http-utils/compress"
)
```

```go
mux := http.NewServeMux()
mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello World"))
})

http.ListenAndServe(":8080", compress.Handler(mux))
```
15 changes: 9 additions & 6 deletions compress.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
)

// Version is this package's version.
const Version = "0.0.1"
const Version = "0.1.0"

type compressWriter struct {
rw http.ResponseWriter
Expand Down Expand Up @@ -40,8 +40,8 @@ func Handler(h http.Handler) http.Handler {
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
var w io.WriteCloser

if req.Method != http.MethodHead ||
res.Header().Get(headers.ContentEncoding) == "" ||
if req.Method != http.MethodHead &&
res.Header().Get(headers.ContentEncoding) == "" &&
compressible.Test(req.Header.Get(headers.ContentType)) {
n := negotiator.New(req)
encoding, matched := n.Encoding([]string{"gzip", "deflate"})
Expand All @@ -59,11 +59,14 @@ func Handler(h http.Handler) http.Handler {
w, _ = flate.NewWriter(res, flate.DefaultCompression)
}

res.Header().Set(headers.ContentEncoding, encoding)
cw := compressWriter{rw: res, w: w}

defer w.Close()
cw.Header().Set(headers.ContentEncoding, encoding)
cw.Header().Set(headers.Vary, headers.AcceptEncoding)

h.ServeHTTP(compressWriter{rw: res, w: w}, req)
defer cw.w.Close()

h.ServeHTTP(cw, req)
return
}

Expand Down
209 changes: 209 additions & 0 deletions compress_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package compress

import (
"bytes"
"compress/flate"
"compress/gzip"
"io/ioutil"
"net/http"
"net/http/httptest"
"testing"

"github.com/go-http-utils/headers"
"github.com/stretchr/testify/suite"
)

func init() {
gw := gzip.NewWriter(&gziped)
gw.Write(testContent)
gw.Close()

dw, _ := flate.NewWriter(&defalted, flate.DefaultCompression)
dw.Write(testContent)
dw.Close()
}

type CompressSuite struct {
suite.Suite

server *httptest.Server
}

var testContent = []byte("Hello,世界")
var gziped bytes.Buffer
var defalted bytes.Buffer

func (s *CompressSuite) SetupTest() {
mux := http.NewServeMux()
mux.Handle("/", Handler(http.HandlerFunc(helloHandlerFunc)))

s.server = httptest.NewServer(mux)
}

func (s CompressSuite) TestCompressGzip() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodGet, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "gzip")
req.Header.Set(headers.ContentType, "text/plain")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.Equal("gzip", res.Header.Get(headers.ContentEncoding))

body, err := getResRawBody(res)
s.Nil(err)
s.Equal(gziped.Bytes(), body)
}

func (s CompressSuite) TestCompressDeflate() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodGet, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "deflate")
req.Header.Set(headers.ContentType, "text/plain")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.Equal("deflate", res.Header.Get(headers.ContentEncoding))

body, err := getResRawBody(res)
s.Nil(err)
s.Equal(defalted.Bytes(), body)
}

func (s CompressSuite) TestCompressGzipNegotiated() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodGet, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "gzip, deflate")
req.Header.Set(headers.ContentType, "text/plain")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.Equal(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.Equal("gzip", res.Header.Get(headers.ContentEncoding))

body, err := getResRawBody(res)
s.Nil(err)
s.Equal(gziped.Bytes(), body)
}

func (s CompressSuite) TestHead() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodHead, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "gzip, deflate")
req.Header.Set(headers.ContentType, "text/plain")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.NotEqual(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.NotEqual("gzip", res.Header.Get(headers.ContentEncoding))
}

func (s CompressSuite) TestNotCompressible() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodGet, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "gzip")
req.Header.Set(headers.ContentType, "image/png")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.NotEqual(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.NotEqual("gzip", res.Header.Get(headers.ContentEncoding))
}

func (s CompressSuite) TestNotMatchCompressible() {
defer s.server.Close()

req, err := http.NewRequest(http.MethodGet, s.server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "not-match")
req.Header.Set(headers.ContentType, "text/html")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusNotAcceptable, res.StatusCode)
s.NotEqual(headers.AcceptEncoding, res.Header.Get(headers.Vary))

body, err := getResRawBody(res)
s.Nil(err)
s.Equal([]byte("supported encodings: gzip, deflate"), body)
}

func (s CompressSuite) TestAlreadySetContentEncoding() {
defer s.server.Close()

mux := http.NewServeMux()
mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
res.Header().Set(headers.ContentEncoding, "gzip")
Handler(http.HandlerFunc(helloHandlerFunc)).ServeHTTP(res, req)
})

server := httptest.NewServer(mux)
defer server.Close()

req, err := http.NewRequest(http.MethodGet, server.URL+"/", nil)
s.Nil(err)

req.Header.Set(headers.AcceptEncoding, "gzip")
req.Header.Set(headers.ContentType, "image/png")

res, err := sendRequest(req)

s.Nil(err)
s.Equal(http.StatusOK, res.StatusCode)
s.NotEqual(headers.AcceptEncoding, res.Header.Get(headers.Vary))
s.Equal("gzip", res.Header.Get(headers.ContentEncoding))
}

func TestCompress(t *testing.T) {
suite.Run(t, new(CompressSuite))
}

func helloHandlerFunc(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusOK)

res.Write(testContent)
}

func noContentFunc(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusNoContent)

res.Write(nil)
}

func sendRequest(req *http.Request) (*http.Response, error) {
cli := &http.Client{}
return cli.Do(req)
}

func getResRawBody(res *http.Response) ([]byte, error) {
return ioutil.ReadAll(res.Body)
}
16 changes: 16 additions & 0 deletions example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package compress_test

import (
"net/http"

"github.com/go-http-utils/compress"
)

func Example() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) {
res.Write([]byte("Hello World"))
})

http.ListenAndServe(":8080", compress.Handler(mux))
}

0 comments on commit 36abc82

Please sign in to comment.