amqplib 0.5.1 → 0.5.5

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.
Files changed (46) hide show
  1. package/.npmignore +0 -1
  2. package/CHANGELOG.md +84 -0
  3. package/Makefile +2 -1
  4. package/README.md +4 -4
  5. package/bin/generate-defs.js +723 -0
  6. package/callback_api.js +1 -0
  7. package/channel_api.js +1 -0
  8. package/examples/headers.js +2 -2
  9. package/examples/receive_generator.js +39 -0
  10. package/examples/send_generators.js +1 -1
  11. package/examples/ssl.js +1 -1
  12. package/examples/tutorials/callback_api/emit_log.js +1 -1
  13. package/examples/tutorials/callback_api/emit_log_direct.js +1 -1
  14. package/examples/tutorials/callback_api/emit_log_topic.js +1 -1
  15. package/examples/tutorials/callback_api/new_task.js +1 -1
  16. package/examples/tutorials/callback_api/rpc_client.js +1 -1
  17. package/examples/tutorials/callback_api/rpc_server.js +1 -1
  18. package/examples/tutorials/callback_api/send.js +1 -1
  19. package/examples/tutorials/emit_log.js +1 -1
  20. package/examples/tutorials/emit_log_direct.js +1 -1
  21. package/examples/tutorials/emit_log_topic.js +1 -1
  22. package/examples/tutorials/new_task.js +1 -1
  23. package/examples/tutorials/rpc_client.js +1 -1
  24. package/examples/tutorials/rpc_server.js +1 -1
  25. package/examples/tutorials/send.js +1 -1
  26. package/examples/waitForConfirms.js +1 -1
  27. package/lib/api_args.js +2 -0
  28. package/lib/channel.js +30 -12
  29. package/lib/codec.js +64 -38
  30. package/lib/connect.js +26 -15
  31. package/lib/connection.js +6 -4
  32. package/lib/credentials.js +20 -3
  33. package/lib/defs.js +203 -75
  34. package/lib/frame.js +2 -1
  35. package/package-lock.json +711 -0
  36. package/package.json +11 -9
  37. package/test/callback_api.js +6 -5
  38. package/test/channel.js +88 -75
  39. package/test/channel_api.js +38 -24
  40. package/test/codec.js +48 -9
  41. package/test/connect.js +88 -3
  42. package/test/connection.js +57 -56
  43. package/test/data.js +32 -9
  44. package/test/frame.js +4 -4
  45. package/test/mux.js +10 -6
  46. package/test/util.js +16 -2
@@ -7,6 +7,7 @@ var succeed = util.succeed, fail = util.fail;
7
7
  var schedule = util.schedule;
8
8
  var randomString = util.randomString;
9
9
  var Promise = require('bluebird');
10
+ var Buffer = require('safe-buffer').Buffer;
10
11
 
11
12
  var URL = process.env.URL || 'amqp://localhost';
12
13
 
