mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-05 23:13:09 +00:00
adds API for retrieving directory
This commit is contained in:
parent
07971fd566
commit
5def89126f
@ -39,8 +39,9 @@ import ../manifest
|
|||||||
import ../streams/asyncstreamwrapper
|
import ../streams/asyncstreamwrapper
|
||||||
import ../stores
|
import ../stores
|
||||||
import ../utils/options
|
import ../utils/options
|
||||||
|
|
||||||
# tarballs
|
# tarballs
|
||||||
import ../tarballs/directorymanifest
|
import ../tarballs/[directorymanifest, directorydownloader, tarballnodeextensions]
|
||||||
|
|
||||||
import ./coders
|
import ./coders
|
||||||
import ./json
|
import ./json
|
||||||
@ -156,6 +157,61 @@ proc retrieveCid(
|
|||||||
if not stream.isNil:
|
if not stream.isNil:
|
||||||
await stream.close()
|
await stream.close()
|
||||||
|
|
||||||
|
proc retrieveDirectory(
|
||||||
|
node: CodexNodeRef, cid: Cid, resp: HttpResponseRef
|
||||||
|
): Future[void] {.async: (raises: [CancelledError, HttpWriteError]).} =
|
||||||
|
## Download torrent from the node in a streaming
|
||||||
|
## manner
|
||||||
|
##
|
||||||
|
let directoryDownloader = newDirectoryDownloader(node)
|
||||||
|
|
||||||
|
var bytes = 0
|
||||||
|
try:
|
||||||
|
without directoryManifest =? (await node.fetchDirectoryManifest(cid)), err:
|
||||||
|
error "Unable to fetch Directory Metadata", err = err.msg
|
||||||
|
resp.status = Http404
|
||||||
|
await resp.sendBody(err.msg)
|
||||||
|
return
|
||||||
|
|
||||||
|
resp.addHeader("Content-Type", "application/octet-stream")
|
||||||
|
|
||||||
|
resp.setHeader(
|
||||||
|
"Content-Disposition", "attachment; filename=\"" & directoryManifest.name & "\""
|
||||||
|
)
|
||||||
|
|
||||||
|
# ToDo: add contentSize to the directory manifest
|
||||||
|
# let contentLength = codexManifest.datasetSize
|
||||||
|
# resp.setHeader("Content-Length", $(contentLength.int))
|
||||||
|
|
||||||
|
await resp.prepare(HttpResponseStreamType.Plain)
|
||||||
|
|
||||||
|
echo "streaming directory: ", cid
|
||||||
|
directoryDownloader.start(cid)
|
||||||
|
|
||||||
|
echo "streaming directory started: ", cid
|
||||||
|
await sleepAsync(1.seconds)
|
||||||
|
echo "after sleep..."
|
||||||
|
|
||||||
|
while true:
|
||||||
|
echo "getNext: ", directoryDownloader.queue.len, " entries in queue"
|
||||||
|
let data = await directoryDownloader.getNext()
|
||||||
|
echo "getNext[2]: ", data.len, " bytes"
|
||||||
|
await sleepAsync(1.seconds)
|
||||||
|
if data.len == 0:
|
||||||
|
break
|
||||||
|
bytes += data.len
|
||||||
|
await resp.sendChunk(addr data[0], data.len)
|
||||||
|
|
||||||
|
echo "out of loop: ", directoryDownloader.queue.len, " entries in queue"
|
||||||
|
await resp.finish()
|
||||||
|
codex_api_downloads.inc()
|
||||||
|
except CancelledError as exc:
|
||||||
|
info "Streaming directory cancelled", exc = exc.msg
|
||||||
|
raise exc
|
||||||
|
finally:
|
||||||
|
info "Sent bytes for directory", cid, bytes
|
||||||
|
await directoryDownloader.stop()
|
||||||
|
|
||||||
proc buildCorsHeaders(
|
proc buildCorsHeaders(
|
||||||
httpMethod: string, allowedOrigin: Option[string]
|
httpMethod: string, allowedOrigin: Option[string]
|
||||||
): seq[(string, string)] =
|
): seq[(string, string)] =
|
||||||
@ -421,6 +477,25 @@ proc initDataApi(node: CodexNodeRef, repoStore: RepoStore, router: var RestRoute
|
|||||||
resp.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
|
resp.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
|
||||||
await node.retrieveCid(cid.get(), local = false, resp = resp)
|
await node.retrieveCid(cid.get(), local = false, resp = resp)
|
||||||
|
|
||||||
|
router.api(MethodGet, "/api/codex/v1/dir/{cid}/network/stream") do(
|
||||||
|
cid: Cid, resp: HttpResponseRef
|
||||||
|
) -> RestApiResponse:
|
||||||
|
## Download a file from the network in a streaming
|
||||||
|
## manner
|
||||||
|
##
|
||||||
|
|
||||||
|
var headers = buildCorsHeaders("GET", allowedOrigin)
|
||||||
|
|
||||||
|
if cid.isErr:
|
||||||
|
return RestApiResponse.error(Http400, $cid.error(), headers = headers)
|
||||||
|
|
||||||
|
if corsOrigin =? allowedOrigin:
|
||||||
|
resp.setCorsHeaders("GET", corsOrigin)
|
||||||
|
resp.setHeader("Access-Control-Headers", "X-Requested-With")
|
||||||
|
|
||||||
|
resp.setHeader("Access-Control-Expose-Headers", "Content-Disposition")
|
||||||
|
await node.retrieveDirectory(cid.get(), resp = resp)
|
||||||
|
|
||||||
router.api(MethodGet, "/api/codex/v1/data/{cid}/network/manifest") do(
|
router.api(MethodGet, "/api/codex/v1/data/{cid}/network/manifest") do(
|
||||||
cid: Cid, resp: HttpResponseRef
|
cid: Cid, resp: HttpResponseRef
|
||||||
) -> RestApiResponse:
|
) -> RestApiResponse:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user