Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

Commit 695b23e

Browse files
committed
fix: cleanup code, headers, chunkSize options
1 parent 01a575e commit 695b23e

File tree

3 files changed

+67
-74
lines changed

3 files changed

+67
-74
lines changed

package.json

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
"async": "^2.6.1",
3030
"big.js": "^5.1.2",
3131
"bs58": "^4.0.1",
32-
"buffer-to-stream": "^1.0.0",
3332
"cids": "~0.5.3",
3433
"concat-stream": "^1.6.2",
3534
"debug": "^3.1.0",

src/add2/add2.js

+63-69
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict'
22

33
const { Readable, Transform } = require('stream')
4-
const toStream = require('buffer-to-stream')
54
const pump = require('pump')
65
const Multipart = require('./multipart2')
76
const {prepareWithHeaders} = require('./../utils/prepare-file')
@@ -24,106 +23,101 @@ const prepareTransform = (options) => new Transform({
2423
})
2524

2625
module.exports = (send) => (files, options) => {
27-
const multipart = new Multipart()
28-
29-
// add pump
30-
arrayToStream([].concat(files))
31-
.pipe(prepareTransform(options))
32-
.pipe(multipart)
26+
const multipart = pump(
27+
arrayToStream([].concat(files)),
28+
prepareTransform(options),
29+
new Multipart(options),
30+
(err) => {
31+
if (err) {
32+
// probably better to create a rejected Promise to return
33+
console.error(err)
34+
}
35+
}
36+
)
3337

3438
return sendChunked(multipart, send, options)
3539
}
3640

