braid-http 1.3.10 → 1.3.12
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 +9 -5
- package/braid-http-server.js +61 -38
- package/package.json +1 -1
package/braid-http-client.js
CHANGED
|
@@ -592,10 +592,11 @@ function parse_headers (input) {
|
|
|
592
592
|
}
|
|
593
593
|
|
|
594
594
|
// Extract the header string
|
|
595
|
-
var headers_source =
|
|
595
|
+
var headers_source = input.slice(start, end).map(x => String.fromCharCode(x)).join('')
|
|
596
596
|
|
|
597
597
|
// Convert "HTTP 200 OK" to a :status: 200 header
|
|
598
|
-
headers_source = headers_source.replace(/^HTTP\/?\d*\.?\d* (\d\d\d).*\r?\n/,
|
|
598
|
+
headers_source = headers_source.replace(/^HTTP\/?\d*\.?\d* (\d\d\d).*\r?\n/,
|
|
599
|
+
':status: $1\r\n')
|
|
599
600
|
|
|
600
601
|
var headers_length = headers_source.length
|
|
601
602
|
|
|
@@ -728,18 +729,21 @@ function parse_body (state) {
|
|
|
728
729
|
|
|
729
730
|
// Parse Range Patch format
|
|
730
731
|
{
|
|
732
|
+
var to_text = (bytes) =>
|
|
733
|
+
new TextDecoder('utf-8').decode(new Uint8Array(bytes))
|
|
734
|
+
|
|
731
735
|
if (!('content-length' in last_patch.headers))
|
|
732
736
|
return {
|
|
733
737
|
result: 'error',
|
|
734
738
|
message: 'no content-length in patch',
|
|
735
|
-
patch: last_patch, input: (
|
|
739
|
+
patch: last_patch, input: to_text(state.input)
|
|
736
740
|
}
|
|
737
741
|
|
|
738
742
|
if (!('content-range' in last_patch.headers))
|
|
739
743
|
return {
|
|
740
744
|
result: 'error',
|
|
741
745
|
message: 'no content-range in patch',
|
|
742
|
-
patch: last_patch, input: (
|
|
746
|
+
patch: last_patch, input: to_text(state.input)
|
|
743
747
|
}
|
|
744
748
|
|
|
745
749
|
var content_length = parseInt(last_patch.headers['content-length'])
|
|
@@ -755,7 +759,7 @@ function parse_body (state) {
|
|
|
755
759
|
return {
|
|
756
760
|
result: 'error',
|
|
757
761
|
message: 'cannot parse content-range in patch',
|
|
758
|
-
patch: last_patch, input: (
|
|
762
|
+
patch: last_patch, input: to_text(state.input)
|
|
759
763
|
}
|
|
760
764
|
|
|
761
765
|
last_patch.unit = match.unit
|
package/braid-http-server.js
CHANGED
|
@@ -25,11 +25,15 @@ var assert = require('assert')
|
|
|
25
25
|
//
|
|
26
26
|
// {"some": "json object"}
|
|
27
27
|
//
|
|
28
|
-
function write_patches(res, patches) {
|
|
28
|
+
function write_patches (res, patches) {
|
|
29
29
|
// `patches` must be a patch object or an array of patch objects
|
|
30
30
|
// - Object: {unit, range, content}
|
|
31
31
|
// - Array: [{unit, range, content}, ...]
|
|
32
32
|
|
|
33
|
+
if (typeof patches !== 'object')
|
|
34
|
+
console.error('We got bad patches!', {patches})
|
|
35
|
+
|
|
36
|
+
assert(patches)
|
|
33
37
|
assert(typeof patches === 'object') // An array is also an object
|
|
34
38
|
|
|
35
39
|
// An array of one patch behaves like a single patch
|
|
@@ -46,19 +50,29 @@ function write_patches(res, patches) {
|
|
|
46
50
|
assert(typeof patch.unit === 'string')
|
|
47
51
|
assert(typeof patch.range === 'string')
|
|
48
52
|
|
|
49
|
-
if (typeof patch.content === 'string')
|
|
50
|
-
patch.content = new TextEncoder().encode(patch.content)
|
|
51
|
-
|
|
52
53
|
if (i > 0)
|
|
53
54
|
res.write('\r\n\r\n')
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
// Use a slick object_destructuring line to extract the extra_headers
|
|
57
|
+
var {unit, range, content, ...extra_headers} = patch
|
|
58
|
+
|
|
59
|
+
// Binarize the patch content
|
|
60
|
+
var binary_content = (typeof patch.content === 'string'
|
|
61
|
+
? new TextEncoder().encode(patch.content)
|
|
62
|
+
: patch.content)
|
|
63
|
+
|
|
64
|
+
// Write the basic headers
|
|
65
|
+
res.write('Content-Length: ' + get_binary_length(binary_content) + '\r\n'
|
|
66
|
+
+ 'Content-Range: ' + patch.unit + ' ' + patch.range + '\r\n')
|
|
67
|
+
|
|
68
|
+
// Write the extra headers:
|
|
69
|
+
for (var header in extra_headers)
|
|
70
|
+
res.write(`${header}: ${extra_headers[header]}\r\n`)
|
|
71
|
+
|
|
72
|
+
res.write('\r\n')
|
|
56
73
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
${Object.entries(extra_headers).map(([k, v]) => `${k}: ${v}\r\n`).join('')}\r
|
|
60
|
-
`)
|
|
61
|
-
write_binary(res, patch.content)
|
|
74
|
+
// Write the patch content
|
|
75
|
+
write_binary(res, binary_content)
|
|
62
76
|
})
|
|
63
77
|
}
|
|
64
78
|
|
|
@@ -150,7 +164,7 @@ function parse_update (req, cb) {
|
|
|
150
164
|
}
|
|
151
165
|
|
|
152
166
|
// Extract the header string
|
|
153
|
-
let headers_source =
|
|
167
|
+
let headers_source = buffer.slice(s, e).map(x => String.fromCharCode(x)).join('')
|
|
154
168
|
|
|
155
169
|
// Now let's parse those headers.
|
|
156
170
|
var headers = require('parse-headers')(headers_source)
|
|
@@ -345,29 +359,27 @@ async function send_update(res, data, url, peer) {
|
|
|
345
359
|
write_binary(res, body)
|
|
346
360
|
}
|
|
347
361
|
|
|
348
|
-
// console.log('
|
|
349
|
-
// subscription: res.isSubscription})
|
|
362
|
+
// console.log('Sending Update', {url, peer, data, subscription: res.isSubscription})
|
|
350
363
|
|
|
351
|
-
// Validate
|
|
352
|
-
|
|
364
|
+
// Validate the body and patches
|
|
365
|
+
assert(!(patch && patches),
|
|
366
|
+
'sendUpdate: cannot have both `update.patch` and `update.patches` set')
|
|
367
|
+
if (patch)
|
|
368
|
+
patches = [patch]
|
|
369
|
+
assert(!(body && patches),
|
|
370
|
+
'sendUpdate: cannot have both `update.body` and `update.patch(es)')
|
|
371
|
+
assert(!patches || Array.isArray(patches),
|
|
372
|
+
'sendUpdate: `patches` provided is not array')
|
|
373
|
+
|
|
374
|
+
// Validate body format
|
|
353
375
|
if (body !== undefined) {
|
|
354
376
|
assert(typeof body === 'string' || get_binary_length(body) != null)
|
|
355
377
|
if (body instanceof Blob) body = await body.arrayBuffer()
|
|
356
|
-
}
|
|
357
|
-
// Only one of patch or patches can be set
|
|
358
|
-
assert(!(patch && patches))
|
|
359
|
-
assert((patch || patches) !== undefined)
|
|
360
|
-
assert((patch || patches) !== null)
|
|
361
|
-
|
|
362
|
-
// Patches must be an array
|
|
363
|
-
if (patches)
|
|
364
|
-
assert(Array.isArray(patches))
|
|
365
|
-
|
|
366
|
-
// But if using `patch`, then we set `patches` to just that object
|
|
367
|
-
if (patch)
|
|
368
|
-
patches = patch
|
|
378
|
+
}
|
|
369
379
|
|
|
370
|
-
|
|
380
|
+
// Validate patches format
|
|
381
|
+
if (patches !== undefined) {
|
|
382
|
+
// Now `patches` will be an array of patches
|
|
371
383
|
//
|
|
372
384
|
// This distinction is used in write_patches() to determine whether
|
|
373
385
|
// to inline a single patch in the update body vs. writing out a
|
|
@@ -377,16 +389,21 @@ async function send_update(res, data, url, peer) {
|
|
|
377
389
|
assert('unit' in p)
|
|
378
390
|
assert('range' in p)
|
|
379
391
|
assert('content' in p)
|
|
380
|
-
assert(typeof p.content === 'string'
|
|
392
|
+
assert(typeof p.content === 'string'
|
|
393
|
+
|| get_binary_length(p.content) != null)
|
|
381
394
|
if (p.content instanceof Blob) p.content = await p.content.arrayBuffer()
|
|
382
395
|
}
|
|
383
396
|
}
|
|
384
397
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
398
|
+
// To send a response without a body, we just send an empty body
|
|
399
|
+
if (!patches && !body)
|
|
400
|
+
body = ''
|
|
388
401
|
|
|
389
|
-
|
|
402
|
+
var reason =
|
|
403
|
+
status === 200 ? 'OK'
|
|
404
|
+
: 404 ? 'Not Found'
|
|
405
|
+
: 'Unknown'
|
|
406
|
+
if (res.isSubscription) res.write(`HTTP ${status} ${reason}\r\n`)
|
|
390
407
|
|
|
391
408
|
// Write the headers or virtual headers
|
|
392
409
|
for (var [header, value] of Object.entries(data)) {
|
|
@@ -396,6 +413,10 @@ async function send_update(res, data, url, peer) {
|
|
|
396
413
|
if (value === undefined)
|
|
397
414
|
continue
|
|
398
415
|
|
|
416
|
+
// Status headers are set in the status line (above)
|
|
417
|
+
if (header === 'status')
|
|
418
|
+
continue
|
|
419
|
+
|
|
399
420
|
// Version and Parents get output in the Structured Headers format,
|
|
400
421
|
// so we convert `value` from array to comma-separated strings.
|
|
401
422
|
if (header === 'version') {
|
|
@@ -414,10 +435,12 @@ async function send_update(res, data, url, peer) {
|
|
|
414
435
|
}
|
|
415
436
|
|
|
416
437
|
// Write the patches or body
|
|
417
|
-
if (
|
|
418
|
-
let
|
|
419
|
-
|
|
420
|
-
|
|
438
|
+
if (body || body === '') {
|
|
439
|
+
let binary = typeof body === 'string' ? new TextEncoder().encode(body) : body,
|
|
440
|
+
length = get_binary_length(binary)
|
|
441
|
+
assert(length !== undefined && length !== 'undefined')
|
|
442
|
+
set_header('Content-Length', length)
|
|
443
|
+
write_body(binary)
|
|
421
444
|
} else
|
|
422
445
|
write_patches(res, patches)
|
|
423
446
|
|