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.
@@ -592,10 +592,11 @@ function parse_headers (input) {
592
592
  }
593
593
 
594
594
  // Extract the header string
595
- var headers_source = new TextDecoder('utf-8').decode(new Uint8Array(input.slice(start, end)))
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/, ':status: $1\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: (new TextDecoder('utf-8')).decode(new Uint8Array(state.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: (new TextDecoder('utf-8')).decode(new Uint8Array(state.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: (new TextDecoder('utf-8')).decode(new Uint8Array(state.input))
762
+ patch: last_patch, input: to_text(state.input)
759
763
  }
760
764
 
761
765
  last_patch.unit = match.unit
@@ -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
- let extra_headers = Object.fromEntries(Object.entries(patch).filter(([k, v]) => k != 'unit' && k != 'range' && k != 'content'))
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
- res.write(`Content-Length: ${get_binary_length(patch.content)}\r
58
- Content-Range: ${patch.unit} ${patch.range}\r
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 = new TextDecoder('utf-8').decode(new Uint8Array(buffer.slice(s, e)))
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('sending version', {url, peer, version, parents, patches, body,
349
- // subscription: res.isSubscription})
362
+ // console.log('Sending Update', {url, peer, data, subscription: res.isSubscription})
350
363
 
351
- // Validate that the body and patches are strings,
352
- // or in the case of body, it could be binary
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
- } else {
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
- // Now `patches` will be an array of patches or a single patch object.
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' || get_binary_length(p.content) != null)
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
- var body_exists = body || body === ''
386
- assert(body_exists || patches, 'Missing body or patches')
387
- assert(!(body_exists && patches), 'Cannot send both body and patches')
398
+ // To send a response without a body, we just send an empty body
399
+ if (!patches && !body)
400
+ body = ''
388
401
 
389
- if (res.isSubscription) res.write(`HTTP ${status} OK\r\n`)
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 (body_exists) {
418
- let x = typeof body === 'string' ? new TextEncoder().encode(body) : body
419
- set_header('Content-Length', get_binary_length(x))
420
- write_body(x)
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-http",
3
- "version": "1.3.10",
3
+ "version": "1.3.12",
4
4
  "description": "An implementation of Braid-HTTP for Node.js and Browsers",
5
5
  "scripts": {
6
6
  "test": "node test/server.js"