braid-http 1.3.1 → 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,18 +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'}
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
588
+ }
589
+
590
+ // Extract the header string
591
+ var headers_source = new TextDecoder('utf-8').decode(new Uint8Array(input.slice(s, e)))
580
592
 
581
593
  // Skip "HTTP 200 OK"
582
- h.header_string = h.header_string.replace(/^HTTP 200.*\r?\n/, '')
594
+ headers_source = headers_source.replace(/^HTTP 200.*\r?\n/, '')
583
595
 
584
- var headers_source = h.header_string
585
596
  var headers_length = headers_source.length
586
597
 
587
598
  // Let's parse them! First define some variables:
588
599
  var headers = {},
589
- 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
590
601
  match,
591
602
  found_last_match = false
592
603
 
@@ -619,7 +630,7 @@ function parse_headers (input) {
619
630
  headers.patches = JSON.parse(headers.patches)
620
631
 
621
632
  // Update the input
622
- input = h.remaining_bytes
633
+ input = input.slice(e)
623
634
 
624
635
  // And return the parsed result
625
636
  return { result: 'success', headers, input }
@@ -787,60 +798,6 @@ function extra_headers (headers) {
787
798
  return result
788
799
  }
789
800
 
790
- // a parsing utility function that will inspect a byte array of incoming data
791
- // to see if there is header information at the beginning,
792
- // namely some non-newline characters followed by two newlines
793
- function extractHeader(input) {
794
- // Find the start of the headers
795
- let begin_headers_i = 0;
796
- while (input[begin_headers_i] === 13 || input[begin_headers_i] === 10) {
797
- begin_headers_i++;
798
- }
799
- if (begin_headers_i === input.length) {
800
- return null; // Incomplete headers
801
- }
802
-
803
- // Look for the double-newline at the end of the headers
804
- let end_headers_i = begin_headers_i;
805
- let size_of_tail = 0;
806
- while (end_headers_i < input.length) {
807
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 10) {
808
- size_of_tail = 2;
809
- break;
810
- }
811
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 13 && input[end_headers_i + 2] === 10) {
812
- size_of_tail = 3;
813
- break;
814
- }
815
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 10) {
816
- size_of_tail = 3;
817
- break;
818
- }
819
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 13 && input[end_headers_i + 3] === 10) {
820
- size_of_tail = 4;
821
- break;
822
- }
823
-
824
- end_headers_i++;
825
- }
826
-
827
- // If no double-newline is found, wait for more input
828
- if (end_headers_i === input.length) {
829
- return null; // Incomplete headers
830
- }
831
-
832
- // Extract the header string
833
- const headerBytes = input.slice(begin_headers_i, end_headers_i);
834
- const headerString = new TextDecoder('utf-8').decode(new Uint8Array(headerBytes));
835
-
836
- // Return the remaining bytes and the header string
837
- const remainingBytes = input.slice(end_headers_i + size_of_tail);
838
- return {
839
- remaining_bytes: remainingBytes,
840
- header_string: headerString
841
- };
842
- }
843
-
844
801
  function get_binary_length(x) {
845
802
  return x instanceof ArrayBuffer ? x.byteLength :
846
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,7 +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
- res.write(`HTTP 200 OK\r\n`)
382
+ if (res.isSubscription) res.write(`HTTP 200 OK\r\n`)
371
383
 
372
384
  // Write the headers or virtual headers
373
385
  for (var [header, value] of Object.entries(data)) {
@@ -416,60 +428,6 @@ async function send_update(res, data, url, peer) {
416
428
  }
417
429
  }
418
430
 
419
- // a parsing utility function that will inspect a byte array of incoming data
420
- // to see if there is header information at the beginning,
421
- // namely some non-newline characters followed by two newlines
422
- function extractHeader(input) {
423
- // Find the start of the headers
424
- let begin_headers_i = 0;
425
- while (input[begin_headers_i] === 13 || input[begin_headers_i] === 10) {
426
- begin_headers_i++;
427
- }
428
- if (begin_headers_i === input.length) {
429
- return null; // Incomplete headers
430
- }
431
-
432
- // Look for the double-newline at the end of the headers
433
- let end_headers_i = begin_headers_i;
434
- let size_of_tail = 0;
435
- while (end_headers_i < input.length) {
436
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 10) {
437
- size_of_tail = 2;
438
- break;
439
- }
440
- if (input[end_headers_i] === 10 && input[end_headers_i + 1] === 13 && input[end_headers_i + 2] === 10) {
441
- size_of_tail = 3;
442
- break;
443
- }
444
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 10) {
445
- size_of_tail = 3;
446
- break;
447
- }
448
- if (input[end_headers_i] === 13 && input[end_headers_i + 1] === 10 && input[end_headers_i + 2] === 13 && input[end_headers_i + 3] === 10) {
449
- size_of_tail = 4;
450
- break;
451
- }
452
-
453
- end_headers_i++;
454
- }
455
-
456
- // If no double-newline is found, wait for more input
457
- if (end_headers_i === input.length) {
458
- return null; // Incomplete headers
459
- }
460
-
461
- // Extract the header string
462
- const headerBytes = input.slice(begin_headers_i, end_headers_i);
463
- const headerString = new TextDecoder('utf-8').decode(new Uint8Array(headerBytes));
464
-
465
- // Return the remaining bytes and the header string
466
- const remainingBytes = input.slice(end_headers_i + size_of_tail);
467
- return {
468
- remaining_bytes: remainingBytes,
469
- header_string: headerString
470
- };
471
- }
472
-
473
431
  function get_binary_length(x) {
474
432
  return x instanceof ArrayBuffer ? x.byteLength :
475
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.1",
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"