package main import ( . "gopkg.in/check.v1" "bytes" gzipp "compress/gzip" "encoding/base64" gifp "image/gif" jpegp "image/jpeg" pngp "image/png" "io/ioutil" "net/http" "net/http/httptest" "net/url" "testing" "github.com/ahmetb/go-httpbin" "github.com/barnacs/compy/proxy" tc "github.com/barnacs/compy/transcoder" "github.com/chai2010/webp" brotlidec "gopkg.in/kothar/brotli-go.v0/dec" ) func Test(t *testing.T) { TestingT(t) } type CompyTest struct { client *http.Client server *httptest.Server proxy *proxy.Proxy } var _ = Suite(&CompyTest{}) func (s *CompyTest) SetUpSuite(c *C) { s.server = httptest.NewServer(httpbin.GetMux()) s.proxy = proxy.New("localhost"+*host, "") s.proxy.AddTranscoder("image/gif", &tc.Gif{}) s.proxy.AddTranscoder("image/jpeg", tc.NewJpeg(50)) s.proxy.AddTranscoder("image/png", &tc.Png{}) s.proxy.AddTranscoder("text/html", &tc.Zip{&tc.Identity{}, *brotli, *gzip, true}) go func() { err := s.proxy.Start(*host) if err != nil { c.Fatal(err) } }() proxyUrl := &url.URL{Scheme: "http", Host: "localhost" + *host} tr := &http.Transport{ DisableCompression: true, Proxy: http.ProxyURL(proxyUrl), } s.client = &http.Client{Transport: tr} } func (s *CompyTest) TearDownSuite(c *C) { s.server.Close() // TODO: Go 1.8 will provide http.Server.Shutdown for proxy.Proxy } func (s *CompyTest) TestHttpBin(c *C) { resp, err := s.client.Get(s.server.URL + "/status/200") c.Assert(err, IsNil) c.Assert(resp.StatusCode, Equals, 200) } func (s *CompyTest) TestNoGzip(c *C) { resp, err := http.Get(s.server.URL + "/html") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Encoding"), Equals, "") _, err = gzipp.NewReader(resp.Body) c.Assert(err, NotNil) } func (s *CompyTest) TestGzip(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/html", nil) c.Assert(err, IsNil) req.Header.Add("Accept-Encoding", "gzip") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Encoding"), Equals, "gzip") gzr, err := gzipp.NewReader(resp.Body) c.Assert(err, IsNil) defer gzr.Close() _, err = ioutil.ReadAll(gzr) c.Assert(err, IsNil) } func (s *CompyTest) TestBrotli(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/html", nil) c.Assert(err, IsNil) req.Header.Add("Accept-Encoding", "br, gzip") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Encoding"), Equals, "br") brr := brotlidec.NewBrotliReader(resp.Body) defer brr.Close() _, err = ioutil.ReadAll(brr) c.Assert(err, IsNil) } func (s *CompyTest) TestGif(c *C) { resp, err := http.Get(s.server.URL + "/image/gif") c.Assert(err, IsNil) uncompressedLength, err := new(bytes.Buffer).ReadFrom(resp.Body) c.Assert(err, IsNil) resp.Body.Close() resp, err = s.client.Get(s.server.URL + "/image/gif") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/gif") _, err = gifp.Decode(resp.Body) c.Assert(err, IsNil) compressedLength := resp.ContentLength c.Assert(uncompressedLength > compressedLength, Equals, true) } func (s *CompyTest) TestGifToWebP(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/image/gif", nil) c.Assert(err, IsNil) req.Header.Add("Accept", "image/webp") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/webp") _, err = webp.Decode(resp.Body) c.Assert(err, IsNil) } func (s *CompyTest) TestJpeg(c *C) { resp, err := s.client.Get(s.server.URL + "/image/jpeg") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/jpeg") _, err = jpegp.Decode(resp.Body) c.Assert(err, IsNil) } func (s *CompyTest) TestJpegQuality(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/image/jpeg", nil) c.Assert(err, IsNil) req.Header.Add("X-Compy-Quality", "10") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/jpeg") len10, err := new(bytes.Buffer).ReadFrom(resp.Body) c.Assert(err, IsNil) req, err = http.NewRequest("GET", s.server.URL+"/image/jpeg", nil) c.Assert(err, IsNil) req.Header.Add("X-Compy-Quality", "90") resp, err = s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/jpeg") len90, err := new(bytes.Buffer).ReadFrom(resp.Body) c.Assert(err, IsNil) c.Assert(len10 < len90, Equals, true) } func (s *CompyTest) TestJpegToWebP(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/image/jpeg", nil) c.Assert(err, IsNil) req.Header.Add("Accept", "image/webp,image/jpeg") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/webp") _, err = webp.Decode(resp.Body) c.Assert(err, IsNil) } func (s *CompyTest) TestPng(c *C) { resp, err := s.client.Get(s.server.URL + "/image/png") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/png") _, err = pngp.Decode(resp.Body) c.Assert(err, IsNil) } func (s *CompyTest) TestPngToWebP(c *C) { req, err := http.NewRequest("GET", s.server.URL+"/image/png", nil) c.Assert(err, IsNil) req.Header.Add("Accept", "image/webp") resp, err := s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Assert(resp.Header.Get("Content-Type"), Equals, "image/webp") _, err = webp.Decode(resp.Body) c.Assert(err, IsNil) } func (s *CompyTest) TestAuthentication(c *C) { s.proxy.SetAuthentication("user", "pass") defer s.proxy.SetAuthentication("", "") // no password resp, err := s.client.Get(s.server.URL + "/status/200") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 407) // incorrect password req, err := http.NewRequest("GET", s.server.URL+"/status/200", nil) c.Assert(err, IsNil) req.Header.Add("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("wrong:bad"))) resp, err = s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 407) // correct password req, err = http.NewRequest("GET", s.server.URL+"/status/200", nil) c.Assert(err, IsNil) req.Header.Add("Proxy-Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte("user:pass"))) resp, err = s.client.Do(req) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) } func (s *CompyTest) TestAdmin(c *C) { resp, err := s.client.Get("http://localhost" + *host) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) resp, err = s.client.Get("http://localhost" + *host + "/cacert") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 404) resp, err = s.client.Get("http://localhost" + *host + "/fake") c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 501) }