Skip to content

Commit

Permalink
Merge pull request #12 from JSainsburyPLC/fix/localhost-links
Browse files Browse the repository at this point in the history
Change links to point to localhost on local dev
  • Loading branch information
msachi authored Aug 4, 2021
2 parents 7359c15 + e1980b4 commit 0cf97e5
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 8 deletions.
17 changes: 9 additions & 8 deletions domain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@ type Config struct {
}

type Route struct {
Type string `json:"type"`
PathPattern *PathPattern `json:"path_pattern"`
Backend *Backend `json:"backend"`
Mock *Mock `json:"mock"`
Rewrite []Rewrite `json:"rewrite"`
Redirect *Redirect `json:"redirect"`
ProxyPassHeaders map[string]string `json:"proxy_pass_headers"`
ProxyResponseHeaders map[string]string `json:"proxy_response_headers"`
Type string `json:"type"`
PathPattern *PathPattern `json:"path_pattern"`
Backend *Backend `json:"backend"`
Mock *Mock `json:"mock"`
Rewrite []Rewrite `json:"rewrite"`
Redirect *Redirect `json:"redirect"`
ProxyPassHeaders map[string]string `json:"proxy_pass_headers"`
ProxyResponseHeaders map[string]string `json:"proxy_response_headers"`
ProxyResponseReplacements map[string]string `json:"proxy_response_replacements"`
}

type Rewrite struct {
Expand Down
85 changes: 85 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package proxy

import (
"bytes"
"compress/gzip"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
"net/url"
"path"
"strings"
"time"

"github.com/JSainsburyPLC/ui-dev-proxy/domain"
Expand Down Expand Up @@ -93,6 +98,44 @@ func director(defaultBackend *url.URL, logger *log.Logger) func(req *http.Reques
}
}

func gUnzipData(data []byte) ([]byte, error) {
b := bytes.NewBuffer(data)

var r io.Reader
r, err := gzip.NewReader(b)
if err != nil {
return nil, err
}

var resB bytes.Buffer
_, err = resB.ReadFrom(r)
if err != nil {
return nil, err
}

return resB.Bytes(), nil
}

func gZipData(data []byte) ([]byte, error) {
var b bytes.Buffer
gz := gzip.NewWriter(&b)

_, err := gz.Write(data)
if err != nil {
return nil, err
}

if err = gz.Flush(); err != nil {
return nil, err
}

if err = gz.Close(); err != nil {
return nil, err
}

return b.Bytes(), nil
}

func modifyResponse() func(*http.Response) error {
return func(res *http.Response) error {
route, ok := res.Request.Context().Value(routeCtxKey).(*domain.Route)
Expand All @@ -105,6 +148,48 @@ func modifyResponse() func(*http.Response) error {
res.Header.Set(k, v)
}

if len(route.ProxyResponseReplacements) != 0 {

bodyBytes, err := ioutil.ReadAll(res.Body)
if err != nil {
return err
}

isGZipped := http.DetectContentType(bodyBytes) == "application/x-gzip"

if isGZipped {
bodyBytes, err = gUnzipData(bodyBytes)
if err != nil {
return err
}
}

bodyString := string(bodyBytes)

for k, v := range route.ProxyResponseReplacements {
bodyString = strings.ReplaceAll(bodyString, k, v)

for headerKey, headerValues := range res.Header {
res.Header.Del(headerKey)
for _, headerValue := range headerValues {
res.Header.Add(headerKey, strings.ReplaceAll(headerValue, k, v))
}
}
}

bodyBytes = []byte(bodyString)

if isGZipped {
bodyBytes, err = gZipData(bodyBytes)
if err != nil {
return err
}
}

res.Header.Set("content-length", fmt.Sprintf("%d", len(bodyBytes)))
res.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))
}

return nil
}
}
Expand Down
21 changes: 21 additions & 0 deletions proxy/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@ func TestProxy_ProxyBackend_UserProxy_Success(t *testing.T) {
End()
}

func TestProxy_ProxyBackend_ResponseReplacements(t *testing.T) {
backendMock := apitest.NewMock().Get("http://localhost:3001/test-ui/users/info").
RespondWith().
Status(http.StatusOK).
Header("test-header", "test-value-1").
Body(`{"product_id": "test-value-1"}`).
End()

newApiTest(config(), "http://test-backend", false).
Mocks(backendMock).
Get("/test-ui/users/info").
Expect(t).
Status(http.StatusOK).
Header("test-header", "test-value-2").
Body(`{"product_id": "test-value-2"}`).
End()
}

func TestProxy_Rewrite(t *testing.T) {
tests := map[string]struct {
pattern string
Expand Down Expand Up @@ -335,6 +353,9 @@ func config() domain.Config {
ProxyResponseHeaders: map[string]string{
"Cache-Control": "no-cache",
},
ProxyResponseReplacements: map[string]string{
"test-value-1": "test-value-2",
},
},
{
Type: "proxy",
Expand Down

0 comments on commit 0cf97e5

Please sign in to comment.