mirror of
https://github.com/waku-org/nwaku.git
synced 2025-02-26 14:00:57 +00:00
fix(rest): encode waku message payload in base64
This commit is contained in:
parent
842cfb3476
commit
791ce6d222
@ -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]
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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))
|
||||
))
|
||||
|
@ -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
|
||||
|
||||
|
||||
@ -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)
|
||||
@ -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
waku/v2/node/rest/base64.nim
Normal file
27
waku/v2/node/rest/base64.nim
Normal file
@ -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)
|
@ -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]
|
||||
@ -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))
|
||||
@ -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))
|
||||
@ -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)
|
||||
@ -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":
|
||||
|
@ -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"
|
||||
|
||||
@ -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()
|
||||
|
||||
|
@ -118,6 +118,7 @@ components:
|
||||
properties:
|
||||
payload:
|
||||
type: string
|
||||
format: byte
|
||||
contentTopic:
|
||||
$ref: '#/components/schemas/ContentTopic'
|
||||
version:
|
||||
|
@ -1,7 +1,7 @@
|
||||
{.push raises: [Defect].}
|
||||
|
||||
import std/typetraits
|
||||
import
|
||||
std/typetraits,
|
||||
stew/results,
|
||||
chronicles,
|
||||
serialization,
|
||||
|
Loading…
x
Reference in New Issue
Block a user