|
@@ -6,6 +6,8 @@ import (
|
|
|
"io/ioutil"
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
"net/http"
|
|
|
"net/http/httptest"
|
|
"net/http/httptest"
|
|
|
|
|
+ "net/http/httputil"
|
|
|
|
|
+ "net/url"
|
|
|
"strconv"
|
|
"strconv"
|
|
|
"testing"
|
|
"testing"
|
|
|
|
|
|
|
@@ -14,16 +16,55 @@ import (
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
const (
|
|
|
- testResponse = "Gzip Test Response "
|
|
|
|
|
|
|
+ testResponse = "Gzip Test Response "
|
|
|
|
|
+ testReverseResponse = "Gzip Test Reverse Response "
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
+func init() {
|
|
|
|
|
+ gin.SetMode(gin.ReleaseMode)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type rServer struct{}
|
|
|
|
|
+
|
|
|
|
|
+func (s *rServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
|
|
|
|
+ fmt.Fprint(rw, testReverseResponse)
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+type closeNotifyingRecorder struct {
|
|
|
|
|
+ *httptest.ResponseRecorder
|
|
|
|
|
+ closed chan bool
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func newCloseNotifyingRecorder() *closeNotifyingRecorder {
|
|
|
|
|
+ return &closeNotifyingRecorder{
|
|
|
|
|
+ httptest.NewRecorder(),
|
|
|
|
|
+ make(chan bool, 1),
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (c *closeNotifyingRecorder) close() {
|
|
|
|
|
+ c.closed <- true
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func (c *closeNotifyingRecorder) CloseNotify() <-chan bool {
|
|
|
|
|
+ return c.closed
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func newServer() *gin.Engine {
|
|
func newServer() *gin.Engine {
|
|
|
- router := gin.Default()
|
|
|
|
|
|
|
+ // init reverse proxy server
|
|
|
|
|
+ rServer := httptest.NewServer(new(rServer))
|
|
|
|
|
+ target, _ := url.Parse(rServer.URL)
|
|
|
|
|
+ rp := httputil.NewSingleHostReverseProxy(target)
|
|
|
|
|
+
|
|
|
|
|
+ router := gin.New()
|
|
|
router.Use(Gzip(DefaultCompression))
|
|
router.Use(Gzip(DefaultCompression))
|
|
|
router.GET("/", func(c *gin.Context) {
|
|
router.GET("/", func(c *gin.Context) {
|
|
|
c.Header("Content-Length", strconv.Itoa(len(testResponse)))
|
|
c.Header("Content-Length", strconv.Itoa(len(testResponse)))
|
|
|
c.String(200, testResponse)
|
|
c.String(200, testResponse)
|
|
|
})
|
|
})
|
|
|
|
|
+ router.Any("/reverse", func(c *gin.Context) {
|
|
|
|
|
+ rp.ServeHTTP(c.Writer, c.Request)
|
|
|
|
|
+ })
|
|
|
return router
|
|
return router
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -81,3 +122,26 @@ func TestNoGzip(t *testing.T) {
|
|
|
assert.Equal(t, w.Header().Get("Content-Length"), "19")
|
|
assert.Equal(t, w.Header().Get("Content-Length"), "19")
|
|
|
assert.Equal(t, w.Body.String(), testResponse)
|
|
assert.Equal(t, w.Body.String(), testResponse)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+func TestGzipWithReverseProxy(t *testing.T) {
|
|
|
|
|
+ req, _ := http.NewRequest("GET", "/reverse", nil)
|
|
|
|
|
+ req.Header.Add("Accept-Encoding", "gzip")
|
|
|
|
|
+
|
|
|
|
|
+ w := newCloseNotifyingRecorder()
|
|
|
|
|
+ r := newServer()
|
|
|
|
|
+ r.ServeHTTP(w, req)
|
|
|
|
|
+
|
|
|
|
|
+ assert.Equal(t, w.Code, 200)
|
|
|
|
|
+ assert.Equal(t, w.Header().Get("Content-Encoding"), "gzip")
|
|
|
|
|
+ assert.Equal(t, w.Header().Get("Vary"), "Accept-Encoding")
|
|
|
|
|
+ assert.NotEqual(t, w.Header().Get("Content-Length"), "0")
|
|
|
|
|
+ assert.NotEqual(t, w.Body.Len(), 19)
|
|
|
|
|
+ assert.Equal(t, fmt.Sprint(w.Body.Len()), w.Header().Get("Content-Length"))
|
|
|
|
|
+
|
|
|
|
|
+ gr, err := gzip.NewReader(w.Body)
|
|
|
|
|
+ assert.NoError(t, err)
|
|
|
|
|
+ defer gr.Close()
|
|
|
|
|
+
|
|
|
|
|
+ body, _ := ioutil.ReadAll(gr)
|
|
|
|
|
+ assert.Equal(t, string(body), testReverseResponse)
|
|
|
|
|
+}
|