mirror of
https://github.com/waku-org/nwaku.git
synced 2025-03-01 07:20:54 +00:00
chore: Allow text/plain content type descriptor for json formatted content body (#2209)
* Allow text/plain content type descriptor for json formatted content body. Refactored duplicated encode/decode functions for rest api * Fix relay endpoint decodings of content bodies to accept text/plain * Added support for content body decoder for checking media type if additional parameters are present * Fix wrong usage of ContentTypeData - appeared only for tests
This commit is contained in:
parent
2cb0989a28
commit
6d81e3841a
@ -13,6 +13,7 @@ import
|
||||
import
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -21,37 +22,9 @@ export types
|
||||
logScope:
|
||||
topics = "waku node rest admin api"
|
||||
|
||||
proc decodeBytes*(t: typedesc[seq[WakuPeer]], data: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[seq[WakuPeer]] =
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported response contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = decodeFromJsonBytes(seq[WakuPeer], data).valueOr:
|
||||
return err("Invalid response from server, could not decode.")
|
||||
|
||||
return ok(decoded)
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
proc encodeBytes*(value: seq[string],
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
proc getPeers*():
|
||||
RestResponse[seq[WakuPeer]]
|
||||
|
@ -21,6 +21,7 @@ import
|
||||
../../../node/peer_manager,
|
||||
../responses,
|
||||
../serdes,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -32,23 +33,6 @@ const ROUTE_ADMIN_V1_PEERS* = "/admin/v1/peers"
|
||||
|
||||
type PeerProtocolTuple = tuple[multiaddr: string, protocol: string, connected: bool]
|
||||
|
||||
func decodeRequestBody[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
||||
if contentBody.isNone():
|
||||
return err(RestApiResponse.badRequest("Missing content body"))
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json"))
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
|
||||
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
||||
if requestResult.isErr():
|
||||
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
||||
$requestResult.error))
|
||||
|
||||
return ok(requestResult.get())
|
||||
|
||||
proc tuplesToWakuPeers(peers: var WakuPeers, peersTup: seq[PeerProtocolTuple]) =
|
||||
for peer in peersTup:
|
||||
peers.add(peer.multiaddr, peer.protocol, peer.connected)
|
||||
|
@ -11,6 +11,7 @@ import
|
||||
import
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -19,31 +20,8 @@ export types
|
||||
logScope:
|
||||
topics = "waku node rest debug_api"
|
||||
|
||||
|
||||
proc decodeBytes*(t: typedesc[DebugWakuInfo], data: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[DebugWakuInfo] =
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported respose contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(DebugWakuInfo, data)
|
||||
return ok(decoded)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc debugInfoV1*(): RestResponse[DebugWakuInfo] {.rest, endpoint: "/debug/v1/info", meth: HttpMethod.MethodGet.}
|
||||
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc debugVersionV1*(): RestResponse[string] {.rest, endpoint: "/debug/v1/version", meth: HttpMethod.MethodGet.}
|
||||
|
@ -16,6 +16,7 @@ import
|
||||
../../../waku_core,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -25,52 +26,19 @@ logScope:
|
||||
|
||||
proc encodeBytes*(value: FilterSubscribeRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
proc encodeBytes*(value: FilterSubscriberPing,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
proc encodeBytes*(value: FilterUnsubscribeRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
proc encodeBytes*(value: FilterUnsubscribeAllRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
|
||||
proc decodeBytes*(t: typedesc[FilterSubscriptionResponse],
|
||||
value: openarray[byte],
|
||||
contentType: Opt[ContentTypeData]):
|
||||
|
||||
RestResult[FilterSubscriptionResponse] =
|
||||
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(FilterSubscriptionResponse, value)
|
||||
return ok(decoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
proc filterSubscriberPing*(requestId: string):
|
||||
RestResponse[FilterSubscriptionResponse]
|
||||
@ -92,16 +60,6 @@ proc filterDeleteAllSubscriptions*(body: FilterUnsubscribeAllRequest):
|
||||
RestResponse[FilterSubscriptionResponse]
|
||||
{.rest, endpoint: "/filter/v2/subscriptions/all", meth: HttpMethod.MethodDelete.}
|
||||
|
||||
proc decodeBytes*(t: typedesc[FilterGetMessagesResponse],
|
||||
data: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[FilterGetMessagesResponse] =
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported response contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(FilterGetMessagesResponse, data)
|
||||
return ok(decoded)
|
||||
|
||||
proc filterGetMessagesV1*(contentTopic: string):
|
||||
RestResponse[FilterGetMessagesResponse]
|
||||
{.rest, endpoint: "/filter/v2/messages/{contentTopic}", meth: HttpMethod.MethodGet.}
|
||||
|
@ -24,6 +24,7 @@ import
|
||||
../../handlers,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -44,23 +45,6 @@ const filterMessageCacheDefaultCapacity* = 30
|
||||
type
|
||||
MessageCache* = message_cache.MessageCache[ContentTopic]
|
||||
|
||||
func decodeRequestBody[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
||||
if contentBody.isNone():
|
||||
return err(RestApiResponse.badRequest("Missing content body"))
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json"))
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
|
||||
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
||||
if requestResult.isErr():
|
||||
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
||||
$requestResult.error))
|
||||
|
||||
return ok(requestResult.get())
|
||||
|
||||
proc getErrorCause(err: filter_protocol_type.FilterSubscribeError): string =
|
||||
## Retrieve proper error cause of FilterSubscribeError - due stringify make some parts of text double
|
||||
|
||||
|
@ -14,6 +14,7 @@ import
|
||||
../../../waku_core,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -23,24 +24,7 @@ logScope:
|
||||
|
||||
proc encodeBytes*(value: FilterLegacySubscribeRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openarray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc filterPostSubscriptionsV1*(body: FilterLegacySubscribeRequest):
|
||||
@ -52,16 +36,6 @@ proc filterDeleteSubscriptionsV1*(body: FilterLegacySubscribeRequest):
|
||||
RestResponse[string]
|
||||
{.rest, endpoint: "/filter/v1/subscriptions", meth: HttpMethod.MethodDelete.}
|
||||
|
||||
proc decodeBytes*(t: typedesc[FilterGetMessagesResponse],
|
||||
data: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[FilterGetMessagesResponse] =
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported response contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(FilterGetMessagesResponse, data)
|
||||
return ok(decoded)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc filterGetMessagesV1*(contentTopic: string):
|
||||
RestResponse[FilterGetMessagesResponse]
|
||||
|
@ -20,6 +20,7 @@ import
|
||||
../../message_cache,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -38,23 +39,6 @@ const filterMessageCacheDefaultCapacity* = 30
|
||||
type
|
||||
MessageCache* = message_cache.MessageCache[ContentTopic]
|
||||
|
||||
func decodeRequestBody[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
||||
if contentBody.isNone():
|
||||
return err(RestApiResponse.badRequest("Missing content body"))
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json"))
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
|
||||
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
||||
if requestResult.isErr():
|
||||
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
||||
$requestResult.error))
|
||||
|
||||
return ok(requestResult.get())
|
||||
|
||||
proc installFilterV1PostSubscriptionsV1Handler*(router: var RestRouter,
|
||||
node: WakuNode,
|
||||
cache: MessageCache) =
|
||||
|
@ -10,21 +10,10 @@ import
|
||||
presto/[route, client]
|
||||
import
|
||||
../serdes,
|
||||
../responses
|
||||
../responses,
|
||||
../rest_serdes
|
||||
|
||||
logScope:
|
||||
topics = "waku node rest health_api"
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
proc healthCheck*(): RestResponse[string] {.rest, endpoint: "/health", meth: HttpMethod.MethodGet.}
|
||||
|
@ -16,6 +16,7 @@ import
|
||||
../../../waku_core,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -25,24 +26,8 @@ logScope:
|
||||
|
||||
proc encodeBytes*(value: PushRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openarray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
proc sendPushRequest*(body: PushRequest):
|
||||
RestResponse[string]
|
||||
|
@ -21,6 +21,7 @@ import
|
||||
../../handlers,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -40,23 +41,6 @@ const NoPeerNoneFoundError = RestApiResponse.serviceUnavailable(
|
||||
|
||||
const ROUTE_LIGHTPUSH* = "/lightpush/v1/message"
|
||||
|
||||
func decodeRequestBody[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
||||
if contentBody.isNone():
|
||||
return err(RestApiResponse.badRequest("Missing content body"))
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json"))
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
|
||||
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
||||
if requestResult.isErr():
|
||||
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
||||
$requestResult.error))
|
||||
|
||||
return ok(requestResult.get())
|
||||
|
||||
proc installLightPushRequestHandler*(
|
||||
router: var RestRouter,
|
||||
node: WakuNode,
|
||||
|
@ -14,6 +14,7 @@ import
|
||||
../../../waku_core,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
export types
|
||||
@ -25,24 +26,7 @@ logScope:
|
||||
|
||||
proc encodeBytes*(value: seq[PubSubTopic],
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openarray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc relayPostSubscriptionsV1*(body: seq[PubsubTopic]): RestResponse[string] {.rest, endpoint: "/relay/v1/subscriptions", meth: HttpMethod.MethodPost.}
|
||||
@ -52,22 +36,9 @@ proc relayPostAutoSubscriptionsV1*(body: seq[ContentTopic]): RestResponse[string
|
||||
proc relayDeleteSubscriptionsV1*(body: seq[PubsubTopic]): RestResponse[string] {.rest, endpoint: "/relay/v1/subscriptions", meth: HttpMethod.MethodDelete.}
|
||||
proc relayDeleteAutoSubscriptionsV1*(body: seq[ContentTopic]): RestResponse[string] {.rest, endpoint: "/relay/v1/auto/subscriptions", meth: HttpMethod.MethodDelete.}
|
||||
|
||||
proc decodeBytes*(t: typedesc[RelayGetMessagesResponse], data: openArray[byte], contentType: Opt[ContentTypeData]): RestResult[RelayGetMessagesResponse] =
|
||||
if MediaType.init($contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported respose contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(RelayGetMessagesResponse, data)
|
||||
return ok(decoded)
|
||||
|
||||
proc encodeBytes*(value: RelayPostMessagesRequest,
|
||||
contentType: string): RestResult[seq[byte]] =
|
||||
if MediaType.init(contentType) != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
return encodeBytesOf(value, contentType)
|
||||
|
||||
# TODO: Check how we can use a constant to set the method endpoint (improve "rest" pragma under nim-presto)
|
||||
proc relayGetMessagesV1*(pubsubTopic: string): RestResponse[RelayGetMessagesResponse] {.rest, endpoint: "/relay/v1/messages/{pubsubTopic}", meth: HttpMethod.MethodGet.}
|
||||
|
@ -20,6 +20,7 @@ import
|
||||
../../handlers,
|
||||
../serdes,
|
||||
../responses,
|
||||
../rest_serdes,
|
||||
./types
|
||||
|
||||
from std/times import getTime
|
||||
@ -55,16 +56,8 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(seq[PubsubTopic], reqBodyData)
|
||||
if reqResult.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let req: seq[PubsubTopic] = reqResult.get()
|
||||
let req: seq[PubsubTopic] = decodeRequestBody[seq[PubsubTopic]](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
# Only subscribe to topics for which we have no subscribed topic handlers yet
|
||||
let newTopics = req.filterIt(not cache.isSubscribed(it))
|
||||
@ -83,16 +76,8 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(seq[PubsubTopic], reqBodyData)
|
||||
if reqResult.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let req: seq[PubsubTopic] = reqResult.get()
|
||||
let req: seq[PubsubTopic] = decodeRequestBody[seq[PubsubTopic]](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
# Unsubscribe all handlers from requested topics
|
||||
for pubsubTopic in req:
|
||||
@ -139,21 +124,12 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return RestApiResponse.badRequest()
|
||||
let reqWakuMessage: RelayWakuMessage = decodeRequestBody[RelayWakuMessage](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(RelayPostMessagesRequest, reqBodyData)
|
||||
if reqResult.isErr():
|
||||
var message: WakuMessage = reqWakuMessage.toWakuMessage(version = 0).valueOr:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let resMessage = reqResult.value.toWakuMessage(version = 0)
|
||||
if resMessage.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
var message = resMessage.get()
|
||||
|
||||
# if RLN is mounted, append the proof to the message
|
||||
if not node.wakuRlnRelay.isNil():
|
||||
# append the proof to the message
|
||||
@ -191,16 +167,8 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(seq[ContentTopic], reqBodyData)
|
||||
if reqResult.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let req: seq[ContentTopic] = reqResult.get()
|
||||
let req: seq[ContentTopic] = decodeRequestBody[seq[ContentTopic]](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
# Only subscribe to topics for which we have no subscribed topic handlers yet
|
||||
let newTopics = req.filterIt(not cache.isSubscribed(it))
|
||||
@ -219,16 +187,8 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(seq[ContentTopic], reqBodyData)
|
||||
if reqResult.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let req: seq[ContentTopic] = reqResult.get()
|
||||
let req: seq[ContentTopic] = decodeRequestBody[seq[ContentTopic]](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
# Unsubscribe all handlers from requested topics
|
||||
for contentTopic in req:
|
||||
@ -266,24 +226,15 @@ proc installRelayApiHandlers*(router: var RestRouter, node: WakuNode, cache: Mes
|
||||
if contentBody.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyContentType = MediaType.init($contentBody.get().contentType)
|
||||
if reqBodyContentType != MIMETYPE_JSON:
|
||||
let req: RelayWakuMessage = decodeRequestBody[RelayWakuMessage](contentBody).valueOr:
|
||||
return error
|
||||
|
||||
if req.contentTopic.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
let reqResult = decodeFromJsonBytes(RelayPostMessagesRequest, reqBodyData)
|
||||
if reqResult.isErr():
|
||||
var message: WakuMessage = req.toWakuMessage(version = 0).valueOr:
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
if reqResult.value.contentTopic.isNone():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
let resMessage = reqResult.value.toWakuMessage(version = 0)
|
||||
if resMessage.isErr():
|
||||
return RestApiResponse.badRequest()
|
||||
|
||||
var message = resMessage.get()
|
||||
|
||||
# if RLN is mounted, append the proof to the message
|
||||
if not node.wakuRlnRelay.isNil():
|
||||
# append the proof to the message
|
||||
|
79
waku/waku_api/rest/rest_serdes.nim
Normal file
79
waku/waku_api/rest/rest_serdes.nim
Normal file
@ -0,0 +1,79 @@
|
||||
when (NimMajor, NimMinor) < (1, 4):
|
||||
{.push raises: [Defect].}
|
||||
else:
|
||||
{.push raises: [].}
|
||||
|
||||
import
|
||||
std/typetraits,
|
||||
std/os,
|
||||
stew/results,
|
||||
chronicles,
|
||||
serialization,
|
||||
json_serialization,
|
||||
json_serialization/std/options,
|
||||
json_serialization/std/net,
|
||||
json_serialization/std/sets,
|
||||
presto/common
|
||||
|
||||
import
|
||||
./serdes,
|
||||
./responses
|
||||
|
||||
logScope:
|
||||
topics = "waku node rest"
|
||||
|
||||
proc encodeBytesOf*[T](value: T,
|
||||
contentType: string): RestResult[seq[byte]]=
|
||||
let reqContentType = MediaType.init(contentType)
|
||||
|
||||
if reqContentType != MIMETYPE_JSON:
|
||||
error "Unsupported contentType value", contentType = contentType, typ = value.type.name
|
||||
return err("Unsupported contentType")
|
||||
|
||||
let encoded = ?encodeIntoJsonBytes(value)
|
||||
return ok(encoded)
|
||||
|
||||
func decodeRequestBody*[T](contentBody: Option[ContentBody]) : Result[T, RestApiResponse] =
|
||||
if contentBody.isNone():
|
||||
return err(RestApiResponse.badRequest("Missing content body"))
|
||||
|
||||
let reqBodyContentType = contentBody.get().contentType.mediaType
|
||||
|
||||
if reqBodyContentType != MIMETYPE_JSON and reqBodyContentType != MIMETYPE_TEXT:
|
||||
return err(RestApiResponse.badRequest("Wrong Content-Type, expected application/json or text/plain"))
|
||||
|
||||
let reqBodyData = contentBody.get().data
|
||||
|
||||
let requestResult = decodeFromJsonBytes(T, reqBodyData)
|
||||
if requestResult.isErr():
|
||||
return err(RestApiResponse.badRequest("Invalid content body, could not decode. " &
|
||||
$requestResult.error))
|
||||
|
||||
return ok(requestResult.get())
|
||||
|
||||
proc decodeBytes*(t: typedesc[string], value: openarray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[string] =
|
||||
if MediaType.init($contentType) != MIMETYPE_TEXT:
|
||||
error "Unsupported contentType value", contentType = contentType
|
||||
return err("Unsupported contentType")
|
||||
|
||||
var res: string
|
||||
if len(value) > 0:
|
||||
res = newString(len(value))
|
||||
copyMem(addr res[0], unsafeAddr value[0], len(value))
|
||||
return ok(res)
|
||||
|
||||
proc decodeBytes*[T](t: typedesc[T],
|
||||
data: openArray[byte],
|
||||
contentType: Opt[ContentTypeData]): RestResult[T] =
|
||||
|
||||
let reqContentType = contentType.valueOr():
|
||||
error "Unsupported response, missing contentType value"
|
||||
return err("Unsupported response, missing contentType")
|
||||
|
||||
if reqContentType.mediaType != MIMETYPE_JSON and reqContentType.mediaType != MIMETYPE_TEXT:
|
||||
error "Unsupported response contentType value", contentType = contentType
|
||||
return err("Unsupported response contentType")
|
||||
|
||||
let decoded = ?decodeFromJsonBytes(T, data)
|
||||
return ok(decoded)
|
@ -15,6 +15,7 @@ import
|
||||
json_serialization/std/sets,
|
||||
presto/common
|
||||
|
||||
|
||||
logScope:
|
||||
topics = "waku node rest"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user