From de49229cfd4519311e89dc1639adf6b45f0a3f38 Mon Sep 17 00:00:00 2001 From: Luis Fonseca Date: Wed, 2 Sep 2020 15:15:14 +0100 Subject: [PATCH 1/2] Allow message limit to be overridden for dedicate cluster customers --- CHANGELOG.md | 4 ++++ client.go | 7 ++++--- client_test.go | 11 +++++++++++ encoder.go | 39 ++++++++++++++++++++++++++++++++------- 4 files changed, 51 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64298a1..32702e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +4.0.4 / 2020-09-02 +================== +* Allow message size to be overridden for dedicate cluster customers (PR [#63](https://github.com/pusher/pusher-http-go/pull/71)) + 4.0.3 / 2020-07-28 ================== * Added library name and version in HTTP Header (PR [#62](https://github.com/pusher/pusher-http-go/pull/62)) diff --git a/client.go b/client.go index 4f42ed6..de89a95 100644 --- a/client.go +++ b/client.go @@ -17,7 +17,7 @@ var pusherPathRegex = regexp.MustCompile("^/apps/([0-9]+)$") var maxTriggerableChannels = 100 const ( - libraryVersion = "4.0.3" + libraryVersion = "4.0.4" libraryName = "pusher-http-go" ) @@ -58,6 +58,7 @@ type Client struct { HTTPClient *http.Client EncryptionMasterKey string // deprecated EncryptionMasterKeyBase64 string // for E2E + OverrideMaxMessagePayloadKB int // set the agreed Pusher message limit increase validatedEncryptionMasterKey *[]byte // parsed key for use } @@ -200,7 +201,7 @@ func (c *Client) trigger(channels []string, eventName string, data interface{}, return err } - payload, err := encodeTriggerBody(channels, eventName, data, socketID, masterKey) + payload, err := encodeTriggerBody(channels, eventName, data, socketID, masterKey, c.OverrideMaxMessagePayloadKB) if err != nil { return err } @@ -250,7 +251,7 @@ func (c *Client) TriggerBatch(batch []Event) error { return keyErr } - payload, err := encodeTriggerBatchBody(batch, masterKey) + payload, err := encodeTriggerBatchBody(batch, masterKey, c.OverrideMaxMessagePayloadKB) if err != nil { return err } diff --git a/client_test.go b/client_test.go index 4c4f354..1bfc335 100644 --- a/client_test.go +++ b/client_test.go @@ -521,6 +521,17 @@ func TestDataSizeValidation(t *testing.T) { assert.EqualError(t, err, "Event payload exceeded maximum size (20481 bytes is too much)") } +func TestDataSizeOverridenValidation(t *testing.T) { + client := Client{AppID: "id", Key: "key", Secret: "secret", OverrideMaxMessagePayloadKB: 80} + data := strings.Repeat("a", 81920) + err := client.Trigger("channel", "event", data) + assert.NotContains(t, err.Error(), "\"Event payload exceeded maximum size (81921 bytes is too much)") + + data = strings.Repeat("a", 81921) + err = client.Trigger("channel", "event", data) + assert.EqualError(t, err, "Event payload exceeded maximum size (81921 bytes is too much)") +} + func TestInitialisationFromURL(t *testing.T) { url := "http://feaf18a411d3cb9216ee:fec81108d90e1898e17a@api.pusherapp.com/apps/104060" client, _ := ClientFromURL(url) diff --git a/encoder.go b/encoder.go index 425c763..4d6a5ab 100644 --- a/encoder.go +++ b/encoder.go @@ -6,8 +6,9 @@ import ( "fmt" ) -// maxEventPayloadSize indicates the max size allowed for the data content (payload) of each event -const maxEventPayloadSize = 20480 // on dedicated clusters we may allow 2x the usual limit +// defaultMaxEventPayloadSizeKB indicates the max size allowed for the data content +// (payload) of each event, unless an override is present in the client +const defaultMaxEventPayloadSizeKB = 10 type batchEvent struct { Channel string `json:"channel"` @@ -26,7 +27,14 @@ type eventPayload struct { SocketID *string `json:"socket_id,omitempty"` } -func encodeTriggerBody(channels []string, event string, data interface{}, socketID *string, encryptionKey []byte) ([]byte, error) { +func encodeTriggerBody( + channels []string, + event string, + data interface{}, + socketID *string, + encryptionKey []byte, + overrideMaxMessagePayloadKB int, +) ([]byte, error) { dataBytes, err := encodeEventData(data) if err != nil { return nil, err @@ -37,7 +45,14 @@ func encodeTriggerBody(channels []string, event string, data interface{}, socket } else { payloadData = string(dataBytes) } - if len(payloadData) > maxEventPayloadSize { + + eventExceedsMaximumSize := false + if overrideMaxMessagePayloadKB == 0 { + eventExceedsMaximumSize = len(payloadData) > defaultMaxEventPayloadSizeKB*1024 + } else { + eventExceedsMaximumSize = len(payloadData) > overrideMaxMessagePayloadKB*1024 + } + if eventExceedsMaximumSize { return nil, errors.New(fmt.Sprintf("Event payload exceeded maximum size (%d bytes is too much)", len(payloadData))) } return json.Marshal(&eventPayload{ @@ -48,7 +63,11 @@ func encodeTriggerBody(channels []string, event string, data interface{}, socket }) } -func encodeTriggerBatchBody(batch []Event, encryptionKey []byte) ([]byte, error) { +func encodeTriggerBatchBody( + batch []Event, + encryptionKey []byte, + overrideMaxMessagePayloadKB int, +) ([]byte, error) { batchEvents := make([]batchEvent, len(batch)) for idx, e := range batch { var stringifyedDataBytes string @@ -61,8 +80,14 @@ func encodeTriggerBatchBody(batch []Event, encryptionKey []byte) ([]byte, error) } else { stringifyedDataBytes = string(dataBytes) } - if len(stringifyedDataBytes) > maxEventPayloadSize { - return nil, fmt.Errorf("Data of the event #%d in batch, must be smaller than 10kb", idx) + eventExceedsMaximumSize := false + if overrideMaxMessagePayloadKB == 0 { + eventExceedsMaximumSize = len(stringifyedDataBytes) > defaultMaxEventPayloadSizeKB*1024 + } else { + eventExceedsMaximumSize = len(stringifyedDataBytes) > overrideMaxMessagePayloadKB*1024 + } + if eventExceedsMaximumSize { + return nil, fmt.Errorf("Data of the event #%d in batch, exceeded maximum size (%d bytes is too much)", idx, len(stringifyedDataBytes)) } newBatchEvent := batchEvent{ Channel: e.Channel, From 8557c5a509a070f996eec09148b491508d0900cb Mon Sep 17 00:00:00 2001 From: Luis Fonseca Date: Wed, 2 Sep 2020 15:46:27 +0100 Subject: [PATCH 2/2] Extend test coverage --- client_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/client_test.go b/client_test.go index 1bfc335..14df24c 100644 --- a/client_test.go +++ b/client_test.go @@ -519,17 +519,31 @@ func TestDataSizeValidation(t *testing.T) { err := client.Trigger("channel", "event", data) assert.EqualError(t, err, "Event payload exceeded maximum size (20481 bytes is too much)") + + err = client.TriggerBatch([]Event{ + {"channel", "event", data, nil}, + }) + assert.EqualError(t, err, "Data of the event #0 in batch, exceeded maximum size (20481 bytes is too much)") } func TestDataSizeOverridenValidation(t *testing.T) { client := Client{AppID: "id", Key: "key", Secret: "secret", OverrideMaxMessagePayloadKB: 80} data := strings.Repeat("a", 81920) err := client.Trigger("channel", "event", data) - assert.NotContains(t, err.Error(), "\"Event payload exceeded maximum size (81921 bytes is too much)") + assert.NotContains(t, err.Error(), "\"Event payload exceeded maximum size (81920 bytes is too much)") + err = client.TriggerBatch([]Event{ + {"channel", "event", data, nil}, + }) + assert.NotContains(t, err.Error(), "Data of the event #0 in batch, exceeded maximum size (81920 bytes is too much)") data = strings.Repeat("a", 81921) err = client.Trigger("channel", "event", data) assert.EqualError(t, err, "Event payload exceeded maximum size (81921 bytes is too much)") + + err = client.TriggerBatch([]Event{ + {"channel", "event", data, nil}, + }) + assert.EqualError(t, err, "Data of the event #0 in batch, exceeded maximum size (81921 bytes is too much)") } func TestInitialisationFromURL(t *testing.T) {