Skip to content

Commit 6fac5d1

Browse files
committed
Fix pubsub errors when receiving unencoded message. googleapis#2513.
1 parent 1d39cfd commit 6fac5d1

File tree

3 files changed

+26
-1
lines changed

3 files changed

+26
-1
lines changed

docs/pubsub-usage.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ Test permissions allowed by the current IAM policy on a topic:
8585
Publish messages to a topic
8686
---------------------------
8787

88+
.. note::
89+
If you're publishing a message from console.cloud.google.com, you will need
90+
to base64 encode the message first.
91+
8892
Publish a single message to a topic, without attributes:
8993

9094
.. literalinclude:: pubsub_snippets.py

pubsub/google/cloud/pubsub/message.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""Define API Topics."""
1616

1717
import base64
18+
import binascii
1819

1920
from google.cloud._helpers import _rfc3339_to_datetime
2021

@@ -85,7 +86,14 @@ def from_api_repr(cls, api_repr):
8586
:rtype: :class:`Message`
8687
:returns: The message created from the response.
8788
"""
88-
data = base64.b64decode(api_repr.get('data', b''))
89+
raw_data = api_repr.get('data', b'')
90+
try:
91+
data = base64.b64decode(raw_data)
92+
except (binascii.Error, TypeError):
93+
to_pad = (- len(raw_data)) % 4
94+
padded_data = raw_data + b'=' * to_pad
95+
data = base64.b64decode(padded_data)
96+
8997
instance = cls(
9098
data=data, message_id=api_repr['messageId'],
9199
attributes=api_repr.get('attributes'))

pubsub/unit_tests/test_message.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,19 @@ def test_from_api_repr_missing_data(self):
8989
self.assertEqual(message.attributes, {})
9090
self.assertIsNone(message.service_timestamp)
9191

92+
def test_from_api_repr_bad_b64_data(self):
93+
DATA = b'wefwefw'
94+
BAD_B64_DATA = b'd2Vmd2Vmdw='
95+
MESSAGE_ID = '12345'
96+
TIMESTAMP = '2016-03-18-19:38:22.001393427Z'
97+
api_repr = {
98+
'data': BAD_B64_DATA,
99+
'messageId': MESSAGE_ID,
100+
'publishTimestamp': TIMESTAMP,
101+
}
102+
message = self._getTargetClass().from_api_repr(api_repr)
103+
self.assertEqual(message.data, DATA)
104+
92105
def test_from_api_repr_no_attributes(self):
93106
from base64 import b64encode as b64
94107
DATA = b'DEADBEEF'

0 commit comments

Comments
 (0)