3741
const sendChunked = (multipartStream, send, options) => {
3842
return new Promise((resolve, reject) => {
39-
const boundary = multipartStream._boundary
40-
let index = 0
41-
let rangeStart = 0
42-
let rangeEnd = 0
43-
let size = 0
44-
let ended = false
45-
let running = false
46-
const name = createName()
43+
const state = {
44+
boundary: multipartStream._boundary,
45+
id: uuid(),
46+
index: 0,
47+
rangeStart: 0,
48+
rangeEnd: 0,
49+
rangeTotal: 0,
50+
ended: false,
51+
running: false
52+
}
4753

54+
multipartStream.on('error', reject)
4855
multipartStream.on('end', () => {
49-
ended = true
50-
console.log('end', size)
56+
state.ended = true
57+
console.log('end', state.rangeTotal)
5158

5259
// multipart ended and no request is running send last request
53-
if (!running) {
54-
// sendChunk('', -1, rangeEnd, rangeEnd, name, boundary, size)
55-
sendChunkRequest(send, options, '', -1, rangeEnd, rangeEnd, name, boundary, size)
56-
.then(rsp => {
57-
resolve(rsp)
58-
})
60+
if (!state.running) {
61+
sendChunkRequest(send, options, '', state)
62+
.then(resolve)
63+
.catch(reject)
5964
}
6065
})
6166

6267
multipartStream.on('data', (chunk) => {
6368
console.log('Sending ', chunk.length)
69+
// stop producing chunks
6470
multipartStream.pause()
65-
index++
66-
rangeEnd = rangeStart + chunk.length
67-
size += chunk.length
68-
running = true
71+
state.index++
72+
state.rangeEnd = state.rangeStart + chunk.length
73+
state.rangeTotal += chunk.length
74+
state.running = true
6975

70-
// sendChunk(chunk, index, rangeStart, rangeEnd, name, boundary)
71-
sendChunkRequest(send, options, chunk, index, rangeStart, rangeEnd, name, boundary)
76+
sendChunkRequest(send, options, chunk, state)
7277
.then(rsp => {
7378
console.log('Response', rsp)
74-
rangeStart = rangeEnd
79+
state.running = false
80+
state.rangeStart = state.rangeEnd
81+
// resume producing chunks
7582
multipartStream.resume()
83+
7684
// if multipart already ended send last request
77-
if (ended) {
78-
console.log('sending last')
79-
// sendChunk('', -1, rangeEnd, rangeEnd, name, boundary, size)
80-
sendChunkRequest(send, options, '', -1, rangeEnd, rangeEnd, name, boundary, size)
81-
.then(rsp => {
82-
resolve(rsp)
83-
})
85+
if (state.ended) {
86+
return sendChunkRequest(send, options, '', state)
87+
.then(resolve)
8488
}
85-
running = false
8689
})
8790
.catch(reject)
8891
})
8992
})
9093
}
9194

92-
const sendChunk = (chunk, id, start, end, name, boundary, size = '*') => {
93-
const url = new URL('http://localhost')
94-
const search = new URLSearchParams()
95-
search.set('stream-channels', true)
96-
url.port = 5002
97-
url.pathname = 'api/v0/add-chunked'
98-
url.search = search
99-
100-
return window.fetch(url.href, {
101-
method: 'POST',
102-
body: chunk,
103-
headers: {
104-
'Content-Type': 'application/octet-stream',
105-
'Content-Range': `bytes ${start}-${end}/${size}`,
106-
'Ipfs-Chunk-Name': name,
107-
'Ipfs-Chunk-Id': id,
108-
'Ipfs-Chunk-Boundary': boundary
109-
}
110-
})
111-
.then(res => res.json())
112-
}
113-
114-
function createName () {
115-
const date = new Date(Date.now()).toISOString()
95+
/**
96+
* Poor man's uuid
97+
*
98+
* @returns {String}
99+
*/
100+
function uuid () {
116101
function chr4 () {
117102
return Math.random().toString(16).slice(-4)
118103
}
119-
return date + '--' + chr4() + chr4() +
104+
return chr4() + chr4() +
120105
'-' + chr4() +
121106
'-' + chr4() +
122107
'-' + chr4() +
123108
'-' + chr4() + chr4() + chr4()
124109
}
125110

126-
const sendChunkRequest = (send, options, chunk, id, start, end, name, boundary, size = '*') => {
111+
/**
112+
* Send http request
113+
*
114+
* @param {function} send
115+
* @param {Object} options - http request options
116+
* @param {Uint8Array} chunk - chunk to send
117+
* @param {Object} {id, start, end, name, boundary, size = '*'} - uploading session state
118+
* @returns {Promise}
119+
*/
120+
const sendChunkRequest = (send, options, chunk, { boundary, id, index, rangeStart, rangeEnd, rangeTotal = '*' }) => {
127121
return new Promise((resolve, reject) => {
128122
const qs = {
129123
'cid-version': options['cid-version'],
@@ -141,21 +135,21 @@ const sendChunkRequest = (send, options, chunk, id, start, end, name, boundary,
141135
progress: options.progress,
142136
headers: {
143137
'Content-Type': 'application/octet-stream',
144-
'Content-Range': `bytes ${start}-${end}/${size}`,
145-
'Ipfs-Chunk-Name': name,
146-
'Ipfs-Chunk-Id': id,
147-
'Ipfs-Chunk-Boundary': boundary
138+
'Content-Range': `bytes ${rangeStart}-${rangeEnd}/${rangeTotal}`,
139+
'X-Ipfs-Chunk-Group-Uuid': id,
140+
'X-Ipfs-Chunk-Index': index,
141+
'X-Ipfs-Chunk-Boundary': boundary
148142
}
149143
}
150144

151145
const req = send(args, (err, res) => {
152146
if (err) {
153147
return reject(err)
154148
}
155-
156149
resolve(res)
157150
})
158151

152+
// write and send
159153
req.write(Buffer.from(chunk))
160154
req.end()
161155
})

src/add2/multipart2.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ const leading = (headers = {}, boundary) => {
3333
}
3434

3535
class Multipart extends Duplex {
36-
constructor (options) {
37-
super(Object.assign({}, options, { writableObjectMode: true, writableHighWaterMark: 1 }))
36+
constructor ({ chunkSize = 256000 } = {}) {
37+
super({ writableObjectMode: true, writableHighWaterMark: 1 })
3838

3939
this._boundary = generateBoundary()
4040
this.source = null
41-
this.chunkSize = 256000
41+
this.chunkSize = chunkSize
4242
this.buffer = Buffer.alloc(this.chunkSize)
4343
this.bufferOffset = 0
4444
this.running = true
@@ -116,8 +116,8 @@ class Multipart extends Duplex {
116116
content = toStream.source(content)
117117
}
118118
this.source = content
119-
// From now on we assume content is a stream
120119

120+
// From now on we assume content is a stream
121121
content.on('data', (data) => {
122122
if (!this.pushChunk(data)) {
123123
content.pause()

0 commit comments

Comments
 (0)