braid-http 1.3.0 → 1.3.2

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.
@@ -575,24 +575,29 @@ function parse_update (state) {
575
575
  // Parsing helpers
576
576
  function parse_headers (input) {
577
577
 
578
- var h = extractHeader(input)
579
- if (!h) return {result: 'waiting'}
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'}
578
+ // Find the start of the headers
579
+ let s = 0;
580
+ while (input[s] === 13 || input[s] === 10) s++
581
+ if (s === input.length) return {result: 'waiting'}
582
+
583
+ // Look for the double-newline at the end of the headers.
584
+ let e = s;
585
+ while (++e) {
586
+ if (e > input.length) return {result: 'waiting'}
587
+ if (input[e - 1] === 10 && (input[e - 2] === 10 || (input[e - 2] === 13 && input[e - 3] === 10))) break
585
588
  }
586
589
 
590
+ // Extract the header string
591
+ var headers_source = new TextDecoder('utf-8').decode(new Uint8Array(input.slice(s, e)))
592
+
587
593
  // Skip "HTTP 200 OK"
588
- h.header_string = h.header_string.replace(/^HTTP 200.*\r?\n/, '')
594
+ headers_source = headers_source.replace(/^HTTP 200.*\r?\n/, '')
589
595
 
590
- var headers_source = h.header_string
591
596
  var headers_length = headers_source.length
592
597
 
593
598
  // Let's parse them! First define some variables:
594
599
  var headers = {},
595
- header_regex = /(:?[\w-_]+):\s?(.*)\r?\n?/gy, // Parses one line a time
600
+ header_regex = /(:?[\w-_]+):\s?(.*)[\r\n]*/gy, // Parses one line a time
596
601
  match,
597
602
  found_last_match = false
598
603
 
@@ -625,7 +630,7 @@ function parse_headers (input) {
625
630
  headers.patches = JSON.parse(headers.patches)
626
631
 
627
632
  // Update the input
628
- input = h.remaining_bytes
633
+ input = input.slice(e)
629
634
 
630
635
  // And return the parsed result
631
636
  return { result: 'success', headers, input }
@@ -793,60 +798,6 @@ function extra_headers (headers) {
793
798
  return result
794
799
  }
795
800
 
796
- // a parsing utility function that will inspect a byte array of incoming data
797
- // to see if there is header information at the beginning,
798
- // namely some non-newline characters followed by two newlines
799
- function extractHeader(input) {
800
- // Find the start of the headers
801
- let begin_headers_i = 0;
802
- while (input[begin_headers_i] === 13 || input[begin_headers_i] === 10) {
803
- begin_headers_i++;
804
- }
805
- if (begin_headers_i === input.length) {
806
- return null; // Incomplete headers
807
- }
808
-
809
- // Look for the double-newline at the end of the headers
810
- let end_headers_i = begin_headers_i;
811
- let size_of_tail = 0;
812
- while (end_headers_i < input.length) {
813
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 10) {
814
- size_of_tail = 2;
815
- break;
816
- }
817
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 13 && input[end_headers_i + 2] === 10) {
818
- size_of_tail = 3;
819
- break;
820
- }
821
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 10) {
822
- size_of_tail = 3;
823
- break;
824
- }
825
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 13 && input[end_headers_i + 3] === 10) {
826
- size_of_tail = 4;
827
- break;
828
- }
829
-
830
- end_headers_i++;
831
- }
832
-
833
- // If no double-newline is found, wait for more input
834
- if (end_headers_i === input.length) {
835
- return null; // Incomplete headers
836
- }
837
-
838
- // Extract the header string
839
- const headerBytes = input.slice(begin_headers_i, end_headers_i);
840
- const headerString = new TextDecoder('utf-8').decode(new Uint8Array(headerBytes));
841
-
842
- // Return the remaining bytes and the header string
843
- const remainingBytes = input.slice(end_headers_i + size_of_tail);
844
- return {
845
- remaining_bytes: remainingBytes,
846
- header_string: headerString
847
- };
848
- }
849
-
850
801
  function get_binary_length(x) {
851
802
  return x instanceof ArrayBuffer ? x.byteLength :
852
803
  x instanceof Uint8Array ? x.length :
@@ -137,11 +137,23 @@ function parse_update (req, cb) {
137
137
  for (let x of chunk) buffer.push(x)
138
138
 
139
139
  while (patches.length < num_patches) {
140
- let h = extractHeader(buffer)
141
- if (!h) return
140
+ // Find the start of the headers
141
+ let s = 0;
142
+ while (buffer[s] === 13 || buffer[s] === 10) s++
143
+ if (s === buffer.length) return {result: 'waiting'}
144
+
145
+ // Look for the double-newline at the end of the headers.
146
+ let e = s;
147
+ while (++e) {
148
+ if (e > buffer.length) return {result: 'waiting'}
149
+ if (buffer[e - 1] === 10 && (buffer[e - 2] === 10 || (buffer[e - 2] === 13 && buffer[e - 3] === 10))) break
150
+ }
151
+
152
+ // Extract the header string
153
+ let headers_source = new TextDecoder('utf-8').decode(new Uint8Array(buffer.slice(s, e)))
142
154
 
143
155
  // Now let's parse those headers.
144
- var headers = require('parse-headers')(h.header_string)
156
+ var headers = require('parse-headers')(headers_source)
145
157
 
146
158
  // We require `content-length` to declare the length of the patch.
147
159
  if (!('content-length' in headers)) {
@@ -154,14 +166,14 @@ function parse_update (req, cb) {
154
166
  var body_length = parseInt(headers['content-length'])
155
167
 
156
168
  // Give up if we don't have the full patch yet.
157
- if (h.remaining_bytes.length < body_length)
169
+ if (buffer.length - e < body_length)
158
170
  return
159
171
 
160
172
  // XX Todo: support custom patch types beyond content-range.
161
173
 
162
174
  // Content-range is of the form '<unit> <range>' e.g. 'json .index'
163
175
  var [unit, range] = parse_content_range(headers['content-range'])
164
- var patch_content = new Uint8Array(h.remaining_bytes.slice(0, body_length))
176
+ var patch_content = new Uint8Array(buffer.slice(e, e + body_length))
165
177
 
166
178
  // We've got our patch!
167
179
  let patch = {unit, range, content: patch_content}
@@ -170,7 +182,7 @@ function parse_update (req, cb) {
170
182
  })
171
183
  patches.push(patch)
172
184
 
173
- buffer = h.remaining_bytes.slice(body_length)
185
+ buffer = buffer.slice(e + body_length)
174
186
  }
175
187
 
176
188
  // We got all the patches! Pause the stream and tell the callback!
@@ -367,13 +379,7 @@ async function send_update(res, data, url, peer) {
367
379
  assert(body_exists || patches, 'Missing body or patches')
368
380
  assert(!(body_exists && patches), 'Cannot send both body and patches')
369
381
 
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`)
382
+ if (res.isSubscription) res.write(`HTTP 200 OK\r\n`)
377
383
 
378
384
  // Write the headers or virtual headers
379
385
  for (var [header, value] of Object.entries(data)) {
@@ -422,60 +428,6 @@ async function send_update(res, data, url, peer) {
422
428
  }
423
429
  }
424
430
 
425
- // a parsing utility function that will inspect a byte array of incoming data
426
- // to see if there is header information at the beginning,
427
- // namely some non-newline characters followed by two newlines
428
- function extractHeader(input) {
429
- // Find the start of the headers
430
- let begin_headers_i = 0;
431
- while (input[begin_headers_i] === 13 || input[begin_headers_i] === 10) {
432
- begin_headers_i++;
433
- }
434
- if (begin_headers_i === input.length) {
435
- return null; // Incomplete headers
436
- }
437
-
438
- // Look for the double-newline at the end of the headers
439
- let end_headers_i = begin_headers_i;
440
- let size_of_tail = 0;
441
- while (end_headers_i < input.length) {
442
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 10) {
443
- size_of_tail = 2;
444
- break;
445
- }
446
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 13 && input[end_headers_i + 2] === 10) {
447
- size_of_tail = 3;
448
- break;
449
- }
450
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 10) {
451
- size_of_tail = 3;
452
- break;
453
- }
454
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 13 && input[end_headers_i + 3] === 10) {
455
- size_of_tail = 4;
456
- break;
457
- }
458
-
459
- end_headers_i++;
460
- }
461
-
462
- // If no double-newline is found, wait for more input
463
- if (end_headers_i === input.length) {
464
- return null; // Incomplete headers
465
- }
466
-
467
- // Extract the header string
468
- const headerBytes = input.slice(begin_headers_i, end_headers_i);
469
- const headerString = new TextDecoder('utf-8').decode(new Uint8Array(headerBytes));
470
-
471
- // Return the remaining bytes and the header string
472
- const remainingBytes = input.slice(end_headers_i + size_of_tail);
473
- return {
474
- remaining_bytes: remainingBytes,
475
- header_string: headerString
476
- };
477
- }
478
-
479
431
  function get_binary_length(x) {
480
432
  return x instanceof ArrayBuffer ? x.byteLength :
481
433
  x instanceof Uint8Array ? x.length :
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-http",
3
- "version": "1.3.0",
3
+ "version": "1.3.2",
4
4
  "description": "An implementation of Braid-HTTP for Node.js and Browsers",
5
5
  "scripts": {
6
6
  "test": "node test/server.js"