w-converhp 2.0.35 → 2.0.37
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/w-converhp-client.umd.js +2 -2
- package/dist/w-converhp-client.umd.js.map +1 -1
- package/dist/w-converhp-server.umd.js +2 -2
- package/dist/w-converhp-server.umd.js.map +1 -1
- package/docs/WConverhpClient.html +1 -1
- package/docs/WConverhpClient.mjs.html +84 -34
- package/docs/WConverhpServer.html +2 -2
- package/docs/WConverhpServer.mjs.html +131 -304
- package/docs/index.html +1 -1
- package/package.json +1 -1
- package/scla.mjs +3 -0
- package/sclb.mjs +3 -0
- package/sclc.mjs +4 -1
- package/scld.mjs +3 -0
- package/script.txt +4 -4
- package/src/WConverhpClient.mjs +83 -33
- package/src/WConverhpServer.mjs +130 -303
- package/src/checkSlicesHash.mjs +68 -0
- package/src/checkSlicesHash.wk.umd.js +1 -0
- package/src/checkTotalHash.mjs +107 -0
- package/src/checkTotalHash.wk.umd.js +1 -0
- package/src/managerMergeSlices.mjs +82 -0
- package/src/mergeSlices.mjs +31 -0
- package/src/mergeSlices.wk.umd.js +1 -0
- package/test/downloadLargeFile.test.mjs +3 -0
- package/test/executeWithFile.test.mjs +3 -0
- package/test/executeWithU8a.test.mjs +3 -0
- package/test/uploadLargeFile.test.mjs +9 -5
- package/toolg/gDistRollup.mjs +48 -4
- package/src/calcFileHash.mjs +0 -10
- package/src/calcFileHash.wk.umd.js +0 -1
- package/src/mergeFiles.mjs +0 -27
- package/src/mergeFiles.wk.umd.js +0 -1
package/src/WConverhpServer.mjs
CHANGED
|
@@ -4,8 +4,6 @@ import stream from 'stream'
|
|
|
4
4
|
import Hapi from '@hapi/hapi'
|
|
5
5
|
import Inert from '@hapi/inert' //提供靜態檔案
|
|
6
6
|
import get from 'lodash-es/get.js'
|
|
7
|
-
import each from 'lodash-es/each.js'
|
|
8
|
-
import size from 'lodash-es/size.js'
|
|
9
7
|
import isNumber from 'lodash-es/isNumber.js'
|
|
10
8
|
import genPm from 'wsemi/src/genPm.mjs'
|
|
11
9
|
import evem from 'wsemi/src/evem.mjs'
|
|
@@ -15,7 +13,6 @@ import isp0int from 'wsemi/src/isp0int.mjs'
|
|
|
15
13
|
import ispint from 'wsemi/src/ispint.mjs'
|
|
16
14
|
import isearr from 'wsemi/src/isearr.mjs'
|
|
17
15
|
import isbol from 'wsemi/src/isbol.mjs'
|
|
18
|
-
import isnum from 'wsemi/src/isnum.mjs'
|
|
19
16
|
import isfun from 'wsemi/src/isfun.mjs'
|
|
20
17
|
import ispm from 'wsemi/src/ispm.mjs'
|
|
21
18
|
import cint from 'wsemi/src/cint.mjs'
|
|
@@ -24,15 +21,13 @@ import str2b64 from 'wsemi/src/str2b64.mjs'
|
|
|
24
21
|
import haskey from 'wsemi/src/haskey.mjs'
|
|
25
22
|
import obj2u8arr from 'wsemi/src/obj2u8arr.mjs'
|
|
26
23
|
import u8arr2obj from 'wsemi/src/u8arr2obj.mjs'
|
|
27
|
-
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
28
24
|
import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
|
|
29
25
|
import fsCreateFolder from 'wsemi/src/fsCreateFolder.mjs'
|
|
30
|
-
import
|
|
31
|
-
import
|
|
32
|
-
|
|
33
|
-
import
|
|
34
|
-
|
|
35
|
-
import mergeFiles from './mergeFiles.wk.umd.js'
|
|
26
|
+
import managerMergeSlices from './managerMergeSlices.mjs'
|
|
27
|
+
// import checkTotalHash from './checkTotalHash.mjs'
|
|
28
|
+
import checkTotalHash from './checkTotalHash.wk.umd.js'
|
|
29
|
+
// import checkSlicesHash from './checkSlicesHash.mjs'
|
|
30
|
+
import checkSlicesHash from './checkSlicesHash.wk.umd.js'
|
|
36
31
|
|
|
37
32
|
|
|
38
33
|
//回傳前端stream時(POST或GET皆可), 前端會須等stream傳完才能判斷是否為大檔或錯誤訊息, 此會導致若回傳超大檔, 會需要對超大檔進行解析會有記憶體上限問題, 故需要通過header提供基本成功或失敗訊息, 讓前端能進行解析判斷
|
|
@@ -40,6 +35,10 @@ import mergeFiles from './mergeFiles.wk.umd.js'
|
|
|
40
35
|
//回傳前端(browser)時, 針對超大檔, 可用POST並用stream回傳但還要處理進度條, 若要交由瀏覽器下載器處理, 只能用GET並用stream回傳, 且前端只能用window.location.href或a.href+a.click()下載
|
|
41
36
|
|
|
42
37
|
|
|
38
|
+
//mmg
|
|
39
|
+
let mmg = managerMergeSlices()
|
|
40
|
+
|
|
41
|
+
|
|
43
42
|
/**
|
|
44
43
|
* 建立Hapi伺服器
|
|
45
44
|
*
|
|
@@ -609,7 +608,7 @@ function WConverhpServer(opt = {}) {
|
|
|
609
608
|
|
|
610
609
|
//apiUploadCheck
|
|
611
610
|
let apiUploadCheck = {
|
|
612
|
-
path: `/${apiName}
|
|
611
|
+
path: `/${apiName}ulctr`,
|
|
613
612
|
method: 'POST',
|
|
614
613
|
options: {
|
|
615
614
|
payload: {
|
|
@@ -646,7 +645,7 @@ function WConverhpServer(opt = {}) {
|
|
|
646
645
|
if (true) {
|
|
647
646
|
|
|
648
647
|
//verifyConn
|
|
649
|
-
let m = verifyConn({ apiType: 'upload-
|
|
648
|
+
let m = verifyConn({ apiType: 'upload-controller', authorization, headers, query })
|
|
650
649
|
if (ispm(m)) {
|
|
651
650
|
m = await m
|
|
652
651
|
}
|
|
@@ -669,13 +668,14 @@ function WConverhpServer(opt = {}) {
|
|
|
669
668
|
let mode = get(req, 'payload.mode', '')
|
|
670
669
|
|
|
671
670
|
//check
|
|
672
|
-
if (mode !== 'check-total-hash' && mode !== 'check-slices-hash') {
|
|
671
|
+
if (mode !== 'check-total-hash' && mode !== 'check-slices-hash' && mode !== 'merge-slices-push' && mode !== 'merge-slices-get') {
|
|
673
672
|
// console.log('invalid mode in payload')
|
|
674
673
|
return responseU8aStreamWithError(res, `invalid mode[${mode}] in payload`)
|
|
675
674
|
}
|
|
676
675
|
|
|
677
676
|
//fileHash, 從payload接收
|
|
678
677
|
let fileHash = get(req, 'payload.fileHash', '')
|
|
678
|
+
// console.log(mode, 'fileHash', fileHash)
|
|
679
679
|
|
|
680
680
|
//check
|
|
681
681
|
if (!isestr(fileHash)) {
|
|
@@ -683,189 +683,143 @@ function WConverhpServer(opt = {}) {
|
|
|
683
683
|
return responseU8aStreamWithError(res, 'invalid fileHash in payload')
|
|
684
684
|
}
|
|
685
685
|
|
|
686
|
-
//
|
|
687
|
-
let
|
|
686
|
+
//procCore
|
|
687
|
+
let procCore = async() => {
|
|
688
|
+
let out = null
|
|
689
|
+
if (mode === 'check-total-hash') {
|
|
688
690
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
691
|
+
//filename, 從payload接收
|
|
692
|
+
let filename = get(req, 'payload.filename', '')
|
|
693
|
+
// console.log(mode, 'filename', filename)
|
|
692
694
|
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
// console.log(`check exist for pathFile[${pathFile}]...`)
|
|
695
|
+
//fileSize, 從payload接收
|
|
696
|
+
let fileSize = get(req, 'payload.fileSize', '')
|
|
697
|
+
// console.log(mode, 'fileSize', fileSize)
|
|
697
698
|
|
|
698
|
-
|
|
699
|
+
//checkTotalHash
|
|
700
|
+
out = await checkTotalHash(fileSize, sizeSlice, fileHash, pathUploadTemp)
|
|
701
|
+
// console.log(mode, 'out', out)
|
|
699
702
|
|
|
700
|
-
//
|
|
701
|
-
|
|
703
|
+
//check, 因合併大檔後可能非預期中斷而重傳, 每次偵測有合併完成大檔, 就得調用procUpload讓伺服器攔截函數處理
|
|
704
|
+
if (out.bAllHash) {
|
|
702
705
|
|
|
703
|
-
|
|
704
|
-
|
|
706
|
+
//ri
|
|
707
|
+
let ri = {
|
|
708
|
+
filename,
|
|
709
|
+
path: out.path,
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
//procUpload
|
|
713
|
+
// console.log('procUpload start')
|
|
714
|
+
let ro = await procUpload(ri)
|
|
715
|
+
// console.log('procUpload done', ro)
|
|
716
|
+
|
|
717
|
+
//out merge, 直接添加ro就回傳, 此處不使用msg儲存
|
|
718
|
+
out = {
|
|
719
|
+
...out,
|
|
720
|
+
...ro,
|
|
721
|
+
}
|
|
705
722
|
|
|
706
|
-
//check
|
|
707
|
-
if (!isnum(fileSize)) {
|
|
708
|
-
// console.log('invalid fileSize in payload')
|
|
709
|
-
let r = {
|
|
710
|
-
error: 'invalid fileSize in payload',
|
|
711
723
|
}
|
|
712
|
-
return r
|
|
713
|
-
}
|
|
714
724
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
if (bAllExist) {
|
|
718
|
-
// console.log(`check size for pathFile[${pathFile}]...`)
|
|
725
|
+
}
|
|
726
|
+
else if (mode === 'check-slices-hash') {
|
|
719
727
|
|
|
720
|
-
//
|
|
721
|
-
let
|
|
722
|
-
|
|
728
|
+
//fileSliceHashs, 從payload接收
|
|
729
|
+
let fileSliceHashs = get(req, 'payload.fileSliceHashs', [])
|
|
730
|
+
// console.log(mode, 'fileSliceHashs', fileSliceHashs)
|
|
723
731
|
|
|
724
|
-
//
|
|
725
|
-
|
|
732
|
+
//checkSlicesHash
|
|
733
|
+
out = await checkSlicesHash(fileSliceHashs, fileHash, pathUploadTemp)
|
|
734
|
+
// console.log(mode, 'out', out)
|
|
726
735
|
|
|
727
|
-
// console.log(`check size for pathFile[${pathFile}] done`, bAllSize)
|
|
728
736
|
}
|
|
737
|
+
else if (mode === 'merge-slices-push') {
|
|
729
738
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
console.log(err)
|
|
742
|
-
console.log(`fsIsFile(pathFile)`, pathFile, fsIsFile(pathFile))
|
|
743
|
-
bAllHash = false
|
|
744
|
-
})
|
|
745
|
-
|
|
746
|
-
// console.log(`check hash for pathFile[${pathFile}] done`, bAllHash)
|
|
747
|
-
}
|
|
739
|
+
//chunkTotal, 從payload接收
|
|
740
|
+
let chunkTotal = get(req, 'payload.chunkTotal', '')
|
|
741
|
+
// console.log(mode, 'chunkTotal', chunkTotal)
|
|
742
|
+
|
|
743
|
+
//mmg.push
|
|
744
|
+
let queueId = mmg.push(fileHash, chunkTotal, pathUploadTemp)
|
|
745
|
+
|
|
746
|
+
//out
|
|
747
|
+
out = {
|
|
748
|
+
queueId,
|
|
749
|
+
}
|
|
748
750
|
|
|
749
|
-
//vfps
|
|
750
|
-
let vfps = fsGetFilesInFolder(pathUploadTemp)
|
|
751
|
-
// console.log('vfps', vfps)
|
|
752
|
-
|
|
753
|
-
//slks
|
|
754
|
-
let slks = []
|
|
755
|
-
if (true) {
|
|
756
|
-
each(vfps, (v, k) => {
|
|
757
|
-
let b1 = (v.name).indexOf(`${fileHash}_`) >= 0
|
|
758
|
-
let stats = fs.statSync(v.path)
|
|
759
|
-
let b2 = stats.size === sizeSlice
|
|
760
|
-
let b = b1 && b2
|
|
761
|
-
if (b) {
|
|
762
|
-
slks.push(k)
|
|
763
|
-
}
|
|
764
|
-
})
|
|
765
|
-
}
|
|
766
|
-
// console.log('slks', slks)
|
|
767
|
-
|
|
768
|
-
//bSls
|
|
769
|
-
let bSls = size(slks) > 0
|
|
770
|
-
// console.log('bSls', bSls)
|
|
771
|
-
|
|
772
|
-
//r
|
|
773
|
-
let r = {
|
|
774
|
-
success: {
|
|
775
|
-
path: pathFile,
|
|
776
|
-
bAllExist,
|
|
777
|
-
bAllSize,
|
|
778
|
-
bAllHash,
|
|
779
|
-
bSls,
|
|
780
|
-
slks,
|
|
781
|
-
},
|
|
782
751
|
}
|
|
752
|
+
else if (mode === 'merge-slices-get') {
|
|
783
753
|
|
|
784
|
-
|
|
785
|
-
|
|
754
|
+
//filename, 從payload接收
|
|
755
|
+
let filename = get(req, 'payload.filename', '')
|
|
756
|
+
// console.log(mode, 'filename', filename)
|
|
786
757
|
|
|
787
|
-
|
|
788
|
-
|
|
758
|
+
//queueId, 從payload接收
|
|
759
|
+
let queueId = get(req, 'payload.queueId', '')
|
|
760
|
+
// console.log(mode, 'queueId', queueId)
|
|
789
761
|
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
// console.log('fileSliceHashs', fileSliceHashs)
|
|
762
|
+
//mmg.get
|
|
763
|
+
let r = mmg.get(queueId, pathUploadTemp)
|
|
793
764
|
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
765
|
+
//out
|
|
766
|
+
out = {
|
|
767
|
+
queueId,
|
|
768
|
+
state: r.state,
|
|
769
|
+
filename,
|
|
770
|
+
path: r.path,
|
|
798
771
|
}
|
|
799
|
-
return r
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
//slksCfm, 已確定hash值一致的切片
|
|
803
|
-
// console.log(`check hash for slices fileHash[${fileHash}]...`, fileSliceHashs[0], size(fileSliceHashs))
|
|
804
|
-
let slksCfm = []
|
|
805
|
-
// let n = Math.max(fileSliceHashs.length, 1)
|
|
806
|
-
// let nr = Math.floor(n / 200)
|
|
807
|
-
for (let k = 0; k < fileSliceHashs.length; k++) {
|
|
808
|
-
// if (k % nr === 0) {
|
|
809
|
-
// console.log(`calc hash for slices`, round(k / fileSliceHashs.length * 100, 1), '%')
|
|
810
|
-
// }
|
|
811
|
-
|
|
812
|
-
//v
|
|
813
|
-
let v = fileSliceHashs[k]
|
|
814
|
-
|
|
815
|
-
//_pathFile
|
|
816
|
-
let _pathFile = path.join(pathUploadTemp, `${fileHash}_${v.i}`)
|
|
817
|
-
// console.log('_pathFile', _pathFile)
|
|
818
|
-
|
|
819
|
-
//_fileHash
|
|
820
|
-
let _fileHash = ''
|
|
821
|
-
// await calcFileHash(_pathFile)
|
|
822
|
-
await getFileXxHash(new Blob([fs.readFileSync(_pathFile)])) //計算切片因檔案很小, 直接用getFileXxHash速度比較快
|
|
823
|
-
.then((res) => {
|
|
824
|
-
_fileHash = res
|
|
825
|
-
})
|
|
826
|
-
.catch((err) => {
|
|
827
|
-
console.log(err)
|
|
828
|
-
console.log(`fsIsFile(_pathFile)`, _pathFile, fsIsFile(_pathFile))
|
|
829
|
-
})
|
|
830
|
-
// console.log('_fileHash', _fileHash)
|
|
831
772
|
|
|
832
773
|
//check
|
|
833
|
-
if (
|
|
834
|
-
slksCfm.push(v.i)
|
|
835
|
-
}
|
|
836
|
-
// else {
|
|
837
|
-
// console.log(`hash is not equal`, `hash(front)`, v.h, `hash(backend)`, _fileHash)
|
|
838
|
-
// }
|
|
774
|
+
if (r.state === 'done') {
|
|
839
775
|
|
|
840
|
-
|
|
841
|
-
|
|
776
|
+
//ri
|
|
777
|
+
let ri = {
|
|
778
|
+
filename,
|
|
779
|
+
path: r.path,
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
//procUpload, 偵測有合併完成大檔, 得調用procUpload讓伺服器攔截函數處理
|
|
783
|
+
// console.log('procUpload start')
|
|
784
|
+
let ro = await procUpload(ri)
|
|
785
|
+
// console.log('procUpload done', ro)
|
|
786
|
+
|
|
787
|
+
//out merge, ro須附加至msg, 才供前端偵測state為'done'時提取msg顯示
|
|
788
|
+
out = {
|
|
789
|
+
...out,
|
|
790
|
+
msg: ro,
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
}
|
|
842
794
|
|
|
843
|
-
//r
|
|
844
|
-
let r = {
|
|
845
|
-
success: {
|
|
846
|
-
slks: slksCfm,
|
|
847
|
-
},
|
|
848
795
|
}
|
|
796
|
+
// console.log('out', out)
|
|
849
797
|
|
|
850
|
-
return
|
|
798
|
+
return out
|
|
851
799
|
}
|
|
852
800
|
|
|
853
|
-
//
|
|
854
|
-
let out =
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
801
|
+
//procCore
|
|
802
|
+
let out = {}
|
|
803
|
+
let returnType = ''
|
|
804
|
+
let returnMsg = ''
|
|
805
|
+
await procCore()
|
|
806
|
+
.then((res) => {
|
|
807
|
+
out.success = res
|
|
808
|
+
returnType = 'success'
|
|
809
|
+
returnMsg = 'need to parse'
|
|
810
|
+
})
|
|
811
|
+
.catch((err) => {
|
|
812
|
+
out.error = err
|
|
813
|
+
returnType = 'error'
|
|
814
|
+
returnMsg = 'need to parse'
|
|
815
|
+
})
|
|
816
|
+
// console.log('out', out)
|
|
861
817
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
return responseU8aStream(res, u8aOut, { returnType: 'success', returnMsg: 'need to parse' })
|
|
868
|
-
}
|
|
818
|
+
//u8aOut
|
|
819
|
+
let u8aOut = obj2u8arr(out)
|
|
820
|
+
// console.log('u8aOut', u8aOut)
|
|
821
|
+
|
|
822
|
+
return responseU8aStream(res, u8aOut, { returnType, returnMsg })
|
|
869
823
|
},
|
|
870
824
|
}
|
|
871
825
|
|
|
@@ -934,18 +888,18 @@ function WConverhpServer(opt = {}) {
|
|
|
934
888
|
|
|
935
889
|
//check
|
|
936
890
|
if (!isp0int(chunkIndex)) {
|
|
937
|
-
console.log('invalid chunkIndex in headers')
|
|
938
|
-
return res
|
|
891
|
+
// console.log('invalid chunkIndex in headers')
|
|
892
|
+
return responseU8aStreamWithError(res, 'invalid chunkIndex in headers')
|
|
939
893
|
}
|
|
940
894
|
chunkIndex = cint(chunkIndex)
|
|
941
895
|
if (!isp0int(chunkTotal)) {
|
|
942
|
-
console.log('invalid chunkTotal in headers')
|
|
943
|
-
return res
|
|
896
|
+
// console.log('invalid chunkTotal in headers')
|
|
897
|
+
return responseU8aStreamWithError(res, 'invalid chunkTotal in headers')
|
|
944
898
|
}
|
|
945
899
|
chunkTotal = cint(chunkTotal)
|
|
946
900
|
if (!isestr(packageId)) {
|
|
947
|
-
console.log('invalid packageId in headers')
|
|
948
|
-
return res
|
|
901
|
+
// console.log('invalid packageId in headers')
|
|
902
|
+
return responseU8aStreamWithError(res, 'invalid packageId in headers')
|
|
949
903
|
}
|
|
950
904
|
|
|
951
905
|
//pathFileChunk
|
|
@@ -1012,126 +966,6 @@ function WConverhpServer(opt = {}) {
|
|
|
1012
966
|
},
|
|
1013
967
|
}
|
|
1014
968
|
|
|
1015
|
-
//apiUploadSliceMerge
|
|
1016
|
-
let apiUploadSliceMerge = {
|
|
1017
|
-
path: `/${apiName}slcm`,
|
|
1018
|
-
method: 'POST',
|
|
1019
|
-
options: {
|
|
1020
|
-
payload: {
|
|
1021
|
-
maxBytes: 1024 * 1024 * 1024 * 1024, //預設為1mb, 調整至1tb, 也就是給予3次方
|
|
1022
|
-
maxParts: 1000 * 1000 * 1000, //預設為1000, 給予3次方
|
|
1023
|
-
timeout: false, //避免請求未完成時中斷
|
|
1024
|
-
// output: 'stream',
|
|
1025
|
-
parse: true, //前端送obj過來須自動解析
|
|
1026
|
-
},
|
|
1027
|
-
timeout: {
|
|
1028
|
-
server: false, //關閉伺服器超時
|
|
1029
|
-
socket: false, //關閉socket超時
|
|
1030
|
-
},
|
|
1031
|
-
},
|
|
1032
|
-
handler: async function (req, res) {
|
|
1033
|
-
// console.log(req, res)
|
|
1034
|
-
// console.log('payload', req.payload)
|
|
1035
|
-
|
|
1036
|
-
//headers
|
|
1037
|
-
let headers = get(req, 'headers')
|
|
1038
|
-
headers = iseobj(headers) ? headers : ''
|
|
1039
|
-
// console.log('headers', headers)
|
|
1040
|
-
|
|
1041
|
-
//query
|
|
1042
|
-
let query = get(req, 'query')
|
|
1043
|
-
query = iseobj(query) ? query : ''
|
|
1044
|
-
// console.log('query', query)
|
|
1045
|
-
|
|
1046
|
-
//authorization
|
|
1047
|
-
let authorization = get(headers, 'authorization', '')
|
|
1048
|
-
authorization = isestr(authorization) ? authorization : ''
|
|
1049
|
-
|
|
1050
|
-
//check
|
|
1051
|
-
if (true) {
|
|
1052
|
-
|
|
1053
|
-
//verifyConn
|
|
1054
|
-
let m = verifyConn({ apiType: 'upload-slice-merge', authorization, headers, query })
|
|
1055
|
-
if (ispm(m)) {
|
|
1056
|
-
m = await m
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
//check
|
|
1060
|
-
if (m !== true) {
|
|
1061
|
-
return responseU8aStreamWithError(res, 'permission denied')
|
|
1062
|
-
}
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
|
|
1066
|
-
//eeEmit
|
|
1067
|
-
eeEmit('handler', {
|
|
1068
|
-
api: 'apiUploadSliceMerge',
|
|
1069
|
-
headers,
|
|
1070
|
-
query,
|
|
1071
|
-
})
|
|
1072
|
-
|
|
1073
|
-
//filename, chunkTotal, packageId, 從payload接收
|
|
1074
|
-
let filename = get(req, 'payload.filename', '')
|
|
1075
|
-
let chunkTotal = get(req, 'payload.chunk-total', '')
|
|
1076
|
-
let packageId = get(req, 'payload.package-id', '')
|
|
1077
|
-
|
|
1078
|
-
//check
|
|
1079
|
-
if (!isestr(filename)) {
|
|
1080
|
-
console.log('invalid filename in payload')
|
|
1081
|
-
return res.response({ error: 'invalid filename in payload' }).code(400)
|
|
1082
|
-
}
|
|
1083
|
-
if (!isp0int(chunkTotal)) {
|
|
1084
|
-
console.log('invalid chunkTotal in payload')
|
|
1085
|
-
return res.response({ error: 'invalid chunkTotal in payload' }).code(400)
|
|
1086
|
-
}
|
|
1087
|
-
chunkTotal = cint(chunkTotal)
|
|
1088
|
-
if (!isestr(packageId)) {
|
|
1089
|
-
console.log('invalid packageId in payload')
|
|
1090
|
-
return res.response({ error: 'invalid packageId in payload' }).code(400)
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
//mergeAndPorc
|
|
1094
|
-
let mergeAndPorc = async() => {
|
|
1095
|
-
|
|
1096
|
-
//merge
|
|
1097
|
-
// console.log('merge start')
|
|
1098
|
-
let r = await mergeFiles(pathUploadTemp, packageId, chunkTotal, filename)
|
|
1099
|
-
// console.log('merge done', r)
|
|
1100
|
-
|
|
1101
|
-
//procUpload
|
|
1102
|
-
// console.log('procUpload start')
|
|
1103
|
-
let rr = await procUpload(r)
|
|
1104
|
-
// console.log('procUpload done', rr)
|
|
1105
|
-
|
|
1106
|
-
return rr
|
|
1107
|
-
}
|
|
1108
|
-
|
|
1109
|
-
//mergeAndPorc
|
|
1110
|
-
let out = {}
|
|
1111
|
-
let returnType = ''
|
|
1112
|
-
let returnMsg = ''
|
|
1113
|
-
await mergeAndPorc()
|
|
1114
|
-
.then((res) => {
|
|
1115
|
-
out.success = res
|
|
1116
|
-
returnType = 'success'
|
|
1117
|
-
returnMsg = 'need to parse'
|
|
1118
|
-
})
|
|
1119
|
-
.catch((err) => {
|
|
1120
|
-
out.error = err
|
|
1121
|
-
returnType = 'error'
|
|
1122
|
-
returnMsg = 'need to parse'
|
|
1123
|
-
eeEmit('error', `${err.message}`)
|
|
1124
|
-
})
|
|
1125
|
-
// console.log('out', out)
|
|
1126
|
-
|
|
1127
|
-
//u8aOut
|
|
1128
|
-
let u8aOut = obj2u8arr(out)
|
|
1129
|
-
// console.log('u8aOut', u8aOut)
|
|
1130
|
-
|
|
1131
|
-
return responseU8aStream(res, u8aOut, { returnType, returnMsg })
|
|
1132
|
-
},
|
|
1133
|
-
}
|
|
1134
|
-
|
|
1135
969
|
//apiDownloadGetFilename
|
|
1136
970
|
let apiDownloadGetFilename = {
|
|
1137
971
|
path: `/${apiName}dwgfn`,
|
|
@@ -1349,14 +1183,6 @@ function WConverhpServer(opt = {}) {
|
|
|
1349
1183
|
//streamRead
|
|
1350
1184
|
let streamRead = get(r, 'streamRead')
|
|
1351
1185
|
|
|
1352
|
-
// //filename
|
|
1353
|
-
// let filename = get(r, 'filename')
|
|
1354
|
-
// if (!isestr(filename)) {
|
|
1355
|
-
// return responseU8aStreamWithError(res, 'invalid filename')
|
|
1356
|
-
// }
|
|
1357
|
-
// filename = str2b64(filename) //headers內對中文支援度不佳須用base64傳
|
|
1358
|
-
// console.log('filename', filename)
|
|
1359
|
-
|
|
1360
1186
|
//fileSize
|
|
1361
1187
|
let fileSize = get(r, 'fileSize')
|
|
1362
1188
|
if (!isNumber(fileSize)) {
|
|
@@ -1551,7 +1377,7 @@ function WConverhpServer(opt = {}) {
|
|
|
1551
1377
|
apiMain,
|
|
1552
1378
|
apiUploadCheck,
|
|
1553
1379
|
apiUploadSlice,
|
|
1554
|
-
apiUploadSliceMerge,
|
|
1380
|
+
// apiUploadSliceMerge,
|
|
1555
1381
|
apiDownloadGetFilename,
|
|
1556
1382
|
apiDownloadGetFile,
|
|
1557
1383
|
apiDownload,
|
|
@@ -1570,7 +1396,8 @@ function WConverhpServer(opt = {}) {
|
|
|
1570
1396
|
|
|
1571
1397
|
//start
|
|
1572
1398
|
if (get(opt, 'serverHapi')) {
|
|
1573
|
-
server.route([apiMain, apiUploadCheck, apiUploadSlice, apiUploadSliceMerge, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
|
|
1399
|
+
// server.route([apiMain, apiUploadCheck, apiUploadSlice, apiUploadSliceMerge, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
|
|
1400
|
+
server.route([apiMain, apiUploadCheck, apiUploadSlice, apiDownloadGetFilename, apiDownloadGetFile, apiDownload])
|
|
1574
1401
|
}
|
|
1575
1402
|
else {
|
|
1576
1403
|
startServer()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import size from 'lodash-es/size.js'
|
|
4
|
+
import fsIsFile from 'wsemi/src/fsIsFile.mjs'
|
|
5
|
+
import getFileXxHash from 'wsemi/src/getFileXxHash.mjs'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
let checkSlicesHash = async(fileSliceHashs, fileHash, pathUploadTemp) => {
|
|
9
|
+
|
|
10
|
+
//check, 前端須檢核, 若之前已回應無切片, 就不能再調用檢測切片hash的API
|
|
11
|
+
if (size(fileSliceHashs) === 0) {
|
|
12
|
+
let r = {
|
|
13
|
+
error: 'no fileSliceHashs',
|
|
14
|
+
}
|
|
15
|
+
return r
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//slksCfm, 已確定hash值一致的切片
|
|
19
|
+
// console.log(`check hash for slices fileHash[${fileHash}]...`, fileSliceHashs[0], size(fileSliceHashs))
|
|
20
|
+
let slksCfm = []
|
|
21
|
+
// let n = Math.max(fileSliceHashs.length, 1)
|
|
22
|
+
// let nr = Math.floor(n / 100)
|
|
23
|
+
for (let k = 0; k < fileSliceHashs.length; k++) {
|
|
24
|
+
// if (k % nr === 0) {
|
|
25
|
+
// console.log(`calc hash for slices`, (k / fileSliceHashs.length * 100).toFixed(1), '%')
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
//v
|
|
29
|
+
let v = fileSliceHashs[k]
|
|
30
|
+
|
|
31
|
+
//_pathFile
|
|
32
|
+
let _pathFile = path.join(pathUploadTemp, `${fileHash}_${v.i}`)
|
|
33
|
+
// console.log('_pathFile', _pathFile)
|
|
34
|
+
|
|
35
|
+
//_fileHash
|
|
36
|
+
let _fileHash = ''
|
|
37
|
+
// await calcFileHash(_pathFile)
|
|
38
|
+
await getFileXxHash(new Blob([fs.readFileSync(_pathFile)])) //計算切片因檔案很小, 直接用getFileXxHash速度比較快
|
|
39
|
+
.then((res) => {
|
|
40
|
+
_fileHash = res
|
|
41
|
+
})
|
|
42
|
+
.catch((err) => {
|
|
43
|
+
console.log(err)
|
|
44
|
+
console.log(`fsIsFile(_pathFile)`, _pathFile, fsIsFile(_pathFile))
|
|
45
|
+
})
|
|
46
|
+
// console.log('_fileHash', _fileHash)
|
|
47
|
+
|
|
48
|
+
//check
|
|
49
|
+
if (v.h === _fileHash) {
|
|
50
|
+
slksCfm.push(v.i)
|
|
51
|
+
}
|
|
52
|
+
// else {
|
|
53
|
+
// console.log(`hash is not equal`, `hash(front)`, v.h, `hash(backend)`, _fileHash)
|
|
54
|
+
// }
|
|
55
|
+
|
|
56
|
+
}
|
|
57
|
+
// console.log(`check hash for slices fileHash[${fileHash}] done`, slksCfm[0], size(slksCfm))
|
|
58
|
+
|
|
59
|
+
//r
|
|
60
|
+
let r = {
|
|
61
|
+
slks: slksCfm,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return r
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
export default checkSlicesHash
|