From e422c9065f4bfd2aefc8b8420d1d30d2bdffccc5 Mon Sep 17 00:00:00 2001 From: Eric <5089238+emizzle@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:33:21 +1000 Subject: [PATCH] config flag to enable CORS response headers for data downloads (#834) --- codex/codex.nim | 2 +- codex/conf.nim | 6 ++++++ codex/rest/api.nim | 23 +++++++++++++++++++++-- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/codex/codex.nim b/codex/codex.nim index 4ca6d63d..fa9d0c13 100644 --- a/codex/codex.nim +++ b/codex/codex.nim @@ -312,7 +312,7 @@ proc new*( taskpool = taskpool) restServer = RestServerRef.new( - codexNode.initRestApi(config, repoStore), + codexNode.initRestApi(config, repoStore, config.apiCorsAllowedOrigin), initTAddress(config.apiBindAddress , config.apiPort), bufferSize = (1024 * 64), maxRequestBodySize = int.high) diff --git a/codex/conf.nim b/codex/conf.nim index dffe4cdd..fb7548c7 100644 --- a/codex/conf.nim +++ b/codex/conf.nim @@ -190,6 +190,12 @@ type name: "api-port" abbr: "p" }: Port + apiCorsAllowedOrigin* {. + desc: "The REST Api CORS allowed origin for downloading data. '*' will allow all origins, '' will allow none.", + defaultValue: string.none + defaultValueDesc: "Disallow all cross origin requests to download data" + name: "api-cors-origin" }: Option[string] + repoKind* {. desc: "Backend for main repo store (fs, sqlite, leveldb)" defaultValueDesc: "fs" diff --git a/codex/rest/api.nim b/codex/rest/api.nim index 1cdc8ab9..6b258b22 100644 --- a/codex/rest/api.nim +++ b/codex/rest/api.nim @@ -107,6 +107,8 @@ proc retrieveCid( await stream.close() proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRouter) = + let allowedOrigin = router.allowedOrigin # prevents capture inside of api defintion + router.rawApi( MethodPost, "/api/codex/v1/data") do ( @@ -166,6 +168,12 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute Http400, $cid.error()) + if corsOrigin =? allowedOrigin: + resp.setHeader("Access-Control-Allow-Origin", corsOrigin) + resp.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS") + resp.setHeader("Access-Control-Headers", "X-Requested-With") + resp.setHeader("Access-Control-Max-Age", "86400") + await node.retrieveCid(cid.get(), local = true, resp=resp) router.api( @@ -181,6 +189,12 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute Http400, $cid.error()) + if corsOrigin =? allowedOrigin: + resp.setHeader("Access-Control-Allow-Origin", corsOrigin) + resp.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS") + resp.setHeader("Access-Control-Headers", "X-Requested-With") + resp.setHeader("Access-Control-Max-Age", "86400") + await node.retrieveCid(cid.get(), local = false, resp=resp) router.api( @@ -636,8 +650,13 @@ proc initDebugApi(node: CodexNodeRef, conf: CodexConf, router: var RestRouter) = trace "Excepting processing request", exc = exc.msg return RestApiResponse.error(Http500) -proc initRestApi*(node: CodexNodeRef, conf: CodexConf, repoStore: RepoStore): RestRouter = - var router = RestRouter.init(validate) +proc initRestApi*( + node: CodexNodeRef, + conf: CodexConf, + repoStore: RepoStore, + corsAllowedOrigin: ?string): RestRouter = + + var router = RestRouter.init(validate, corsAllowedOrigin) initDataApi(node, repoStore, router) initSalesApi(node, router)