Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Make sure event body is a string #393

Merged
merged 17 commits into from
Mar 26, 2018
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions router/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ type HTTPResponse struct {

const (
mimeJSON = "application/json"
mimeFormMultipart = "multipart/form-data"
mimeFormURLEncoded = "application/x-www-form-urlencoded"
)

func isHTTPEvent(r *http.Request) bool {
Expand Down Expand Up @@ -63,10 +65,20 @@ func (router *Router) eventFromRequest(r *http.Request) (*eventpkg.Event, string
}

event := eventpkg.New(eventType, mime, body)
if mime == mimeJSON && len(body) > 0 {
err = json.Unmarshal(body, &event.Data)
if err != nil {
return nil, "", errors.New("malformed JSON body")

// Because event.Data is []bytes here, it will be base64 encoded by default when being sent to remote function,
// which is why we change the event.Data type to "string" for forms, so that, it is left intact.
if len(body) > 0 {
switch {
case mime == mimeJSON:
err := json.Unmarshal(body, &event.Data)
if err != nil {
return nil, "", errors.New("malformed JSON body")
}
break
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elsteelbrain break isn't needed in Golang case statements -- https://tour.golang.org/flowcontrol/9

case strings.HasPrefix(mime, mimeFormMultipart), mime == mimeFormURLEncoded:
event.Data = string(body)
break
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@elsteelbrain Same as above

}
}

Expand Down
1 change: 1 addition & 0 deletions router/mock/mock.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:generate mockgen -package mock -destination ./targetcache.go github.com/serverless/event-gateway/router Targeter
//go:generate mockgen -package mock -destination ./provider.go github.com/serverless/event-gateway/function Provider

package mock
59 changes: 59 additions & 0 deletions router/mock/provider.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions router/router_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package router_test

import (
"encoding/json"
"net/http"
"net/http/httptest"
"strings"
Expand All @@ -13,6 +14,7 @@ import (
"github.com/serverless/event-gateway/function"
"github.com/serverless/event-gateway/internal/pathtree"
"github.com/serverless/event-gateway/plugin"
httpprovider "github.com/serverless/event-gateway/providers/http"
"github.com/serverless/event-gateway/router"
"github.com/serverless/event-gateway/router/mock"
"github.com/serverless/event-gateway/subscription"
Expand Down Expand Up @@ -101,6 +103,38 @@ func TestRouterServeHTTP_ErrorMalformedCustomEventJSONRequest(t *testing.T) {
assert.Equal(t, `{"errors":[{"message":"malformed JSON body"}]}`+"\n", recorder.Body.String())
}

func TestRouterServeHTTP_EncodingBase64(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
testListServer := httptest.NewServer(http.HandlerFunc(
func(w http.ResponseWriter, r *http.Request) {
testevent := event.Event{
Data: event.HTTPEvent{},
}
json.NewDecoder(r.Body).Decode(&testevent)

assert.Equal(t, "c29tZT10aGluZw==", testevent.Data.(map[string]interface{})["body"])
}))
defer testListServer.Close()
target := mock.NewMockTargeter(ctrl)
someFunc := function.Function{
Space: "",
ID: "somefunc",
ProviderType: httpprovider.Type,
Provider: httpprovider.HTTP{
URL: testListServer.URL,
},
}
target.EXPECT().HTTPBackingFunction(http.MethodPost, "/").Return("", &someFunc.ID, pathtree.Params{}, nil)
target.EXPECT().Function("", someFunc.ID).Return(&someFunc)
target.EXPECT().SubscribersOfEvent(gomock.Any(), gomock.Any()).Return([]router.FunctionInfo{}).MaxTimes(3)
router := testrouter(target)

req, _ := http.NewRequest(http.MethodPost, "/", strings.NewReader("some=thing"))
recorder := httptest.NewRecorder()
router.ServeHTTP(recorder, req)
}

func TestRouterServeHTTP_ErrorOnCustomEventEmittedWithNonPostMethod(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
Expand Down