braid-http 1.3.39 → 1.3.40

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.
@@ -307,9 +307,9 @@ async function braid_fetch (url, params = {}) {
307
307
  // Now we run the original fetch....
308
308
 
309
309
  // try multiplexing if the multiplex flag is set, and conditions are met
310
- var mux_params = params.multiplex ?? braid_fetch.multiplex
310
+ var mux_params = params.multiplex ?? braid_fetch.enable_multiplex
311
311
  if (mux_params !== false &&
312
- (params.headers.has('multiplexer') ||
312
+ (params.headers.has('multiplex-at') ||
313
313
  (params.headers.has('subscribe') &&
314
314
  braid_fetch.subscription_counts?.[origin] >
315
315
  (!mux_params ? 1 : (mux_params.after ?? 0))))) {
@@ -828,17 +828,19 @@ function parse_body (state) {
828
828
  // multiplex_fetch provides a fetch-like experience for HTTP requests
829
829
  // where the result is actually being sent over a separate multiplexed connection.
830
830
  async function multiplex_fetch(url, params, skip_multiplex_method) {
831
+ var multiplex_version = '1.0'
832
+
831
833
  var origin = new URL(url, typeof document !== 'undefined' ? document.baseURI : undefined).origin
832
834
 
833
835
  // the mux_key is the same as the origin, unless it is being overriden
834
836
  // (the overriding is done by the tests)
835
- var mux_key = params.headers.get('multiplexer')?.split('/')[3] ?? origin
837
+ var mux_key = params.headers.get('multiplex-at')?.split('/')[3] ?? origin
836
838
 
837
839
  // create a new multiplexer if it doesn't exist for this origin
838
840
  if (!multiplex_fetch.multiplexers) multiplex_fetch.multiplexers = {}
839
841
  if (!multiplex_fetch.multiplexers[mux_key]) multiplex_fetch.multiplexers[mux_key] = (async () => {
840
842
  // make up a new multiplexer id (unless it is being overriden)
841
- var multiplexer = params.headers.get('multiplexer')?.split('/')[3] ?? Math.random().toString(36).slice(2)
843
+ var multiplexer = params.headers.get('multiplex-at')?.split('/')[3] ?? Math.random().toString(36).slice(2)
842
844
 
843
845
  var streams = new Map()
844
846
  var mux_error = null
@@ -847,16 +849,16 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
847
849
  // attempt to establish a multiplexed connection
848
850
  try {
849
851
  if (skip_multiplex_method) throw 'skip multiplex method'
850
- var r = await braid_fetch(`${origin}/${multiplexer}`, {method: 'MULTIPLEX', headers: {'Multiplex-Version': '0.0.1'}, retry: true})
851
- if (!r.ok || r.headers.get('Multiplex-Version') !== '0.0.1') throw 'bad'
852
+ var r = await braid_fetch(`${origin}/${multiplexer}`, {method: 'MULTIPLEX', headers: {'Multiplex-Version': multiplex_version}, retry: true})
853
+ if (!r.ok || r.headers.get('Multiplex-Version') !== multiplex_version) throw 'bad'
852
854
  } catch (e) {
853
855
  // some servers don't like custom methods,
854
856
  // so let's try with a custom header
855
857
  try {
856
- r = await braid_fetch(`${origin}/.well-known/multiplex/${multiplexer}`, {method: 'POST', headers: {'Multiplex-Version': '0.0.1'}, retry: true})
858
+ r = await braid_fetch(`${origin}/.well-known/multiplex/${multiplexer}`, {method: 'POST', headers: {'Multiplex-Version': multiplex_version}, retry: true})
857
859
 
858
860
  if (!r.ok) throw new Error('status not ok: ' + r.status)
859
- if (r.headers.get('Multiplex-Version') !== '0.0.1') throw new Error('wrong multiplex version: ' + r.headers.get('Multiplex-Version') + ', expected 0.0.1')
861
+ if (r.headers.get('Multiplex-Version') !== multiplex_version) throw new Error('wrong multiplex version: ' + r.headers.get('Multiplex-Version') + ', expected ' + multiplex_version)
860
862
  } catch (e) {
861
863
  // fallback to normal fetch if multiplexed connection fails
862
864
  console.error(`Could not establish multiplexed connection.\nGot error: ${e}.\nFalling back to normal connection.`)
@@ -882,16 +884,16 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
882
884
  // if we already know the multiplexer is not working,
883
885
  // then fallback to normal fetch
884
886
  // (unless the user is specifically asking for multiplexing)
885
- if ((await promise_done(mux_promise)) && (await mux_promise) === false && !params.headers.get('multiplexer'))
887
+ if ((await promise_done(mux_promise)) && (await mux_promise) === false && !params.headers.get('multiplex-at'))
886
888
  return await normal_fetch(url, params)
887
889
 
888
890
  // make up a new stream id (unless it is being overriden)
889
- var stream = params.headers.get('multiplexer')?.split('/')[4] ?? Math.random().toString(36).slice(2)
891
+ var stream = params.headers.get('multiplex-at')?.split('/')[4] ?? Math.random().toString(36).slice(2)
890
892
 
891
- // add the multiplexer header without affecting the underlying params
893
+ // add the Multiplex-At header without affecting the underlying params
892
894
  var mux_headers = new Headers(params.headers)
893
- mux_headers.set('Multiplexer', `/.well-known/multiplex/${multiplexer}/${stream}`)
894
- mux_headers.set('Multiplex-Version', '0.0.1')
895
+ mux_headers.set('Multiplex-At', `/.well-known/multiplex/${multiplexer}/${stream}`)
896
+ mux_headers.set('Multiplex-Version', multiplex_version)
895
897
  params = {...params, headers: mux_headers}
896
898
 
897
899
  // setup a way to receive incoming data from the multiplexer
@@ -929,13 +931,13 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
929
931
  stream_error = e
930
932
  bytes_available()
931
933
  try {
932
- var r = await braid_fetch(`${origin}${params.headers.get('multiplexer')}`, {
934
+ var r = await braid_fetch(`${origin}${params.headers.get('multiplex-at')}`, {
933
935
  method: 'DELETE',
934
- headers: { 'Multiplex-Version': '0.0.1' }, retry: true
936
+ headers: { 'Multiplex-Version': multiplex_version }, retry: true
935
937
  })
936
938
 
937
939
  if (!r.ok) throw new Error('status not ok: ' + r.status)
938
- if (r.headers.get('Multiplex-Version') !== '0.0.1') throw new Error('wrong multiplex version: ' + r.headers.get('Multiplex-Version') + ', expected 0.0.1')
940
+ if (r.headers.get('Multiplex-Version') !== multiplex_version) throw new Error('wrong multiplex version: ' + r.headers.get('Multiplex-Version') + ', expected ' + multiplex_version)
939
941
  } catch (e) {
940
942
  e = new Error(`Could not cancel multiplexed connection: ${e}`)
941
943
  console.error('' + e)
@@ -957,9 +959,9 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
957
959
  // fall back to as if it was a normal fetch
958
960
  if (res.ok && res.status !== 293) return res
959
961
 
960
- if (res.status !== 293) throw new Error('Could not establish multiplexed stream ' + params.headers.get('multiplexer') + ', got status: ' + res.status)
962
+ if (res.status !== 293) throw new Error('Could not establish multiplexed stream ' + params.headers.get('multiplex-at') + ', got status: ' + res.status)
961
963
 
962
- if (res.headers.get('Multiplex-Version') !== '0.0.1') throw new Error('Could not establish multiplexed stream ' + params.headers.get('multiplexer') + ', got unknown version: ' + res.headers.get('Multiplex-Version'))
964
+ if (res.headers.get('Multiplex-Version') !== multiplex_version) throw new Error('Could not establish multiplexed stream ' + params.headers.get('multiplex-at') + ', got unknown version: ' + res.headers.get('Multiplex-Version'))
963
965
 
964
966
  // we want to present the illusion that the connection is still open,
965
967
  // and therefor closable with "abort",
@@ -1022,7 +1024,7 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
1022
1024
 
1023
1025
  // add a convenience property for the user to know if
1024
1026
  // this response is being multiplexed
1025
- res.multiplexer = params.headers.get('multiplexer')
1027
+ res.is_multiplexed = true
1026
1028
 
1027
1029
  // return the fake response object
1028
1030
  return res
@@ -1038,7 +1040,7 @@ async function multiplex_fetch(url, params, skip_multiplex_method) {
1038
1040
  return await (await multiplex_fetch.multiplexers[mux_key])(url, params)
1039
1041
  }
1040
1042
 
1041
- // waits on reader for chunks like: 123 bytes for stream ABC\r\n..123 bytes..
1043
+ // waits on reader for chunks like: 123 bytes for request ABC\r\n..123 bytes..
1042
1044
  // which would trigger cb("ABC", bytes)
1043
1045
  async function parse_multiplex_stream(reader, cb, on_error) {
1044
1046
  try {
@@ -1072,7 +1074,7 @@ async function parse_multiplex_stream(reader, cb, on_error) {
1072
1074
  }
1073
1075
  if (headerComplete) {
1074
1076
  var headerStr = new TextDecoder().decode(buffers[0].slice(0, header_length))
1075
- var m = headerStr.match(/^[\r\n]*((\d+) bytes for|close) stream ([A-Za-z0-9_-]+)\r\n$/)
1077
+ var m = headerStr.match(/^[\r\n]*((\d+) bytes for|close) request ([A-Za-z0-9_-]+)\r\n$/)
1076
1078
  if (!m) throw new Error('invalid multiplex header')
1077
1079
  stream_id = m[3]
1078
1080
 
@@ -243,9 +243,10 @@ function braidify (req, res, next) {
243
243
  req.subscribe = subscribe
244
244
 
245
245
  // Multiplexer stuff
246
- if (braidify.use_multiplexing &&
246
+ var multiplex_version = '1.0'
247
+ if ((braidify.enable_multiplex ?? true) &&
247
248
  (req.method === 'MULTIPLEX' || req.url.startsWith('/.well-known/multiplex/')) &&
248
- req.headers['multiplex-version'] === '0.0.1') {
249
+ req.headers['multiplex-version'] === multiplex_version) {
249
250
 
250
251
  // let the caller know we're handling things
251
252
  req.is_multiplexer = res.is_multiplexer = true
@@ -262,6 +263,17 @@ function braidify (req, res, next) {
262
263
  if (!stream) {
263
264
  // maintain a Map of all the multiplexers
264
265
  if (!braidify.multiplexers) braidify.multiplexers = new Map()
266
+
267
+ // if this multiplexer already exists, respond with an error
268
+ if (braidify.multiplexers.has(multiplexer)) {
269
+ res.writeHead(409, 'Conflict', {'Content-Type': 'application/json'})
270
+ return res.end(JSON.stringify({
271
+ error: 'Multiplexer already exists',
272
+ message: `Cannot create duplicate multiplexer with ID '${multiplexer}'`,
273
+ details: 'This multiplexer ID must be unique'
274
+ }))
275
+ }
276
+
265
277
  braidify.multiplexers.set(multiplexer, {streams: new Map(), res})
266
278
 
267
279
  // when the response closes,
@@ -274,7 +286,7 @@ function braidify (req, res, next) {
274
286
  // keep the connection open,
275
287
  // so people can send multiplexed data to it
276
288
  res.writeHead(200, 'OK', {
277
- 'Multiplex-Version': '0.0.1',
289
+ 'Multiplex-Version': multiplex_version,
278
290
  'Incremental': '?1',
279
291
  'Cache-Control': 'no-cache',
280
292
  'X-Accel-Buffering': 'no',
@@ -306,7 +318,7 @@ function braidify (req, res, next) {
306
318
  s()
307
319
 
308
320
  // let the requester know we succeeded
309
- res.writeHead(200, 'OK', { 'Multiplex-Version': '0.0.1' })
321
+ res.writeHead(200, 'OK', { 'Multiplex-Version': multiplex_version })
310
322
  return res.end(``)
311
323
  }
312
324
  }
@@ -314,12 +326,12 @@ function braidify (req, res, next) {
314
326
  // a multiplexer header means the user wants to send the
315
327
  // results of this request to the provided multiplexer,
316
328
  // tagged with the given stream id
317
- if (braidify.use_multiplexing &&
318
- req.headers.multiplexer &&
319
- req.headers['multiplex-version'] === '0.0.1') {
329
+ if ((braidify.enable_multiplex ?? true) &&
330
+ req.headers['multiplex-at'] &&
331
+ req.headers['multiplex-version'] === multiplex_version) {
320
332
 
321
333
  // parse the multiplexer id and stream id from the header
322
- var [multiplexer, stream] = req.headers.multiplexer.split('/').slice(3)
334
+ var [multiplexer, stream] = req.headers['multiplex-at'].split('/').slice(3)
323
335
 
324
336
  // find the multiplexer object (contains a response object)
325
337
  var m = braidify.multiplexers?.get(multiplexer)
@@ -349,16 +361,16 @@ function braidify (req, res, next) {
349
361
  if (og_stream) {
350
362
  og_stream.respond({
351
363
  ':status': 293,
352
- Multiplexer: req.headers.multiplexer,
353
- 'Multiplex-Version': '0.0.1',
364
+ 'Multiplex-At': req.headers['multiplex-at'],
365
+ 'Multiplex-Version': multiplex_version,
354
366
  ...Object.fromEntries(cors_headers)
355
367
  })
356
368
  og_stream.write('Ok.')
357
369
  og_stream.end()
358
370
  } else {
359
371
  og_socket.write('HTTP/1.1 293 Responded via multiplexer\r\n')
360
- og_socket.write(`Multiplexer: ${req.headers.multiplexer}\r\n`)
361
- og_socket.write(`Multiplex-Version: 0.0.1\r\n`)
372
+ og_socket.write(`Multiplex-At: ${req.headers['multiplex-at']}\r\n`)
373
+ og_socket.write(`Multiplex-Version: ${multiplex_version}\r\n`)
362
374
  cors_headers.forEach(([key, value]) =>
363
375
  og_socket.write(`${key}: ${value}\r\n`))
364
376
  og_socket.write('\r\n')
@@ -383,11 +395,11 @@ function braidify (req, res, next) {
383
395
 
384
396
  try {
385
397
  var len = Buffer.isBuffer(chunk) ? chunk.length : Buffer.byteLength(chunk, encoding)
386
- this.multiplexer.res.write(`${len} bytes for stream ${this.stream}\r\n`)
398
+ this.multiplexer.res.write(`${len} bytes for request ${this.stream}\r\n`)
387
399
  this.multiplexer.res.write(chunk, encoding, callback)
388
400
 
389
401
  // console.log(`wrote:`)
390
- // console.log(`${len} bytes for stream /${this.stream}\r\n`)
402
+ // console.log(`${len} bytes for request /${this.stream}\r\n`)
391
403
  // if (Buffer.isBuffer(chunk)) console.log(new TextDecoder().decode(chunk))
392
404
  // else console.log('STRING?: ' + chunk)
393
405
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "braid-http",
3
- "version": "1.3.39",
3
+ "version": "1.3.40",
4
4
  "description": "An implementation of Braid-HTTP for Node.js and Browsers",
5
5
  "scripts": {
6
6
  "test": "node test/server.js"