Skip to content

Commit

Permalink
fix(rest): encode waku message payload in base64
Browse files Browse the repository at this point in the history
  • Loading branch information
Lorenzo Delgado authored and LNSD committed Aug 30, 2022
1 parent 842cfb3 commit 791ce6d
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 39 deletions.
8 changes: 4 additions & 4 deletions tests/v2/test_rest_relay_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import
libp2p/protocols/pubsub/pubsub
import
../../waku/v2/node/wakunode2,
../../waku/v2/node/rest/[server, client, utils],
../../waku/v2/node/rest/[server, client, base64, utils],
../../waku/v2/node/rest/relay/[api_types, relay_api, topic_cache]


Expand Down Expand Up @@ -164,8 +164,8 @@ suite "REST API - Relay":
response.contentType == $MIMETYPE_JSON
response.data.len == 3
response.data.all do (msg: RelayWakuMessage) -> bool:
msg.payload == "TEST-1" and
string(msg.contentTopic.get()) == "content-topic-x" and
msg.payload == Base64String.encode("TEST-1") and
msg.contentTopic.get().string == "content-topic-x" and
msg.version.get() == Natural(1) and
msg.timestamp.get() == int64(2022)

Expand Down Expand Up @@ -211,7 +211,7 @@ suite "REST API - Relay":
discard await client.relayPostSubscriptionsV1(newTopics)

let response = await client.relayPostMessagesV1(defaultTopic, RelayWakuMessage(
payload: "TEST-PAYLOAD",
payload: Base64String.encode("TEST-PAYLOAD"),
contentTopic: some(ContentTopicString(defaultContentTopic)),
timestamp: some(int64(2022))
))
Expand Down
27 changes: 15 additions & 12 deletions tests/v2/test_rest_relay_api_serdes.nim
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{.used.}

import std/typetraits
import chronicles,
unittest2,
import
stew/[results, byteutils],
chronicles,
unittest2,
json_serialization
import
../../waku/v2/node/rest/serdes,
../../waku/v2/node/rest/base64,
../../waku/v2/node/rest/relay/api_types


Expand All @@ -15,25 +16,27 @@ suite "Relay API - serialization":
suite "RelayWakuMessage - decode":
test "optional fields are not provided":
# Given
let jsonBytes = toBytes("""{ "payload": "MESSAGE" }""")
let payload = Base64String.encode("MESSAGE")
let jsonBytes = toBytes("{\"payload\":\"" & $payload & "\"}")

# When
let res = decodeFromJsonBytes(RelayWakuMessage, jsonBytes, requireAllFields = true)

# Then
require(res.isOk)
require(res.isOk())
let value = res.get()
check:
value.payload == "MESSAGE"
value.contentTopic.isNone
value.version.isNone
value.timestamp.isNone
value.payload == payload
value.contentTopic.isNone()
value.version.isNone()
value.timestamp.isNone()

