Skip to content

Commit

Permalink
bugfix - return base64 encoded string for binary data in request view
Browse files Browse the repository at this point in the history
  • Loading branch information
kapishmalik authored and tommysitu committed Sep 12, 2023
1 parent ab7d4f8 commit 70aa6a5
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 23 deletions.
31 changes: 8 additions & 23 deletions core/models/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ import (
log "github.com/sirupsen/logrus"
)

var (
// mime types which will not be base 64 encoded when exporting as JSON
supportedMimeTypes = [...]string{"text", "plain", "css", "html", "json", "xml", "js", "javascript"}
)

// Payload structure holds request and response structure
type RequestResponsePair struct {
Response ResponseDetails
Expand Down Expand Up @@ -122,14 +117,19 @@ func NewRequestDetailsFromHttpRequest(req *http.Request) (RequestDetails, error)
func (this *RequestDetails) ConvertToRequestDetailsView() v2.RequestDetailsView {
queryString := this.QueryString()

body := this.Body
if util.NeedsEncoding(this.Headers, this.Body) {
body = base64.StdEncoding.EncodeToString([]byte(this.Body))
}

return v2.RequestDetailsView{
Path: &this.Path,
Method: &this.Method,
Destination: &this.Destination,
Scheme: &this.Scheme,
Query: &queryString,
QueryMap: this.Query,
Body: &this.Body,
Body: &body,
FormData: this.FormData,
Headers: this.Headers,
}
Expand Down Expand Up @@ -251,22 +251,7 @@ func NewResponseDetailsFromResponse(data interfaces.Response) ResponseDetails {
// If the response headers indicate that the content is encoded, or it has a non-matching
// supported mimetype, we base64 encode it.
func (r *ResponseDetails) ConvertToResponseDetailsView() v2.ResponseDetailsView {
needsEncoding := false

// Check headers for gzip
contentEncodingValues := r.Headers["Content-Encoding"]
if len(contentEncodingValues) > 0 {
needsEncoding = true
} else {
mimeType := http.DetectContentType([]byte(r.Body))
needsEncoding = true
for _, v := range supportedMimeTypes {
if strings.Contains(mimeType, v) {
needsEncoding = false
break
}
}
}
needsEncoding := util.NeedsEncoding(r.Headers, r.Body)

// If contains gzip, base64 encode
body := r.Body
Expand All @@ -293,7 +278,7 @@ func (r *ResponseDetails) ConvertToResponseDetailsViewV5() v2.ResponseDetailsVie
} else {
mimeType := http.DetectContentType([]byte(r.Body))
needsEncoding = true
for _, v := range supportedMimeTypes {
for _, v := range util.SupportedMimeTypes {
if strings.Contains(mimeType, v) {
needsEncoding = false
break
Expand Down
20 changes: 20 additions & 0 deletions core/models/payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ func TestResponseDetails_ConvertToResponseDetailsView_WithPlainTextResponseDetai
Expect(respView.Body).To(Equal(body))
}

func TestRequestDetails_ConvertToRequestDetailsView_WithGzipContentEncodedHeader(t *testing.T) {
RegisterTestingT(t)

originalBody := "hello_world"
body := GzipString(originalBody)
headers := map[string][]string{"Content-Encoding": {"gzip"}}

originalRequest := models.RequestDetails{Method: "POST", Headers: headers, Body: body}

requestView := originalRequest.ConvertToRequestDetailsView()

Expect(requestView.Headers).To(Equal(headers))
Expect(requestView.Body).NotTo(Equal(body))
Expect(requestView.Body).NotTo(Equal(originalBody))

base64EncodedBody := "H4sIAAAAAAAA/w=="

Expect(*requestView.Body).To(Equal(base64EncodedBody))
}

func TestResponseDetails_ConvertToResponseDetailsView_WithGzipContentEncodedHeader(t *testing.T) {
RegisterTestingT(t)

Expand Down
25 changes: 25 additions & 0 deletions core/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ import (
"github.com/tdewolff/minify/v2/xml"
)

var (
// mime types which will not be base 64 encoded when exporting as JSON
SupportedMimeTypes = [...]string{"text", "plain", "css", "html", "json", "xml", "js", "javascript"}
)

// GetRequestBody will read the http.Request body io.ReadCloser
// and will also set the buffer to the original value as the
// buffer will be empty after reading it.
Expand Down Expand Up @@ -333,3 +338,23 @@ func GetBoolOrDefault(data map[string]interface{}, key string, defaultValue bool
}
return genericValue.(bool)
}

func NeedsEncoding(headers map[string][]string, body string) bool {
needsEncoding := false

// Check headers for gzip
contentEncodingValues := headers["Content-Encoding"]
if len(contentEncodingValues) > 0 {
needsEncoding = true
} else {
mimeType := http.DetectContentType([]byte(body))
needsEncoding = true
for _, v := range SupportedMimeTypes {
if strings.Contains(mimeType, v) {
needsEncoding = false
break
}
}
}
return needsEncoding
}

0 comments on commit 70aa6a5

Please sign in to comment.