Repository: labstack/echo
Pull request #1622 (2020-08-14 12:12:58)

added ModifyResponse option to ProxyConfig
Proxied response can be easily modified with optional built in function of ReverseProxy from core Go package "net/http/httputil".

codecov[bot]: # [Codecov](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=h1) Report
> Merging [#1622](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=desc) into [master](https://codecov.io/gh/labstack/echo/commit/8dd25c39ced4fafbe63e361c281f2275d7d9fa41&el=desc) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/labstack/echo/pull/1622/graphs/tree.svg?width=650&height=150&src=pr&token=vqnT76l79i)](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master    #1622   +/-   ##
=======================================
  Coverage   85.08%   85.08%           
=======================================
  Files          28       28           
  Lines        2185     2186    +1     
=======================================
+ Hits         1859     1860    +1     
  Misses        212      212           
  Partials      114      114           
```


| [Impacted Files](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [middleware/proxy.go](https://codecov.io/gh/labstack/echo/pull/1622/diff?src=pr&el=tree#diff-bWlkZGxld2FyZS9wcm94eS5nbw==) | `66.00% <ø> (ø)` | |
| [middleware/proxy\_1\_11.go](https://codecov.io/gh/labstack/echo/pull/1622/diff?src=pr&el=tree#diff-bWlkZGxld2FyZS9wcm94eV8xXzExLmdv) | `100.00% <100.00%> (ø)` | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=footer). Last update [8dd25c3...862a854](https://codecov.io/gh/labstack/echo/pull/1622?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/middleware/proxy.go b/middleware/proxy.go
index 1956e91..a9b91f6 100644
--- a/middleware/proxy.go
+++ b/middleware/proxy.go
@@ -45,6 +45,9 @@ type (
 		// Examples: If custom TLS certificates are required.
 		Transport http.RoundTripper
 
+		// ModifyResponse defines function to modify response from ProxyTarget.
+		ModifyResponse func(*http.Response) error
+
 		rewriteRegex map[*regexp.Regexp]string
 	}
 
diff --git a/middleware/proxy_1_11.go b/middleware/proxy_1_11.go
index 12b7568..a439278 100644
--- a/middleware/proxy_1_11.go
+++ b/middleware/proxy_1_11.go
@@ -20,5 +20,6 @@ func proxyHTTP(tgt *ProxyTarget, c echo.Context, config ProxyConfig) http.Handle
 		c.Set("_error", echo.NewHTTPError(http.StatusBadGateway, fmt.Sprintf("remote %s unreachable, could not forward: %v", desc, err)))
 	}
 	proxy.Transport = config.Transport
+	proxy.ModifyResponse = config.ModifyResponse
 	return proxy
 }


Test patch:
diff --git a/middleware/proxy_test.go b/middleware/proxy_test.go
index 5ef11bc..b19bf4f 100644
--- a/middleware/proxy_test.go
+++ b/middleware/proxy_test.go
@@ -1,7 +1,9 @@
 package middleware
 
 import (
+	"bytes"
 	"fmt"
+	"io/ioutil"
 	"net"
 	"net/http"
 	"net/http/httptest"
@@ -104,11 +106,26 @@ func TestProxy(t *testing.T) {
 	e.ServeHTTP(rec, req)
 	assert.Equal(t, "/user/jack/order/1", req.URL.Path)
 	assert.Equal(t, http.StatusOK, rec.Code)
-  req.URL.Path = "/users/jill/orders/T%2FcO4lW%2Ft%2FVp%2F"
+	req.URL.Path = "/users/jill/orders/T%2FcO4lW%2Ft%2FVp%2F"
 	e.ServeHTTP(rec, req)
 	assert.Equal(t, "/user/jill/order/T%2FcO4lW%2Ft%2FVp%2F", req.URL.Path)
 	assert.Equal(t, http.StatusOK, rec.Code)
 
+	// ModifyResponse
+	e = echo.New()
+	e.Use(ProxyWithConfig(ProxyConfig{
+		Balancer: rrb,
+		ModifyResponse: func(res *http.Response) error {
+			res.Body = ioutil.NopCloser(bytes.NewBuffer([]byte("modified")))
+			res.Header.Set("X-Modified", "1")
+			return nil
+		},
+	}))
+	rec = httptest.NewRecorder()
+	e.ServeHTTP(rec, req)
+	assert.Equal(t, "modified", rec.Body.String())
+	assert.Equal(t, "1", rec.Header().Get("X-Modified"))
+
 	// ProxyTarget is set in context
 	contextObserver := func(next echo.HandlerFunc) echo.HandlerFunc {
 		return func(c echo.Context) (err error) {