diff --git a/packages/siaviewnode-client/src/components/Dropzone.tsx b/packages/siaviewnode-client/src/components/Dropzone.tsx index f81d9217..07b41d04 100644 --- a/packages/siaviewnode-client/src/components/Dropzone.tsx +++ b/packages/siaviewnode-client/src/components/Dropzone.tsx @@ -1,10 +1,10 @@ /** @jsx jsx */ import * as R from "ramda" -import { useCallback, useState } from "react" +import { useCallback, useState, useRef } from "react" import { useDropzone } from "react-dropzone" import { Box, Flex, jsx } from "theme-ui" -import { CircularProgress } from "@material-ui/core" - +import { CircularProgress, Button } from "@material-ui/core" +import { saveAs } from "file-saver" /** * nginx is setup to automatically handle and rewrite the url path. */ @@ -18,83 +18,62 @@ const splitFilename = R.compose(R.head, R.split(".sia")) function MyDropzone() { const [loading, setLoading] = useState(false) const [error, setError] = useState(null) + const formRef = useRef(null) + const inputRef = useRef(null) + const onDrop = useCallback( acceptedFiles => { setLoading(true) const file = R.head(acceptedFiles) - const fd = new FormData() + const fd = new FormData(formRef.current) const fileName = R.compose(splitFilename, pName)(file) - fd.append("file", file) - if (window) { - const streamSaver = require("streamsaver") - console.log("streamSaver", streamSaver) - const url = API_ENDPOINT + "/siafile" - fetch(url, { - method: "POST", - body: fd, - headers: { - "Access-Control-Allow-Origin": "*" - } - }) - .then(res => { - if (!res.ok) { - setLoading(false) - setError(res.status + " " + res.statusText) - return - } - const readableStream = res.body - const fileStream = streamSaver.createWriteStream(fileName) + const url = API_ENDPOINT + "/siafile" - // more optimized - if (window.WritableStream && readableStream.pipeTo) { - return readableStream.pipeTo(fileStream).then(() => { - setLoading(false) - console.log("done writing") - }) - } - ;(window as any).writer = fileStream.getWriter() - const reader = res.body.getReader() - const pump = () => - reader - .read() - .then(res => - res.done - ? (window as any).writer.close() - : (window as any).writer.write(res.value).then(pump) - ) - .catch(e => { - setLoading(false) - }) - pump() - }) - .catch(e => { - // setError(e) - console.log("error is", e) - setLoading(false) - }) - } + // formRef.current.submit() + + // fetch(url, { + // method: "POST", + // body: fd, + // credentials: "include" + // }) + // .then(res => { + // return res.headers + // }) + // .then(headers => { + // console.log("WE OUT HERE BOYS", document.cookie) + // fetch(API_ENDPOINT + "/siafile/download", { + // credentials: "include" + // }) + // .then(res => res.blob()) + // .then(blob => saveAs(blob, fileName)) + // // saveAs(API_ENDPOINT + "/siafile/download", fileName) + // }) + // .catch(e => { + // console.log("error is", e) + // setLoading(false) + // }) }, - [loading, setLoading, error, setError] + [loading, setLoading, error, setError, formRef] ) + const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop }) return ( - - {error && error} - {!error && - (loading ? ( - - ) : isDragActive ? ( -

Drop to 🚀 ...

- ) : ( -

Drag 'n' drop a Sia file here, or click to select a Sia file.

- ))} +
+ + +
) diff --git a/packages/siaviewnode-server/package.json b/packages/siaviewnode-server/package.json index 4c2fb96d..6cf75978 100644 --- a/packages/siaviewnode-server/package.json +++ b/packages/siaviewnode-server/package.json @@ -15,10 +15,11 @@ "cors": "2.8.5", "express": "^4.14.0", "express-fileupload": "1.1.6", + "express-session": "1.17.0", "ramda": "0.26.1", "typescript": "^3.5.2" }, "devDependencies": { "@types/ramda": "0.26.36" } -} \ No newline at end of file +} diff --git a/packages/siaviewnode-server/src/main.ts b/packages/siaviewnode-server/src/main.ts index 168bb3f3..e557edf4 100644 --- a/packages/siaviewnode-server/src/main.ts +++ b/packages/siaviewnode-server/src/main.ts @@ -52,16 +52,24 @@ export class Server { private getPort = (): number => parseInt(process.env.PORT, 10) || 3000 private setRoutes = (): void => { - this.app.use(cors()) + this.app.use( + cors({ + origin: "http://localhost:*", + credentials: true + }) + ) this.app.use( fileUpload({ limits: { fileSize: 10 * 1024 * 1024 } }) ) - this.app.post("/siafile", this.getSiaFile) + this.app.post("/siafile", this.postSiaFile) + this.app.get("/siafile/download", this.downloadSiaFile) } - private async getSiaFile( + private async downloadSiaFile(req, res) {} + + private async postSiaFile( req: express.Request & any, res: express.Response ): Promise { @@ -69,19 +77,33 @@ export class Server { try { const file: any = selectFile(req) - const { data: stream } = await siad.post("/renter/stream", file.data, { - headers: { - "Content-Type": "multipart/form-data" - }, - responseType: "stream" - }) + const selectContentLength = R.path(["headers", "Content-Length"]) + const cl = selectContentLength(req) + console.log("cl is", cl) - res.attachment(file.name) - res.set("Content-Type", "application/octet-stream") + console.log("file is", file) + const { data: stream, headers } = await siad.post( + "/renter/stream", + file.data, + { + responseType: "stream" + } + ) + const contentLength = headers["Content-Length"] + + const pName = R.prop("name") + const splitFilename = R.compose(R.head, R.split(".sia")) + const fileName = R.compose(splitFilename, pName)(file) + + res.set( + "Content-Disposition", + `attachment; filename="${fileName}"; filename*="${fileName}"` + ) + res.set("Content-Length", contentLength) stream.pipe(res) } catch (e) { - console.log("e is", e) + console.log("postSiaFile err:", e) return res.json({ error: e.message }) } } diff --git a/yarn.lock b/yarn.lock index 24b66fb3..3f006b64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3880,6 +3880,11 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + deprecation@^2.0.0: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -4270,6 +4275,20 @@ express-fileupload@1.1.6: dependencies: busboy "^0.3.1" +express-session@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.0.tgz#9b50dbb5e8a03c3537368138f072736150b7f9b3" + integrity sha512-t4oX2z7uoSqATbMfsxWMbNjAL0T5zpvcJCk3Z9wnPPN7ibddhnmDZXHfEcoBMG2ojKXZoCyPMc5FbtK+G7SoDg== + dependencies: + cookie "0.4.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.0" + uid-safe "~2.1.5" + express@^4.14.0: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -7897,6 +7916,11 @@ ramda@0.26.1, ramda@^0.26.1: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha1-T2ih3Arli9P7lYSMMDJNt11kNgs= + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -8366,7 +8390,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== @@ -9295,6 +9319,13 @@ uid-number@0.0.6: resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + umask@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d"