suite "RelayWakuMessage - encode":
test "optional fields are none":
# Given
let payload = Base64String.encode("MESSAGE")
let data = RelayWakuMessage(
payload: "MESSAGE",
payload: payload,
contentTopic: none(ContentTopicString),
version: none(Natural),
timestamp: none(int64)
Expand All @@ -43,7 +46,7 @@ suite "Relay API - serialization":
let res = encodeIntoJsonBytes(data)

# Then
require(res.isOk)
require(res.isOk())
let value = res.get()
check:
value == toBytes("""{"payload":"MESSAGE"}""")
value == toBytes("{\"payload\":\"" & $payload & "\"}")
27 changes: 27 additions & 0 deletions waku/v2/node/rest/base64.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{.push raises: [Defect].}

import stew/[results, byteutils, base64]


type Base64String* = distinct string


proc encode*(t: type Base64String, value: string|seq[byte]): Base64String =
let val = block:
when value is string:
toBytes(value)
else:
value
Base64String(base64.encode(Base64, val))

proc decode*(t: Base64String): Result[seq[byte], cstring] =
try:
ok(base64.decode(Base64, string(t)))
except:
err("failed to decode base64 string")

proc `$`*(t: Base64String): string {.inline.}=
string(t)

proc `==`*(lhs: Base64String|string, rhs: Base64String|string): bool {.inline.}=
string(lhs) == string(rhs)
45 changes: 28 additions & 17 deletions waku/v2/node/rest/relay/api_types.nim
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
{.push raises: [ Defect ].}
{.push raises: [Defect].}

import
std/[sets, strformat],
stew/byteutils,
chronicles,
json_serialization,
json_serialization/std/options,
presto/[route, client, common]
import ".."/serdes
import ../../wakunode2
import
../../../protocol/waku_message,
../serdes,
../base64


#### Types

type
PubSubTopicString* = distinct string
ContentTopicString* = distinct string
PubSubTopicString* = distinct string
ContentTopicString* = distinct string

type RelayWakuMessage* = object
payload*: string
payload*: Base64String
contentTopic*: Option[ContentTopicString]
version*: Option[Natural]
timestamp*: Option[int64]
Expand All @@ -37,23 +38,29 @@ type

proc toRelayWakuMessage*(msg: WakuMessage): RelayWakuMessage =
RelayWakuMessage(
payload: string.fromBytes(msg.payload),
payload: base64.encode(Base64String, msg.payload),
contentTopic: some(ContentTopicString(msg.contentTopic)),
version: some(Natural(msg.version)),
timestamp: some(msg.timestamp)
)

proc toWakuMessage*(msg: RelayWakuMessage, version = 0): WakuMessage =
proc toWakuMessage*(msg: RelayWakuMessage, version = 0): Result[WakuMessage, cstring] =
const defaultContentTopic = ContentTopicString("/waku/2/default-content/proto")
WakuMessage(
payload: msg.payload.toBytes(),
contentTopic: ContentTopic(msg.contentTopic.get(defaultContentTopic)),
version: uint32(msg.version.get(version)),
timestamp: msg.timestamp.get(0)
)
let
payload = ?msg.payload.decode()
contentTopic = ContentTopic(msg.contentTopic.get(defaultContentTopic))
version = uint32(msg.version.get(version))
timestamp = msg.timestamp.get(0)

ok(WakuMessage(payload: payload, contentTopic: contentTopic, version: version, timestamp: timestamp))


#### Serialization and deserialization

proc writeValue*(writer: var JsonWriter[RestJson], value: Base64String)
{.raises: [IOError, Defect].} =
writer.writeValue(string(value))

proc writeValue*(writer: var JsonWriter[RestJson], value: PubSubTopicString)
{.raises: [IOError, Defect].} =
writer.writeValue(string(value))
Expand All @@ -74,6 +81,10 @@ proc writeValue*(writer: var JsonWriter[RestJson], value: RelayWakuMessage)
writer.writeField("timestamp", value.timestamp)
writer.endRecord()

proc readValue*(reader: var JsonReader[RestJson], value: var Base64String)
{.raises: [SerializationError, IOError, Defect].} =
value = Base64String(reader.readValue(string))

proc readValue*(reader: var JsonReader[RestJson], value: var PubSubTopicString)
{.raises: [SerializationError, IOError, Defect].} =
value = PubSubTopicString(reader.readValue(string))
Expand All @@ -85,7 +96,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var ContentTopicString)
proc readValue*(reader: var JsonReader[RestJson], value: var RelayWakuMessage)
{.raises: [SerializationError, IOError, Defect].} =
var
payload = none(string)
payload = none(Base64String)
contentTopic = none(ContentTopicString)
version = none(Natural)
timestamp = none(int64)
Expand All @@ -100,7 +111,7 @@ proc readValue*(reader: var JsonReader[RestJson], value: var RelayWakuMessage)

case fieldName
of "payload":
payload = some(reader.readValue(string))
payload = some(reader.readValue(Base64String))
of "contentTopic":
contentTopic = some(reader.readValue(ContentTopicString))
of "version":
Expand Down
15 changes: 10 additions & 5 deletions waku/v2/node/rest/relay/relay_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import
json_serialization,
json_serialization/std/options,
presto/[route, client, common]
import ".."/[serdes, utils]
import ../../wakunode2
import "."/[api_types, topic_cache]
import
../../wakunode2,
../serdes,
../utils,
./api_types,
./topic_cache

logScope: topics = "rest_api_relay"

Expand Down Expand Up @@ -130,9 +133,11 @@ proc installRelayPostMessagesV1Handler*(router: var RestRouter, node: WakuNode)
if reqResult.isErr():
return RestApiResponse.badRequest()

let message: RelayPostMessagesRequest = reqResult.get()
let resMessage = reqResult.value.toWakuMessage(version = 0)
if resMessage.isErr():
return RestApiResponse.badRequest()

if not (waitFor node.publish(pubSubTopic, message.toWakuMessage(version = 0)).withTimeout(futTimeout)):
if not (waitFor node.publish(pubSubTopic, resMessage.value).withTimeout(futTimeout)):
error "Failed to publish message to topic", topic=pubSubTopic
return RestApiResponse.internalServerError()

Expand Down
1 change: 1 addition & 0 deletions waku/v2/node/rest/relay/relay_api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ components:
properties:
payload:
type: string
format: byte
contentTopic:
$ref: '#/components/schemas/ContentTopic'
version:
Expand Down
2 changes: 1 addition & 1 deletion waku/v2/node/rest/serdes.nim
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{.push raises: [Defect].}

import std/typetraits
import
std/typetraits,
stew/results,
chronicles,
serialization,
Expand Down

0 comments on commit 791ce6d

Please sign in to comment.