diff --git a/ext/image/image_test.go b/ext/image/image_test.go new file mode 100644 index 00000000..620f5cfa --- /dev/null +++ b/ext/image/image_test.go @@ -0,0 +1,171 @@ +package goproxy_image_test + +import ( + "bytes" + "crypto/tls" + "github.com/elazarl/goproxy" + goproxy_image "github.com/elazarl/goproxy/ext/image" + "image" + "io" + "net/http" + "net/http/httptest" + "net/url" + "os" + "testing" +) + +var acceptAllCerts = &tls.Config{InsecureSkipVerify: true} + +func oneShotProxy(proxy *goproxy.ProxyHttpServer, t *testing.T) (client *http.Client, s *httptest.Server) { + s = httptest.NewServer(proxy) + + proxyUrl, _ := url.Parse(s.URL) + tr := &http.Transport{TLSClientConfig: acceptAllCerts, Proxy: http.ProxyURL(proxyUrl)} + client = &http.Client{Transport: tr} + return +} + +func getImage(file string, t *testing.T) image.Image { + newimage, err := os.ReadFile(file) + if err != nil { + t.Fatal("Cannot read file", file, err) + } + img, _, err := image.Decode(bytes.NewReader(newimage)) + if err != nil { + t.Fatal("Cannot decode image", file, err) + } + return img +} + +func compareImage(eImg, aImg image.Image, t *testing.T) { + if eImg.Bounds().Dx() != aImg.Bounds().Dx() || eImg.Bounds().Dy() != aImg.Bounds().Dy() { + t.Error("image sizes different") + return + } + for i := 0; i < eImg.Bounds().Dx(); i++ { + for j := 0; j < eImg.Bounds().Dy(); j++ { + er, eg, eb, ea := eImg.At(i, j).RGBA() + ar, ag, ab, aa := aImg.At(i, j).RGBA() + if er != ar || eg != ag || eb != ab || ea != aa { + t.Error("images different at", i, j, "vals\n", er, eg, eb, ea, "\n", ar, ag, ab, aa, aa) + return + } + } + } +} + +var fs = httptest.NewServer(http.FileServer(http.Dir("."))) + +func localFile(url string) string { return fs.URL + "/" + url } + +func TestConstantImageHandler(t *testing.T) { + proxy := goproxy.NewProxyHttpServer() + football := getImage("test_data/football.png", t) + proxy.OnResponse().Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { + return football + })) + + client, l := oneShotProxy(proxy, t) + defer l.Close() + + resp, err := client.Get(localFile("test_data/panda.png")) + if err != nil { + t.Fatal("Cannot get panda.png", err) + } + + img, _, err := image.Decode(resp.Body) + if err != nil { + t.Error("decode", err) + } else { + compareImage(football, img, t) + } +} + +func TestImageHandler(t *testing.T) { + proxy := goproxy.NewProxyHttpServer() + football := getImage("test_data/football.png", t) + + proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { + return football + })) + + client, l := oneShotProxy(proxy, t) + defer l.Close() + + resp, err := client.Get(localFile("test_data/panda.png")) + if err != nil { + t.Fatal("Cannot get panda.png", err) + } + + img, _, err := image.Decode(resp.Body) + if err != nil { + t.Error("decode", err) + } else { + compareImage(football, img, t) + } + + // and again + resp, err = client.Get(localFile("test_data/panda.png")) + if err != nil { + t.Fatal("Cannot get panda.png", err) + } + + img, _, err = image.Decode(resp.Body) + if err != nil { + t.Error("decode", err) + } else { + compareImage(football, img, t) + } +} + +func fatalOnErr(err error, msg string, t *testing.T) { + if err != nil { + t.Fatal(msg, err) + } +} + +func get(url string, client *http.Client) ([]byte, error) { + resp, err := client.Get(url) + if err != nil { + return nil, err + } + txt, err := io.ReadAll(resp.Body) + defer resp.Body.Close() + if err != nil { + return nil, err + } + return txt, nil +} + +func getOrFail(url string, client *http.Client, t *testing.T) []byte { + txt, err := get(url, client) + if err != nil { + t.Fatal("Can't fetch url", url, err) + } + return txt +} + +func TestReplaceImage(t *testing.T) { + proxy := goproxy.NewProxyHttpServer() + + panda := getImage("test_data/panda.png", t) + football := getImage("test_data/football.png", t) + + proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { + return football + })) + proxy.OnResponse(goproxy.UrlIs("/test_data/football.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { + return panda + })) + + client, l := oneShotProxy(proxy, t) + defer l.Close() + + imgByPandaReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/panda.png"), client, t))) + fatalOnErr(err, "decode panda", t) + compareImage(football, imgByPandaReq, t) + + imgByFootballReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/football.png"), client, t))) + fatalOnErr(err, "decode football", t) + compareImage(panda, imgByFootballReq, t) +} diff --git a/go.mod b/go.mod index 278a4f92..8ef6b038 100644 --- a/go.mod +++ b/go.mod @@ -2,9 +2,6 @@ module github.com/elazarl/goproxy go 1.20 -require ( - github.com/elazarl/goproxy/ext v0.0.0-20241217120900-7711dfa3811c - golang.org/x/net v0.33.0 -) +require golang.org/x/net v0.33.0 require golang.org/x/text v0.21.0 // indirect diff --git a/go.sum b/go.sum index 2a9d0c08..845330e7 100644 --- a/go.sum +++ b/go.sum @@ -1,8 +1,3 @@ -github.com/elazarl/goproxy/ext v0.0.0-20241217120900-7711dfa3811c h1:R+i10jtNSzKJKqEZAYJnR9M8y14k0zrNHqD1xkv/A2M= -github.com/elazarl/goproxy/ext v0.0.0-20241217120900-7711dfa3811c/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8= -github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/proxy_test.go b/proxy_test.go index 426339d3..6d164e81 100644 --- a/proxy_test.go +++ b/proxy_test.go @@ -8,7 +8,6 @@ import ( "crypto/x509" "encoding/base64" "fmt" - "image" "io" "net" "net/http" @@ -22,7 +21,6 @@ import ( "time" "github.com/elazarl/goproxy" - goproxy_image "github.com/elazarl/goproxy/ext/image" ) var acceptAllCerts = &tls.Config{InsecureSkipVerify: true} @@ -221,18 +219,6 @@ func TestContentType(t *testing.T) { } } -func getImage(file string, t *testing.T) image.Image { - newimage, err := os.ReadFile(file) - if err != nil { - t.Fatal("Cannot read file", file, err) - } - img, _, err := image.Decode(bytes.NewReader(newimage)) - if err != nil { - t.Fatal("Cannot decode image", file, err) - } - return img -} - func readAll(r io.Reader, t *testing.T) []byte { b, err := io.ReadAll(r) if err != nil { @@ -259,84 +245,6 @@ func panicOnErr(err error, msg string) { } } -func compareImage(eImg, aImg image.Image, t *testing.T) { - if eImg.Bounds().Dx() != aImg.Bounds().Dx() || eImg.Bounds().Dy() != aImg.Bounds().Dy() { - t.Error("image sizes different") - return - } - for i := 0; i < eImg.Bounds().Dx(); i++ { - for j := 0; j < eImg.Bounds().Dy(); j++ { - er, eg, eb, ea := eImg.At(i, j).RGBA() - ar, ag, ab, aa := aImg.At(i, j).RGBA() - if er != ar || eg != ag || eb != ab || ea != aa { - t.Error("images different at", i, j, "vals\n", er, eg, eb, ea, "\n", ar, ag, ab, aa, aa) - return - } - } - } -} - -func TestConstantImageHandler(t *testing.T) { - proxy := goproxy.NewProxyHttpServer() - //panda := getImage("panda.png", t) - football := getImage("test_data/football.png", t) - proxy.OnResponse().Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { - return football - })) - - client, l := oneShotProxy(proxy, t) - defer l.Close() - - resp, err := client.Get(localFile("test_data/panda.png")) - if err != nil { - t.Fatal("Cannot get panda.png", err) - } - - img, _, err := image.Decode(resp.Body) - if err != nil { - t.Error("decode", err) - } else { - compareImage(football, img, t) - } -} - -func TestImageHandler(t *testing.T) { - proxy := goproxy.NewProxyHttpServer() - football := getImage("test_data/football.png", t) - - proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { - return football - })) - - client, l := oneShotProxy(proxy, t) - defer l.Close() - - resp, err := client.Get(localFile("test_data/panda.png")) - if err != nil { - t.Fatal("Cannot get panda.png", err) - } - - img, _, err := image.Decode(resp.Body) - if err != nil { - t.Error("decode", err) - } else { - compareImage(football, img, t) - } - - // and again - resp, err = client.Get(localFile("test_data/panda.png")) - if err != nil { - t.Fatal("Cannot get panda.png", err) - } - - img, _, err = image.Decode(resp.Body) - if err != nil { - t.Error("decode", err) - } else { - compareImage(football, img, t) - } -} - func TestChangeResp(t *testing.T) { proxy := goproxy.NewProxyHttpServer() proxy.OnResponse().DoFunc(func(resp *http.Response, ctx *goproxy.ProxyCtx) *http.Response { @@ -358,30 +266,6 @@ func TestChangeResp(t *testing.T) { t.Fatal(err) } } -func TestReplaceImage(t *testing.T) { - proxy := goproxy.NewProxyHttpServer() - - panda := getImage("test_data/panda.png", t) - football := getImage("test_data/football.png", t) - - proxy.OnResponse(goproxy.UrlIs("/test_data/panda.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { - return football - })) - proxy.OnResponse(goproxy.UrlIs("/test_data/football.png")).Do(goproxy_image.HandleImage(func(img image.Image, ctx *goproxy.ProxyCtx) image.Image { - return panda - })) - - client, l := oneShotProxy(proxy, t) - defer l.Close() - - imgByPandaReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/panda.png"), client, t))) - fatalOnErr(err, "decode panda", t) - compareImage(football, imgByPandaReq, t) - - imgByFootballReq, _, err := image.Decode(bytes.NewReader(getOrFail(localFile("test_data/football.png"), client, t))) - fatalOnErr(err, "decode football", t) - compareImage(panda, imgByFootballReq, t) -} func getCert(c *tls.Conn, t *testing.T) []byte { if err := c.Handshake(); err != nil {