@@ -23,7 +24,7 @@ function expectFail(promise) {
23
24
 
24
25
  // I'll rely on operations being rejected, rather than the channel
25
26
  // close error, to detect failure.
26
- function ignore() {}
27
+ function ignore () {}
27
28
  function ignoreErrors(c) {
28
29
  c.on('error', ignore); return c;
29
30
  }
@@ -112,7 +113,7 @@ chtest("fail on reasserting exchange with different type",
112
113
  chtest("channel break on publishing to non-exchange", function(ch) {
113
114
  return new Promise(function(resolve) {
114
115
  ch.on('error', resolve);
115
- ch.publish(randomString(), '', new Buffer('foobar'));
116
+ ch.publish(randomString(), '', Buffer.from('foobar'));
116
117
  });
117
118
  });
118
119
 
@@ -179,7 +180,7 @@ chtest("send to queue and get from queue", function(ch) {
179
180
  var msg = randomString();
180
181
  return Promise.join(ch.assertQueue(q, QUEUE_OPTS), ch.purgeQueue(q))
181
182
  .then(function() {
182
- ch.sendToQueue(q, new Buffer(msg));
183
+ ch.sendToQueue(q, Buffer.from(msg));
183
184
  return waitForMessages(q);
184
185
  })
185
186
  .then(function() {
@@ -193,7 +194,7 @@ chtest("send to queue and get from queue", function(ch) {
193
194
 
194
195
  chtest("send (and get) zero content to queue", function(ch) {
195
196
  var q = 'test.send-to-q';
196
- var msg = new Buffer(0);
197
+ var msg = Buffer.alloc(0);
197
198
  return Promise.join(
198
199
  ch.assertQueue(q, QUEUE_OPTS),
199
200
  ch.purgeQueue(q))
@@ -224,7 +225,7 @@ chtest("route message", function(ch) {
224
225
  ch.purgeQueue(q),
225
226
  ch.bindQueue(q, ex, '', {}))
226
227
  .then(function() {
227
- ch.publish(ex, '', new Buffer(msg));
228
+ ch.publish(ex, '', Buffer.from(msg));
228
229
  return waitForMessages(q);})
229
230
  .then(function() {
230
231
  return ch.get(q, {noAck: true});})
@@ -239,7 +240,7 @@ chtest("purge queue", function(ch) {
239
240
  var q = 'test.purge-queue';
240
241
  return ch.assertQueue(q, {durable: false})
241
242
  .then(function() {
242
- ch.sendToQueue(q, new Buffer('foobar'));
243
+ ch.sendToQueue(q, Buffer.from('foobar'));
243
244
  return waitForMessages(q);})
244
245
  .then(function() {
245
246
  ch.purgeQueue(q);
@@ -262,7 +263,7 @@ chtest("unbind queue", function(ch) {
262
263
  ch.purgeQueue(q),
263
264
  ch.bindQueue(q, ex, '', {}))
264
265
  .then(function() {
265
- ch.publish(ex, '', new Buffer('foobar'));
266
+ ch.publish(ex, '', Buffer.from('foobar'));
266
267
  return waitForMessages(q);})
267
268
  .then(function() { // message got through!
268
269
  return ch.get(q, {noAck:true})
@@ -271,9 +272,9 @@ chtest("unbind queue", function(ch) {
271
272
  return ch.unbindQueue(q, ex, '', {});})
272
273
  .then(function() {
273
274
  // via the no-longer-existing binding
274
- ch.publish(ex, '', new Buffer(viabinding));
275
+ ch.publish(ex, '', Buffer.from(viabinding));
275
276
  // direct to the queue
276
- ch.sendToQueue(q, new Buffer(direct));
277
+ ch.sendToQueue(q, Buffer.from(direct));
277
278
  return waitForMessages(q);})
278
279
  .then(function() {return ch.get(q)})
279
280
  .then(function(m) {
@@ -305,7 +306,7 @@ chtest("consume via exchange-exchange binding", function(ch) {
305
306
  }
306
307
  ch.consume(q, delivery, {noAck: true})
307
308
  .then(function() {
308
- ch.publish(ex1, rk, new Buffer(msg));
309
+ ch.publish(ex1, rk, Buffer.from(msg));
309
310
  });
310
311
  });
311
312
  });
@@ -327,7 +328,7 @@ chtest("unbind exchange", function(ch) {
327
328
  ch.bindExchange(dest, source, '', {}),
328
329
  ch.bindQueue(q, dest, '', {}))
329
330
  .then(function() {
330
- ch.publish(source, '', new Buffer('foobar'));
331
+ ch.publish(source, '', Buffer.from('foobar'));
331
332
  return waitForMessages(q);})
332
333
  .then(function() { // message got through!
333
334
  return ch.get(q, {noAck:true})
@@ -336,9 +337,9 @@ chtest("unbind exchange", function(ch) {
336
337
  return ch.unbindExchange(dest, source, '', {});})
337
338
  .then(function() {
338
339
  // via the no-longer-existing binding
339
- ch.publish(source, '', new Buffer(viabinding));
340
+ ch.publish(source, '', Buffer.from(viabinding));
340
341
  // direct to the queue
341
- ch.sendToQueue(q, new Buffer(direct));
342
+ ch.sendToQueue(q, Buffer.from(direct));
342
343
  return waitForMessages(q);})
343
344
  .then(function() {return ch.get(q)})
344
345
  .then(function(m) {
@@ -360,7 +361,7 @@ chtest("cancel consumer", function(ch) {
360
361
  ch.consume(q, resolve, {noAck:true})
361
362
  .then(function(ok) {
362
363
  ctag = ok.consumerTag;
363
- ch.sendToQueue(q, new Buffer('foo'));
364
+ ch.sendToQueue(q, Buffer.from('foo'));
364
365
  }));
365
366
  });
366
367
 
@@ -368,7 +369,7 @@ chtest("cancel consumer", function(ch) {
368
369
  return recv1.then(function() {
369
370
  var recv2 = Promise.join(
370
371
  ch.cancel(ctag).then(function() {
371
- return ch.sendToQueue(q, new Buffer('bar'));
372
+ return ch.sendToQueue(q, Buffer.from('bar'));
372
373
  }),
373
374
  // but check a message did arrive in the queue
374
375
  waitForMessages(q))
@@ -412,8 +413,8 @@ chtest("ack", function(ch) {
412
413
  ch.assertQueue(q, QUEUE_OPTS),
413
414
  ch.purgeQueue(q))
414
415
  .then(function() {
415
- ch.sendToQueue(q, new Buffer(msg1));
416
- ch.sendToQueue(q, new Buffer(msg2));
416
+ ch.sendToQueue(q, Buffer.from(msg1));
417
+ ch.sendToQueue(q, Buffer.from(msg2));
417
418
  return waitForMessages(q, 2);
418
419
  })
419
420
  .then(function() {
@@ -441,7 +442,7 @@ chtest("nack", function(ch) {
441
442
  return Promise.join(
442
443
  ch.assertQueue(q, QUEUE_OPTS), ch.purgeQueue(q))
443
444
  .then(function() {
444
- ch.sendToQueue(q, new Buffer(msg1));
445
+ ch.sendToQueue(q, Buffer.from(msg1));
445
446
  return waitForMessages(q);})
446
447
  .then(function() {
447
448
  return ch.get(q, {noAck: false})})
@@ -466,7 +467,7 @@ chtest("reject", function(ch) {
466
467
  return Promise.join(
467
468
  ch.assertQueue(q, QUEUE_OPTS), ch.purgeQueue(q))
468
469
  .then(function() {
469
- ch.sendToQueue(q, new Buffer(msg1));
470
+ ch.sendToQueue(q, Buffer.from(msg1));
470
471
  return waitForMessages(q);})
471
472
  .then(function() {
472
473
  return ch.get(q, {noAck: false})})
@@ -488,8 +489,8 @@ chtest("prefetch", function(ch) {
488
489
  ch.assertQueue(q, QUEUE_OPTS), ch.purgeQueue(q),
489
490
  ch.prefetch(1))
490
491
  .then(function() {
491
- ch.sendToQueue(q, new Buffer('foobar'));
492
- ch.sendToQueue(q, new Buffer('foobar'));
492
+ ch.sendToQueue(q, Buffer.from('foobar'));
493
+ ch.sendToQueue(q, Buffer.from('foobar'));
493
494
  return waitForMessages(q, 2);
494
495
  })
495
496
  .then(function() {
@@ -526,7 +527,7 @@ confirmtest('message is confirmed', function(ch) {
526
527
  return Promise.join(
527
528
  ch.assertQueue(q, QUEUE_OPTS), ch.purgeQueue(q))
528
529
  .then(function() {
529
- return ch.sendToQueue(q, new Buffer('bleep'));
530
+ return ch.sendToQueue(q, Buffer.from('bleep'));
530
531
  });
531
532
  });
532
533
 
@@ -550,7 +551,7 @@ confirmtest('multiple confirms', function(ch) {
550
551
 
551
552
  function sendAndPushPromise() {
552
553
  var conf = Promise.fromCallback(function(cb) {
553
- return ch.sendToQueue(q, new Buffer('bleep'), {}, cb);
554
+ return ch.sendToQueue(q, Buffer.from('bleep'), {}, cb);
554
555
  });
555
556
  cs.push(conf);
556
557
  }
@@ -575,9 +576,22 @@ confirmtest('multiple confirms', function(ch) {
575
576
 
576
577
  confirmtest('wait for confirms', function(ch) {
577
578
  for (var i=0; i < 1000; i++) {
578
- ch.publish('', '', new Buffer('foobar'), {});
579
+ ch.publish('', '', Buffer.from('foobar'), {});
579
580
  }
580
581
  return ch.waitForConfirms();
581
582
  })
582
583
 
584
+ confirmtest('works when channel is closed', function(ch) {
585
+ for (var i=0; i < 1000; i++) {
586
+ ch.publish('', '', Buffer.from('foobar'), {});
587
+ }
588
+ return ch.close().then(function () {
589
+ return ch.waitForConfirms()
590
+ }).then(function () {
591
+ assert.strictEqual(true, false, 'Wait should have failed.')
592
+ }, function (e) {
593
+ assert.strictEqual(e.message, 'channel closed')
594
+ });
595
+ });
596
+
583
597
  });
package/test/codec.js CHANGED
@@ -4,7 +4,7 @@ var codec = require('../lib/codec');
4
4
  var defs = require('../lib/defs');
5
5
  var assert = require('assert');
6
6
  var ints = require('buffer-more-ints');
7
-
7
+ var Buffer = require('safe-buffer').Buffer
8
8
  var C = require('claire');
9
9
  var forAll = C.forAll;
10
10
 
@@ -31,12 +31,12 @@ var testCases = [
31
31
  ['float value', {double: 0.5}, [6,100,111,117,98,108,101,100,63,224,0,0,0,0,0,0]],
32
32
  ['negative float value', {double: -0.5}, [6,100,111,117,98,108,101,100,191,224,0,0,0,0,0,0]],
33
33
  // %% test some boundaries of precision?
34
-
34
+
35
35
  // string
36
36
  ['string', {string: "boop"}, [6,115,116,114,105,110,103,83,0,0,0,4,98,111,111,112]],
37
37
 
38
38
  // buffer -> byte array
39
- ['byte array from buffer', {bytes: new Buffer([1,2,3,4])},
39
+ ['byte array from buffer', {bytes: Buffer.from([1,2,3,4])},
40
40
  [5,98,121,116,101,115,120,0,0,0,4,1,2,3,4]],
41
41
 
42
42
  // boolean, void
@@ -64,12 +64,12 @@ function bufferToArray(b) {
64
64
  return Array.prototype.slice.call(b);
65
65
  }
66
66
 
67
- suite("Explicit encodings", function() {
67
+ suite("Implicit encodings", function() {
68
68
 
69
69
  testCases.forEach(function(tc) {
70
70
  var name = tc[0], val = tc[1], expect = tc[2];
71
71
  test(name, function() {
72
- var buffer = new Buffer(1000);
72
+ var buffer = Buffer.alloc(1000);
73
73
  var size = codec.encodeTable(buffer, val, 0);
74
74
  var result = buffer.slice(4, size);
75
75
  assert.deepEqual(expect, bufferToArray(result));
@@ -82,11 +82,11 @@ suite("Explicit encodings", function() {
82
82
  var amqp = require('./data');
83
83
 
84
84
  function roundtrip_table(t) {
85
- var buf = new Buffer(4096);
85
+ var buf = Buffer.alloc(4096);
86
86
  var size = codec.encodeTable(buf, t, 0);
87
87
  var decoded = codec.decodeFields(buf.slice(4, size)); // ignore the length-prefix
88
88
  try {
89
- assert.deepEqual(t, decoded);
89
+ assert.deepEqual(removeExplicitTypes(t), decoded);
90
90
  }
91
91
  catch (e) { return false; }
92
92
  return true;
@@ -119,6 +119,45 @@ suite("Roundtrip values", function() {
119
119
  });
120
120
  });
121
121
 
122
+ // When encoding, you can supply explicitly-typed fields like `{'!':
123
+ // int32, 50}`. Most of these do not appear in the decoded values, so
124
+ // to compare like-to-like we have to remove them from the input.
125
+ function removeExplicitTypes(input) {
126
+ switch (typeof input) {
127
+ case 'object':
128
+ if (input == null) {
129
+ return null;
130
+ }
131
+ if (Array.isArray(input)) {
132
+ var newArr = [];
133
+ for (var i = 0; i < input.length; i++) {
134
+ newArr[i] = removeExplicitTypes(input[i]);
135
+ }
136
+ return newArr;
137
+ }
138
+ if (Buffer.isBuffer(input)) {
139
+ return input;
140
+ }
141
+ switch (input['!']) {
142
+ case 'timestamp':
143
+ case 'decimal':
144
+ case 'float':
145
+ return input;
146
+ case undefined:
147
+ var newObj = {}
148
+ for (var k in input) {
149
+ newObj[k] = removeExplicitTypes(input[k]);
150
+ }
151
+ return newObj;
152
+ default:
153
+ return input.value;
154
+ }
155
+
156
+ default:
157
+ return input;
158
+ }
159
+ }
160
+
122
161
  // Asserts that the decoded fields are equal to the original fields,
123
162
  // or equal to a default where absent in the original. The defaults
124
163
  // depend on the type of method or properties.
@@ -141,11 +180,11 @@ function assertEqualModuloDefaults(original, decodedFields) {
141
180
  // given as strings rather than buffers, but the decoded values
142
181
  // will be buffers.
143
182
  assert.deepEqual((arg.type === 'longstr') ?
144
- new Buffer(arg.default) : arg.default,
183
+ Buffer.from(arg.default) : arg.default,
145
184
  decodedValue);
146
185
  }
147
186
  else {
148
- assert.deepEqual(originalValue, decodedValue);
187
+ assert.deepEqual(removeExplicitTypes(originalValue), decodedValue);
149
188
  }
150
189
  }
151
190
  catch (assertionErr) {
package/test/connect.js CHANGED
@@ -1,21 +1,67 @@
1
1
  'use strict';
2
2
 
3
3
  var connect = require('../lib/connect').connect;
4
+ var Buffer = require('safe-buffer').Buffer
5
+ var credentialsFromUrl = require('../lib/connect').credentialsFromUrl;
4
6
  var assert = require('assert');
5
7
  var util = require('./util');
6
8
  var net = require('net');
7
9
  var fail = util.fail, succeed = util.succeed,
8
- kCallback = util.kCallback;
10
+ kCallback = util.kCallback,
11
+ succeedIfAttributeEquals = util.succeedIfAttributeEquals;
12
+ var format = require('util').format;
9
13
 
10
14
  var URL = process.env.URL || 'amqp://localhost';
11
15
 
16
+ var urlparse = require('url-parse');
17
+
18
+ suite("Credentials", function() {
19
+
20
+ function checkCreds(creds, user, pass, done) {
21
+ if (creds.mechanism != 'PLAIN') {
22
+ return done('expected mechanism PLAIN');
23
+ }
24
+ if (creds.username != user || creds.password != pass) {
25
+ return done(format("expected '%s', '%s'; got '%s', '%s'",
26
+ user, pass, creds.username, creds.password));
27
+ }
28
+ done();
29
+ }
30
+
31
+ test("no creds", function(done) {
32
+ var parts = urlparse('amqp://localhost');
33
+ var creds = credentialsFromUrl(parts);
34
+ checkCreds(creds, 'guest', 'guest', done);
35
+ });
36
+ test("usual user:pass", function(done) {
37
+ var parts = urlparse('amqp://user:pass@localhost')
38
+ var creds = credentialsFromUrl(parts);
39
+ checkCreds(creds, 'user', 'pass', done);
40
+ });
41
+ test("missing user", function(done) {
42
+ var parts = urlparse('amqps://:password@localhost');
43
+ var creds = credentialsFromUrl(parts);
44
+ checkCreds(creds, '', 'password', done);
45
+ });
46
+ test("missing password", function(done) {
47
+ var parts = urlparse('amqps://username:@localhost');
48
+ var creds = credentialsFromUrl(parts);
49
+ checkCreds(creds, 'username', '', done);
50
+ });
51
+ test("escaped colons", function(done) {
52
+ var parts = urlparse('amqp://user%3Aname:pass%3Aword@localhost')
53
+ var creds = credentialsFromUrl(parts);
54
+ checkCreds(creds, 'user:name', 'pass:word', done);
55
+ });
56
+ });
57
+
12
58
  suite("Connect API", function() {
13
59
 
14
60
  test("Connection refused", function(done) {
15
61
  connect('amqp://localhost:23450', {},
16
62
  kCallback(fail(done), succeed(done)));
17
63
  });
18
-
64
+
19
65
  // %% this ought to fail the promise, rather than throwing an error
20
66
  test("bad URL", function() {
21
67
  assert.throws(function() {
@@ -33,6 +79,33 @@ suite("Connect API", function() {
33
79
  connect(u, {}, kCallback(fail(done), succeed(done)));
34
80
  });
35
81
 
82
+ test("serverProperties", function(done) {
83
+ var url = require('url');
84
+ var parts = url.parse(URL, true);
85
+ var config = parts.query || {};
86
+ connect(config, {}, function(err, connection) {
87
+ if (err) { return done(err); }
88
+ assert.equal(connection.serverProperties.product, 'RabbitMQ');
89
+ done();
90
+ });
91
+ });
92
+
93
+ test("using custom heartbeat option", function(done) {
94
+ var url = require('url');
95
+ var parts = url.parse(URL, true);
96
+ var config = parts.query || {};
97
+ config.heartbeat = 20;
98
+ connect(config, {}, kCallback(succeedIfAttributeEquals('heartbeat', 20, done), fail(done)));
99
+ });
100
+
101
+ test("wrongly typed heartbeat option", function(done) {
102
+ var url = require('url');
103
+ var parts = url.parse(URL, true);
104
+ var config = parts.query || {};
105
+ config.heartbeat = 'NOT A NUMBER';
106
+ connect(config, {}, kCallback(fail(done), succeed(done)));
107
+ });
108
+
36
109
  test("using plain credentials", function(done) {
37
110
  var url = require('url');
38
111
  var parts = url.parse(URL, true);
@@ -45,10 +118,22 @@ suite("Connect API", function() {
45
118
  kCallback(succeed(done), fail(done)));
46
119
  });
47
120
 
121
+ test("using amqplain credentials", function(done) {
122
+ var url = require('url');
123
+ var parts = url.parse(URL, true);
124
+ var u = 'guest', p = 'guest';
125
+ if (parts.auth) {
126
+ var auth = parts.auth.split(":");
127
+ u = auth[0], p = auth[1];
128
+ }
129
+ connect(URL, {credentials: require('../lib/credentials').amqplain(u, p)},
130
+ kCallback(succeed(done), fail(done)));
131
+ });
132
+
48
133
  test("using unsupported mechanism", function(done) {
49
134
  var creds = {
50
135
  mechanism: 'UNSUPPORTED',
51
- response: function() { return new Buffer(''); }
136
+ response: function() { return Buffer.from(''); }
52
137
  };
53
138
  connect(URL, {credentials: creds},
54
139
  kCallback(fail(done), succeed(done)));