braid-http 1.2.0 → 1.3.0
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/braid-http-client.js +16 -2
- package/braid-http-server.js +46 -34
- package/package.json +1 -1
package/braid-http-client.js
CHANGED
|
@@ -193,7 +193,6 @@ async function braid_fetch (url, params = {}) {
|
|
|
193
193
|
if (typeof patch.content === 'string')
|
|
194
194
|
patch.content = new TextEncoder().encode(patch.content)
|
|
195
195
|
|
|
196
|
-
params.headers.set('Content-Length', `${patch.content.length}`)
|
|
197
196
|
params.body = patch.content
|
|
198
197
|
}
|
|
199
198
|
|
|
@@ -208,7 +207,7 @@ async function braid_fetch (url, params = {}) {
|
|
|
208
207
|
if (typeof patch.content === 'string')
|
|
209
208
|
patch.content = te.encode(patch.content)
|
|
210
209
|
|
|
211
|
-
var length = `content-length: ${patch.content
|
|
210
|
+
var length = `content-length: ${get_binary_length(patch.content)}`
|
|
212
211
|
var range = `content-range: ${patch.unit} ${patch.range}`
|
|
213
212
|
bufs.push(te.encode(`${length}\r\n${range}\r\n\r\n`))
|
|
214
213
|
bufs.push(patch.content)
|
|
@@ -579,6 +578,15 @@ function parse_headers (input) {
|
|
|
579
578
|
var h = extractHeader(input)
|
|
580
579
|
if (!h) return {result: 'waiting'}
|
|
581
580
|
|
|
581
|
+
// Skip "HTTP 104 Multiresponse"
|
|
582
|
+
if (h.header_string.startsWith('HTTP 104')) {
|
|
583
|
+
h = extractHeader(h.remaining_bytes)
|
|
584
|
+
if (!h) return {result: 'waiting'}
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
// Skip "HTTP 200 OK"
|
|
588
|
+
h.header_string = h.header_string.replace(/^HTTP 200.*\r?\n/, '')
|
|
589
|
+
|
|
582
590
|
var headers_source = h.header_string
|
|
583
591
|
var headers_length = headers_source.length
|
|
584
592
|
|
|
@@ -839,6 +847,12 @@ function extractHeader(input) {
|
|
|
839
847
|
};
|
|
840
848
|
}
|
|
841
849
|
|
|
850
|
+
function get_binary_length(x) {
|
|
851
|
+
return x instanceof ArrayBuffer ? x.byteLength :
|
|
852
|
+
x instanceof Uint8Array ? x.length :
|
|
853
|
+
x instanceof Blob ? x.size : undefined
|
|
854
|
+
}
|
|
855
|
+
|
|
842
856
|
// ****************************
|
|
843
857
|
// Exports
|
|
844
858
|
// ****************************
|
package/braid-http-server.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var assert = require('assert')
|
|
2
2
|
|
|
3
|
-
//
|
|
3
|
+
// Writes patches in pseudoheader format.
|
|
4
4
|
//
|
|
5
5
|
// The `patches` argument can be:
|
|
6
6
|
// - Array of patches
|
|
@@ -25,9 +25,7 @@ var assert = require('assert')
|
|
|
25
25
|
//
|
|
26
26
|
// {"some": "json object"}
|
|
27
27
|
//
|
|
28
|
-
function
|
|
29
|
-
var result = ''
|
|
30
|
-
|
|
28
|
+
function write_patches(res, patches) {
|
|
31
29
|
// `patches` must be a patch object or an array of patch objects
|
|
32
30
|
// - Object: {unit, range, content}
|
|
33
31
|
// - Array: [{unit, range, content}, ...]
|
|
@@ -38,7 +36,7 @@ function generate_patches(res, patches) {
|
|
|
38
36
|
if (Array.isArray(patches)) {
|
|
39
37
|
|
|
40
38
|
// Add `Patches: N` header if array
|
|
41
|
-
|
|
39
|
+
res.write(`Patches: ${patches.length}\r\n\r\n`)
|
|
42
40
|
} else
|
|
43
41
|
// Else, we'll out put a single patch
|
|
44
42
|
patches = [patches]
|
|
@@ -47,19 +45,21 @@ function generate_patches(res, patches) {
|
|
|
47
45
|
patches.forEach((patch, i) => {
|
|
48
46
|
assert(typeof patch.unit === 'string')
|
|
49
47
|
assert(typeof patch.range === 'string')
|
|
50
|
-
|
|
48
|
+
|
|
49
|
+
if (typeof patch.content === 'string')
|
|
50
|
+
patch.content = new TextEncoder().encode(patch.content)
|
|
51
51
|
|
|
52
52
|
if (i > 0)
|
|
53
|
-
|
|
53
|
+
res.write('\r\n\r\n')
|
|
54
54
|
|
|
55
55
|
let extra_headers = Object.fromEntries(Object.entries(patch).filter(([k, v]) => k != 'unit' && k != 'range' && k != 'content'))
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
res.write(`Content-Length: ${get_binary_length(patch.content)}\r
|
|
58
58
|
Content-Range: ${patch.unit} ${patch.range}\r
|
|
59
59
|
${Object.entries(extra_headers).map(([k, v]) => `${k}: ${v}\r\n`).join('')}\r
|
|
60
|
-
|
|
60
|
+
`)
|
|
61
|
+
write_binary(res, patch.content)
|
|
61
62
|
})
|
|
62
|
-
return result
|
|
63
63
|
}
|
|
64
64
|
|
|
65
65
|
|
|
@@ -312,7 +312,7 @@ function braidify (req, res, next) {
|
|
|
312
312
|
next && next()
|
|
313
313
|
}
|
|
314
314
|
|
|
315
|
-
function send_update(res, data, url, peer) {
|
|
315
|
+
async function send_update(res, data, url, peer) {
|
|
316
316
|
var {version, parents, patches, patch, body} = data
|
|
317
317
|
|
|
318
318
|
function set_header (key, val) {
|
|
@@ -323,7 +323,7 @@ function send_update(res, data, url, peer) {
|
|
|
323
323
|
}
|
|
324
324
|
function write_body (body) {
|
|
325
325
|
if (res.isSubscription) res.write('\r\n')
|
|
326
|
-
res
|
|
326
|
+
write_binary(res, body)
|
|
327
327
|
}
|
|
328
328
|
|
|
329
329
|
// console.log('sending version', {url, peer, version, parents, patches, body,
|
|
@@ -331,14 +331,10 @@ function send_update(res, data, url, peer) {
|
|
|
331
331
|
|
|
332
332
|
// Validate that the body and patches are strings,
|
|
333
333
|
// or in the case of body, it could be binary
|
|
334
|
-
if (body !== undefined)
|
|
335
|
-
assert(typeof body === 'string' ||
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
body instanceof Blob ||
|
|
339
|
-
body instanceof Buffer
|
|
340
|
-
)
|
|
341
|
-
else {
|
|
334
|
+
if (body !== undefined) {
|
|
335
|
+
assert(typeof body === 'string' || get_binary_length(body) != null)
|
|
336
|
+
if (body instanceof Blob) body = await body.arrayBuffer()
|
|
337
|
+
} else {
|
|
342
338
|
// Only one of patch or patches can be set
|
|
343
339
|
assert(!(patch && patches))
|
|
344
340
|
assert((patch || patches) !== undefined)
|
|
@@ -354,23 +350,31 @@ function send_update(res, data, url, peer) {
|
|
|
354
350
|
|
|
355
351
|
// Now `patches` will be an array of patches or a single patch object.
|
|
356
352
|
//
|
|
357
|
-
// This distinction is used in
|
|
353
|
+
// This distinction is used in write_patches() to determine whether
|
|
358
354
|
// to inline a single patch in the update body vs. writing out a
|
|
359
355
|
// Patches: N block.
|
|
360
356
|
assert(typeof patches === 'object')
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
357
|
+
for (let p of Array.isArray(patches) ? patches : [patch]) {
|
|
358
|
+
assert('unit' in p)
|
|
359
|
+
assert('range' in p)
|
|
360
|
+
assert('content' in p)
|
|
361
|
+
assert(typeof p.content === 'string' || get_binary_length(p.content) != null)
|
|
362
|
+
if (p.content instanceof Blob) p.content = await p.content.arrayBuffer()
|
|
363
|
+
}
|
|
368
364
|
}
|
|
369
365
|
|
|
370
366
|
var body_exists = body || body === ''
|
|
371
367
|
assert(body_exists || patches, 'Missing body or patches')
|
|
372
368
|
assert(!(body_exists && patches), 'Cannot send both body and patches')
|
|
373
369
|
|
|
370
|
+
// Write the beginning of a new multiresponse response
|
|
371
|
+
if (!res.wrote_104_multiresponse) {
|
|
372
|
+
res.write(`HTTP 104 Multiresponse\r\n\r\n`)
|
|
373
|
+
res.wrote_104_multiresponse = true
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
res.write(`HTTP 200 OK\r\n`)
|
|
377
|
+
|
|
374
378
|
// Write the headers or virtual headers
|
|
375
379
|
for (var [header, value] of Object.entries(data)) {
|
|
376
380
|
header = header.toLowerCase()
|
|
@@ -399,14 +403,10 @@ function send_update(res, data, url, peer) {
|
|
|
399
403
|
// Write the patches or body
|
|
400
404
|
if (body_exists) {
|
|
401
405
|
let x = typeof body === 'string' ? new TextEncoder().encode(body) : body
|
|
402
|
-
set_header('Content-Length',
|
|
403
|
-
x instanceof ArrayBuffer ? x.byteLength :
|
|
404
|
-
x instanceof Uint8Array ? x.length :
|
|
405
|
-
x instanceof Blob ? x.size :
|
|
406
|
-
x instanceof Buffer ? x.length : null)
|
|
406
|
+
set_header('Content-Length', get_binary_length(x))
|
|
407
407
|
write_body(x)
|
|
408
408
|
} else
|
|
409
|
-
|
|
409
|
+
write_patches(res, patches)
|
|
410
410
|
|
|
411
411
|
// Add a newline to prepare for the next version
|
|
412
412
|
// See also https://github.com/braid-org/braid-spec/issues/73
|
|
@@ -476,4 +476,16 @@ function extractHeader(input) {
|
|
|
476
476
|
};
|
|
477
477
|
}
|
|
478
478
|
|
|
479
|
+
function get_binary_length(x) {
|
|
480
|
+
return x instanceof ArrayBuffer ? x.byteLength :
|
|
481
|
+
x instanceof Uint8Array ? x.length :
|
|
482
|
+
x instanceof Blob ? x.size :
|
|
483
|
+
x instanceof Buffer ? x.length : undefined
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function write_binary(res, body) {
|
|
487
|
+
if (body instanceof ArrayBuffer) body = new Uint8Array(body)
|
|
488
|
+
res.write(body)
|
|
489
|
+
}
|
|
490
|
+
|
|
479
491
|
module.exports = braidify
|