amqplib 0.5.1 → 0.5.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.
- package/CHANGELOG.md +21 -0
- package/Makefile +1 -1
- package/README.md +2 -2
- package/callback_api.js +1 -0
- package/channel_api.js +1 -0
- package/examples/headers.js +2 -2
- package/examples/receive_generator.js +39 -0
- package/examples/send_generators.js +1 -1
- package/examples/ssl.js +1 -1
- package/examples/tutorials/callback_api/emit_log.js +1 -1
- package/examples/tutorials/callback_api/emit_log_direct.js +1 -1
- package/examples/tutorials/callback_api/emit_log_topic.js +1 -1
- package/examples/tutorials/callback_api/new_task.js +1 -1
- package/examples/tutorials/callback_api/rpc_client.js +1 -1
- package/examples/tutorials/callback_api/rpc_server.js +1 -1
- package/examples/tutorials/callback_api/send.js +1 -1
- package/examples/tutorials/emit_log.js +1 -1
- package/examples/tutorials/emit_log_direct.js +1 -1
- package/examples/tutorials/emit_log_topic.js +1 -1
- package/examples/tutorials/new_task.js +1 -1
- package/examples/tutorials/rpc_client.js +1 -1
- package/examples/tutorials/rpc_server.js +1 -1
- package/examples/tutorials/send.js +1 -1
- package/examples/waitForConfirms.js +1 -1
- package/lib/channel.js +2 -2
- package/lib/codec.js +64 -38
- package/lib/connect.js +33 -12
- package/lib/connection.js +4 -3
- package/lib/credentials.js +6 -3
- package/lib/defs.js +75 -75
- package/lib/frame.js +2 -1
- package/package.json +4 -3
- package/test/callback_api.js +6 -5
- package/test/channel.js +15 -14
- package/test/channel_api.js +25 -24
- package/test/codec.js +48 -9
- package/test/connect.js +63 -3
- package/test/connection.js +10 -9
- package/test/data.js +32 -9
- package/test/frame.js +4 -4
- package/test/util.js +14 -0
- package/.npmignore +0 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Change log for amqplib
|
|
2
2
|
|
|
3
|
+
## Changes in v0.5.2
|
|
4
|
+
|
|
5
|
+
git log v0.5.1..v0.5.2
|
|
6
|
+
|
|
7
|
+
* Increase encoding buffer to accommodate large header values
|
|
8
|
+
([PR 367](https://github.com/squaremo/amqp.node/pull/367))
|
|
9
|
+
* Bring code up to date with new Buffer interface
|
|
10
|
+
([PR 350](https://github.com/squaremo/amqp.node/pull/350))
|
|
11
|
+
* Fix dangling connection problem
|
|
12
|
+
([PR 340](https://github.com/squaremo/amqp.node/pull/340))
|
|
13
|
+
* Clear up URL credentials parsing
|
|
14
|
+
([PR 330](https://github.com/squaremo/amqp.node/pull/330))
|
|
15
|
+
* Allow connection params to be suppied in object
|
|
16
|
+
([PR 304](https://github.com/squaremo/amqp.node/pull/304))
|
|
17
|
+
* Support explicit numeric types in field tables (e.g., headers)
|
|
18
|
+
([PR 389](https://github.com/squaremo/amqp.node/pull/389), from a
|
|
19
|
+
suggestion in
|
|
20
|
+
[issue 358](https://github.com/squaremo/amqp.node/issues/358))
|
|
21
|
+
|
|
22
|
+
Thank you to all contributors, of PRs, issues and comments.
|
|
23
|
+
|
|
3
24
|
## Changes in v0.5.1
|
|
4
25
|
|
|
5
26
|
git log v0.5.0..v0.5.1
|
package/Makefile
CHANGED
|
@@ -2,7 +2,7 @@ RABBITMQ_SRC_VERSION=rabbitmq_v3_2_1
|
|
|
2
2
|
JSON=amqp-rabbitmq-0.9.1.json
|
|
3
3
|
RABBITMQ_CODEGEN=https://raw.githubusercontent.com/rabbitmq/rabbitmq-codegen
|
|
4
4
|
AMQP_JSON=$(RABBITMQ_CODEGEN)/$(RABBITMQ_SRC_VERSION)/$(JSON)
|
|
5
|
-
NODEJS_VERSIONS='0.8' '0.9' '0.10' '0.11' '0.12' '1.6' '2.5' '3.3' '4.2' '5.5' '6.2'
|
|
5
|
+
NODEJS_VERSIONS='0.8' '0.9' '0.10' '0.11' '0.12' '1.6' '2.5' '3.3' '4.2' '5.5' '6.2' '8.9' '9.1'
|
|
6
6
|
|
|
7
7
|
MOCHA=./node_modules/.bin/mocha
|
|
8
8
|
_MOCHA=./node_modules/.bin/_mocha
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* [Examples from RabbitMQ tutorials][tutes]
|
|
11
11
|
|
|
12
12
|
A library for making AMQP 0-9-1 clients for Node.JS, and an AMQP 0-9-1
|
|
13
|
-
client for Node.JS v0.8-12, v4
|
|
13
|
+
client for Node.JS v0.8-0.12, v4-v9, and the intervening io.js
|
|
14
14
|
releases.
|
|
15
15
|
|
|
16
16
|
This library does not implement [AMQP
|
|
@@ -21,6 +21,7 @@ Project status:
|
|
|
21
21
|
|
|
22
22
|
- Expected to work
|
|
23
23
|
- Complete high-level and low-level APIs (i.e., all bits of the protocol)
|
|
24
|
+
- Stable APIs
|
|
24
25
|
- A fair few tests
|
|
25
26
|
- Measured test coverage
|
|
26
27
|
- Ports of the [RabbitMQ tutorials][rabbitmq-tutes] as [examples][tutes]
|
|
@@ -29,7 +30,6 @@ Project status:
|
|
|
29
30
|
Still working on:
|
|
30
31
|
|
|
31
32
|
- Getting to 100% (or very close to 100%) test coverage
|
|
32
|
-
- Settling on completely stable APIs
|
|
33
33
|
|
|
34
34
|
## Callback API example
|
|
35
35
|
|
package/callback_api.js
CHANGED
package/channel_api.js
CHANGED
package/examples/headers.js
CHANGED
|
@@ -37,6 +37,6 @@ function bindAndConsume(ch, ex, q) {
|
|
|
37
37
|
|
|
38
38
|
function send(ch, ex) {
|
|
39
39
|
// The headers for a message are given as an option to `publish`:
|
|
40
|
-
ch.publish(ex.exchange, '',
|
|
41
|
-
ch.publish(ex.exchange, '',
|
|
40
|
+
ch.publish(ex.exchange, '', Buffer.from('hello'), {headers: {baz: 'boo'}});
|
|
41
|
+
ch.publish(ex.exchange, '', Buffer.from('world'), {headers: {foo: 'bar'}});
|
|
42
42
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict';
|
|
4
|
+
const co = require('co');
|
|
5
|
+
const amqp = require('amqplib');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
|
|
8
|
+
co(function* () {
|
|
9
|
+
const myConsumer = (msg) => {
|
|
10
|
+
if (msg !== null) {
|
|
11
|
+
console.log('consuming message %s in generator', JSON.stringify(msg.content.toString()));
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
const conn = yield amqp.connect('amqp://localhost');
|
|
15
|
+
try {
|
|
16
|
+
// create a message to consume
|
|
17
|
+
const q = 'hello';
|
|
18
|
+
const msg = 'Hello World!';
|
|
19
|
+
const channel = yield conn.createChannel();
|
|
20
|
+
yield channel.assertQueue(q);
|
|
21
|
+
channel.sendToQueue(q, Buffer.from(msg));
|
|
22
|
+
console.log(" [x] Sent '%s'", msg);
|
|
23
|
+
// consume the message
|
|
24
|
+
yield channel.consume(q, myConsumer, { noAck: true });
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
throw e;
|
|
28
|
+
}
|
|
29
|
+
}).catch(err => {
|
|
30
|
+
console.warn('Error:', err);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const rl = readline.createInterface({
|
|
34
|
+
input: process.stdin,
|
|
35
|
+
output: process.stdout
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// pend until message is consumed
|
|
39
|
+
rl.question('newline to exit', () => process.exit());
|
|
@@ -21,7 +21,7 @@ co(function* () {
|
|
|
21
21
|
|
|
22
22
|
yield channel.assertQueue(q);
|
|
23
23
|
|
|
24
|
-
channel.sendToQueue(q,
|
|
24
|
+
channel.sendToQueue(q, Buffer.from(msg));
|
|
25
25
|
|
|
26
26
|
// if message has been nacked, this will result in an error (rejected promise);
|
|
27
27
|
yield channel.waitForConfirms();
|
package/examples/ssl.js
CHANGED
|
@@ -59,6 +59,6 @@ var open = amqp.connect('amqps://localhost', opts);
|
|
|
59
59
|
open.then(function(conn) {
|
|
60
60
|
process.on('SIGINT', conn.close.bind(conn));
|
|
61
61
|
return conn.createChannel().then(function(ch) {
|
|
62
|
-
ch.sendToQueue('foo',
|
|
62
|
+
ch.sendToQueue('foo', Buffer.from('Hello World!'));
|
|
63
63
|
});
|
|
64
64
|
}).then(null, console.warn);
|
|
@@ -17,7 +17,7 @@ function on_connect(err, conn) {
|
|
|
17
17
|
ch.assertExchange(ex, 'fanout', {durable: false});
|
|
18
18
|
var msg = process.argv.slice(2).join(' ') ||
|
|
19
19
|
'info: Hello World!';
|
|
20
|
-
ch.publish(ex, '',
|
|
20
|
+
ch.publish(ex, '', Buffer.from(msg));
|
|
21
21
|
console.log(" [x] Sent '%s'", msg);
|
|
22
22
|
ch.close(function() { conn.close(); });
|
|
23
23
|
}
|
|
@@ -20,7 +20,7 @@ function on_connect(err, conn) {
|
|
|
20
20
|
function on_channel_open(err, ch) {
|
|
21
21
|
if (err !== null) return bail(err, conn);
|
|
22
22
|
ch.assertExchange(ex, 'direct', exopts, function(err, ok) {
|
|
23
|
-
ch.publish(ex, severity,
|
|
23
|
+
ch.publish(ex, severity, Buffer.from(message));
|
|
24
24
|
ch.close(function() { conn.close(); });
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -17,7 +17,7 @@ function on_connect(err, conn) {
|
|
|
17
17
|
conn.createChannel(function(err, ch) {
|
|
18
18
|
ch.assertExchange(ex, 'topic', exopts, function(err, ok) {
|
|
19
19
|
if (err !== null) return bail(err, conn);
|
|
20
|
-
ch.publish(ex, key,
|
|
20
|
+
ch.publish(ex, key, Buffer.from(message));
|
|
21
21
|
console.log(" [x] Sent %s:'%s'", key, message);
|
|
22
22
|
ch.close(function() { conn.close(); });
|
|
23
23
|
});
|
|
@@ -17,7 +17,7 @@ function on_connect(err, conn) {
|
|
|
17
17
|
ch.assertQueue(q, {durable: true}, function(err, _ok) {
|
|
18
18
|
if (err !== null) return bail(err, conn);
|
|
19
19
|
var msg = process.argv.slice(2).join(' ') || "Hello World!";
|
|
20
|
-
ch.sendToQueue(q,
|
|
20
|
+
ch.sendToQueue(q, Buffer.from(msg), {persistent: true});
|
|
21
21
|
console.log(" [x] Sent '%s'", msg);
|
|
22
22
|
ch.close(function() { conn.close(); });
|
|
23
23
|
});
|
|
@@ -39,7 +39,7 @@ function on_connect(err, conn) {
|
|
|
39
39
|
var queue = ok.queue;
|
|
40
40
|
ch.consume(queue, maybeAnswer, {noAck:true});
|
|
41
41
|
console.log(' [x] Requesting fib(%d)', n);
|
|
42
|
-
ch.sendToQueue('rpc_queue',
|
|
42
|
+
ch.sendToQueue('rpc_queue', Buffer.from(n.toString()), {
|
|
43
43
|
replyTo: queue, correlationId: correlationId
|
|
44
44
|
});
|
|
45
45
|
});
|
|
@@ -35,7 +35,7 @@ function on_connect(err, conn) {
|
|
|
35
35
|
var n = parseInt(msg.content.toString());
|
|
36
36
|
console.log(' [.] fib(%d)', n);
|
|
37
37
|
ch.sendToQueue(msg.properties.replyTo,
|
|
38
|
-
|
|
38
|
+
Buffer.from(fib(n).toString()),
|
|
39
39
|
{correlationId: msg.properties.correlationId});
|
|
40
40
|
ch.ack(msg);
|
|
41
41
|
}
|
|
@@ -17,7 +17,7 @@ function on_connect(err, conn) {
|
|
|
17
17
|
if (err !== null) return bail(err, conn);
|
|
18
18
|
ch.assertQueue(q, {durable: false}, function(err, ok) {
|
|
19
19
|
if (err !== null) return bail(err, conn);
|
|
20
|
-
ch.sendToQueue(q,
|
|
20
|
+
ch.sendToQueue(q, Buffer.from(msg));
|
|
21
21
|
console.log(" [x] Sent '%s'", msg);
|
|
22
22
|
ch.close(function() { conn.close(); });
|
|
23
23
|
});
|
|
@@ -11,7 +11,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
11
11
|
'info: Hello World!';
|
|
12
12
|
|
|
13
13
|
return ok.then(function() {
|
|
14
|
-
ch.publish(ex, '',
|
|
14
|
+
ch.publish(ex, '', Buffer.from(message));
|
|
15
15
|
console.log(" [x] Sent '%s'", message);
|
|
16
16
|
return ch.close();
|
|
17
17
|
});
|
|
@@ -12,7 +12,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
12
12
|
var ok = ch.assertExchange(ex, 'direct', {durable: false});
|
|
13
13
|
|
|
14
14
|
return ok.then(function() {
|
|
15
|
-
ch.publish(ex, severity,
|
|
15
|
+
ch.publish(ex, severity, Buffer.from(message));
|
|
16
16
|
console.log(" [x] Sent %s:'%s'", severity, message);
|
|
17
17
|
return ch.close();
|
|
18
18
|
});
|
|
@@ -11,7 +11,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
11
11
|
var ex = 'topic_logs';
|
|
12
12
|
var ok = ch.assertExchange(ex, 'topic', {durable: false});
|
|
13
13
|
return ok.then(function() {
|
|
14
|
-
ch.publish(ex, key,
|
|
14
|
+
ch.publish(ex, key, Buffer.from(message));
|
|
15
15
|
console.log(" [x] Sent %s:'%s'", key, message);
|
|
16
16
|
return ch.close();
|
|
17
17
|
});
|
|
@@ -10,7 +10,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
10
10
|
|
|
11
11
|
return ok.then(function() {
|
|
12
12
|
var msg = process.argv.slice(2).join(' ') || "Hello World!";
|
|
13
|
-
ch.sendToQueue(q,
|
|
13
|
+
ch.sendToQueue(q, Buffer.from(msg), {deliveryMode: true});
|
|
14
14
|
console.log(" [x] Sent '%s'", msg);
|
|
15
15
|
return ch.close();
|
|
16
16
|
});
|
|
@@ -40,7 +40,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
40
40
|
|
|
41
41
|
ok = ok.then(function(queue) {
|
|
42
42
|
console.log(' [x] Requesting fib(%d)', n);
|
|
43
|
-
ch.sendToQueue('rpc_queue',
|
|
43
|
+
ch.sendToQueue('rpc_queue', Buffer.from(n.toString()), {
|
|
44
44
|
correlationId: corrId, replyTo: queue
|
|
45
45
|
});
|
|
46
46
|
});
|
|
@@ -31,7 +31,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
31
31
|
console.log(' [.] fib(%d)', n);
|
|
32
32
|
var response = fib(n);
|
|
33
33
|
ch.sendToQueue(msg.properties.replyTo,
|
|
34
|
-
|
|
34
|
+
Buffer.from(response.toString()),
|
|
35
35
|
{correlationId: msg.properties.correlationId});
|
|
36
36
|
ch.ack(msg);
|
|
37
37
|
}
|
|
@@ -15,7 +15,7 @@ amqp.connect('amqp://localhost').then(function(conn) {
|
|
|
15
15
|
// (when `false`) that you should wait for the event `'drain'`
|
|
16
16
|
// to fire before writing again. We're just doing the one write,
|
|
17
17
|
// so we'll ignore it.
|
|
18
|
-
ch.sendToQueue(q,
|
|
18
|
+
ch.sendToQueue(q, Buffer.from(msg));
|
|
19
19
|
console.log(" [x] Sent '%s'", msg);
|
|
20
20
|
return ch.close();
|
|
21
21
|
});
|
|
@@ -12,7 +12,7 @@ function mkCallback(i) {
|
|
|
12
12
|
amqp.connect().then(function(c) {
|
|
13
13
|
c.createConfirmChannel().then(function(ch) {
|
|
14
14
|
for (var i=0; i < NUM_MSGS; i++) {
|
|
15
|
-
ch.publish('amq.topic', 'whatever',
|
|
15
|
+
ch.publish('amq.topic', 'whatever', Buffer.from('blah'), {}, mkCallback(i));
|
|
16
16
|
}
|
|
17
17
|
ch.waitForConfirms().then(function() {
|
|
18
18
|
console.log('All messages done');
|
package/lib/channel.js
CHANGED
|
@@ -16,7 +16,7 @@ var EventEmitter = require('events').EventEmitter;
|
|
|
16
16
|
var fmt = require('util').format;
|
|
17
17
|
var IllegalOperationError = require('./error').IllegalOperationError;
|
|
18
18
|
var stackCapture = require('./error').stackCapture;
|
|
19
|
-
|
|
19
|
+
var Buffer = require('safe-buffer').Buffer
|
|
20
20
|
function Channel(connection) {
|
|
21
21
|
EventEmitter.call( this );
|
|
22
22
|
this.connection = connection;
|
|
@@ -286,7 +286,7 @@ function acceptMessage(continuation) {
|
|
|
286
286
|
|
|
287
287
|
// for zero-length messages, content frames aren't required.
|
|
288
288
|
if (totalSize === 0) {
|
|
289
|
-
message.content =
|
|
289
|
+
message.content = Buffer.alloc(0);
|
|
290
290
|
continuation(message);
|
|
291
291
|
return acceptDeliveryOrReturn;
|
|
292
292
|
}
|
package/lib/codec.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
//
|
|
2
2
|
//
|
|
3
3
|
//
|
|
4
4
|
|
|
@@ -110,6 +110,40 @@ function encodeFieldValue(buffer, value, offset) {
|
|
|
110
110
|
type = value['!'];
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
+
// If it's a JS number, we'll have to guess what type to encode it
|
|
114
|
+
// as.
|
|
115
|
+
if (type == 'number') {
|
|
116
|
+
// Making assumptions about the kind of number (floating point
|
|
117
|
+
// v integer, signed, unsigned, size) desired is dangerous in
|
|
118
|
+
// general; however, in practice RabbitMQ uses only
|
|
119
|
+
// longstrings and unsigned integers in its arguments, and
|
|
120
|
+
// other clients generally conflate number types anyway. So
|
|
121
|
+
// the only distinction we care about is floating point vs
|
|
122
|
+
// integers, preferring integers since those can be promoted
|
|
123
|
+
// if necessary. If floating point is required, we may as well
|
|
124
|
+
// use double precision.
|
|
125
|
+
if (isFloatingPoint(val)) {
|
|
126
|
+
type = 'double';
|
|
127
|
+
}
|
|
128
|
+
else { // only signed values are used in tables by
|
|
129
|
+
// RabbitMQ. It *used* to (< v3.3.0) treat the byte 'b'
|
|
130
|
+
// type as unsigned, but most clients (and the spec)
|
|
131
|
+
// think it's signed, and now RabbitMQ does too.
|
|
132
|
+
if (val < 128 && val >= -128) {
|
|
133
|
+
type = 'byte';
|
|
134
|
+
}
|
|
135
|
+
else if (val >= -0x8000 && val < 0x8000) {
|
|
136
|
+
type = 'short'
|
|
137
|
+
}
|
|
138
|
+
else if (val >= -0x80000000 && val < 0x80000000) {
|
|
139
|
+
type = 'int';
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
type = 'long';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
113
147
|
function tag(t) { buffer.write(t, offset); offset++; }
|
|
114
148
|
|
|
115
149
|
switch (type) {
|
|
@@ -141,44 +175,36 @@ function encodeFieldValue(buffer, value, offset) {
|
|
|
141
175
|
tag('t');
|
|
142
176
|
buffer.writeUInt8((val) ? 1 : 0, offset); offset++;
|
|
143
177
|
break;
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// type as unsigned, but most clients (and the spec)
|
|
162
|
-
// think it's signed, and now RabbitMQ does too.
|
|
163
|
-
if (val < 128 && val >= -128) {
|
|
164
|
-
tag('b');
|
|
165
|
-
buffer.writeInt8(val, offset); offset++;
|
|
166
|
-
}
|
|
167
|
-
else if (val >= -0x8000 && val < 0x8000) { // short
|
|
168
|
-
tag('s');
|
|
169
|
-
buffer.writeInt16BE(val, offset); offset += 2;
|
|
170
|
-
}
|
|
171
|
-
else if (val >= -0x80000000 && val < 0x80000000) { // int
|
|
172
|
-
tag('I');
|
|
173
|
-
buffer.writeInt32BE(val, offset); offset += 4;
|
|
174
|
-
}
|
|
175
|
-
else { // long
|
|
176
|
-
tag('l');
|
|
177
|
-
ints.writeInt64BE(buffer, val, offset); offset += 8;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
178
|
+
// These are the types that are either guessed above, or
|
|
179
|
+
// explicitly given using the {'!': type} notation.
|
|
180
|
+
case 'double':
|
|
181
|
+
case 'float64':
|
|
182
|
+
tag('d');
|
|
183
|
+
buffer.writeDoubleBE(val, offset);
|
|
184
|
+
offset += 8;
|
|
185
|
+
break;
|
|
186
|
+
case 'byte':
|
|
187
|
+
case 'int8':
|
|
188
|
+
tag('b');
|
|
189
|
+
buffer.writeInt8(val, offset); offset++;
|
|
190
|
+
break;
|
|
191
|
+
case 'short':
|
|
192
|
+
case 'int16':
|
|
193
|
+
tag('s');
|
|
194
|
+
buffer.writeInt16BE(val, offset); offset += 2;
|
|
180
195
|
break;
|
|
181
|
-
|
|
196
|
+
case 'int':
|
|
197
|
+
case 'int32':
|
|
198
|
+
tag('I');
|
|
199
|
+
buffer.writeInt32BE(val, offset); offset += 4;
|
|
200
|
+
break;
|
|
201
|
+
case 'long':
|
|
202
|
+
case 'int64':
|
|
203
|
+
tag('l');
|
|
204
|
+
ints.writeInt64BE(buffer, val, offset); offset += 8;
|
|
205
|
+
break;
|
|
206
|
+
|
|
207
|
+
// Now for exotic types, those can _only_ be denoted by using
|
|
182
208
|
// `{'!': type, value: val}
|
|
183
209
|
case 'timestamp':
|
|
184
210
|
tag('T');
|
package/lib/connect.js
CHANGED
|
@@ -76,13 +76,22 @@ function openFrames(vhost, query, credentials, extraClientProperties) {
|
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
// Decide on credentials based on what we're supplied
|
|
79
|
+
// Decide on credentials based on what we're supplied. Note that in a
|
|
80
|
+
// parsed URL, the auth part is already URL-decoded, so e.g., '%3a' in
|
|
81
|
+
// the URL is already decoded to ':'. This is a bit unhelpful, as it
|
|
82
|
+
// means we can't tell whether a colon is a separator, or part of the
|
|
83
|
+
// username. Assume no colons in usernames.
|
|
80
84
|
function credentialsFromUrl(parts) {
|
|
81
85
|
var user = 'guest', passwd = 'guest';
|
|
82
86
|
if (parts.auth) {
|
|
83
|
-
var
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
var colon = parts.auth.indexOf(':')
|
|
88
|
+
if (colon == -1) {
|
|
89
|
+
user = parts.auth;
|
|
90
|
+
passwd = '';
|
|
91
|
+
} else {
|
|
92
|
+
user = parts.auth.substring(0, colon);
|
|
93
|
+
passwd = parts.auth.substring(colon+1);
|
|
94
|
+
}
|
|
86
95
|
}
|
|
87
96
|
return credentials.plain(user, passwd);
|
|
88
97
|
}
|
|
@@ -110,15 +119,23 @@ function connect(url, socketOptions, openCallback) {
|
|
|
110
119
|
sockopts.port = url.port || ((protocol === 'amqp:') ? 5672 : 5671);
|
|
111
120
|
|
|
112
121
|
var user, pass;
|
|
113
|
-
if
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
// Only default if both are missing, to have the same behaviour as
|
|
123
|
+
// the stringly URL.
|
|
124
|
+
if (url.username == undefined && url.password == undefined) {
|
|
125
|
+
user = 'guest'; pass = 'guest';
|
|
116
126
|
} else {
|
|
117
|
-
user = url.username;
|
|
118
|
-
pass = url.password;
|
|
127
|
+
user = url.username || '';
|
|
128
|
+
pass = url.password || '';
|
|
119
129
|
}
|
|
120
130
|
|
|
121
|
-
|
|
131
|
+
var config = {
|
|
132
|
+
locale: url.locale,
|
|
133
|
+
channelMax: url.channelMax,
|
|
134
|
+
frameMax: url.frameMax,
|
|
135
|
+
heartbeat: url.heartbeat,
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
fields = openFrames(url.vhost, config, sockopts.credentials || credentials.plain(user, pass), extraClientProperties);
|
|
122
139
|
} else {
|
|
123
140
|
var parts = URL.parse(url, true); // yes, parse the query string
|
|
124
141
|
protocol = parts.protocol;
|
|
@@ -159,8 +176,11 @@ function connect(url, socketOptions, openCallback) {
|
|
|
159
176
|
}
|
|
160
177
|
|
|
161
178
|
if (timeout) {
|
|
162
|
-
sock.setTimeout(
|
|
163
|
-
|
|
179
|
+
sock.setTimeout(timeout, function() {
|
|
180
|
+
sock.end();
|
|
181
|
+
sock.destroy();
|
|
182
|
+
openCallback(new Error('connect ETIMEDOUT'));
|
|
183
|
+
});
|
|
164
184
|
}
|
|
165
185
|
|
|
166
186
|
sock.once('error', function(err) {
|
|
@@ -170,3 +190,4 @@ function connect(url, socketOptions, openCallback) {
|
|
|
170
190
|
}
|
|
171
191
|
|
|
172
192
|
module.exports.connect = connect;
|
|
193
|
+
module.exports.credentialsFromUrl = credentialsFromUrl;
|
package/lib/connection.js
CHANGED
|
@@ -9,6 +9,7 @@ var constants = defs.constants;
|
|
|
9
9
|
var frame = require('./frame');
|
|
10
10
|
var HEARTBEAT = frame.HEARTBEAT;
|
|
11
11
|
var Mux = require('./mux').Mux;
|
|
12
|
+
var Buffer = require('safe-buffer').Buffer
|
|
12
13
|
|
|
13
14
|
var Duplex =
|
|
14
15
|
require('stream').Duplex ||
|
|
@@ -43,7 +44,7 @@ function Connection(underlying) {
|
|
|
43
44
|
this.muxer = new Mux(stream);
|
|
44
45
|
|
|
45
46
|
// frames
|
|
46
|
-
this.rest =
|
|
47
|
+
this.rest = Buffer.alloc(0);
|
|
47
48
|
this.frameMax = constants.FRAME_MIN_SIZE;
|
|
48
49
|
this.sentSinceLastCheck = false;
|
|
49
50
|
this.recvSinceLastCheck = false;
|
|
@@ -550,7 +551,7 @@ C.sendMessage = function(channel,
|
|
|
550
551
|
var allLen = methodHeaderLen + bodyLen;
|
|
551
552
|
|
|
552
553
|
if (allLen < SINGLE_CHUNK_THRESHOLD) {
|
|
553
|
-
var all =
|
|
554
|
+
var all = Buffer.alloc(allLen);
|
|
554
555
|
var offset = mframe.copy(all, 0);
|
|
555
556
|
offset += pframe.copy(all, offset);
|
|
556
557
|
|
|
@@ -560,7 +561,7 @@ C.sendMessage = function(channel,
|
|
|
560
561
|
}
|
|
561
562
|
else {
|
|
562
563
|
if (methodHeaderLen < SINGLE_CHUNK_THRESHOLD) {
|
|
563
|
-
var both =
|
|
564
|
+
var both = Buffer.alloc(methodHeaderLen);
|
|
564
565
|
var offset = mframe.copy(both, 0);
|
|
565
566
|
pframe.copy(both, offset);
|
|
566
567
|
buffer.write(both);
|
package/lib/credentials.js
CHANGED
|
@@ -8,19 +8,22 @@
|
|
|
8
8
|
// * PLAIN (send username and password in the plain)
|
|
9
9
|
// * EXTERNAL (assume the server will figure out who you are from
|
|
10
10
|
// context, i.e., your SSL certificate)
|
|
11
|
+
var Buffer = require('safe-buffer').Buffer
|
|
11
12
|
|
|
12
13
|
module.exports.plain = function(user, passwd) {
|
|
13
14
|
return {
|
|
14
15
|
mechanism: 'PLAIN',
|
|
15
16
|
response: function() {
|
|
16
|
-
return
|
|
17
|
-
}
|
|
17
|
+
return Buffer.from(['', user, passwd].join(String.fromCharCode(0)))
|
|
18
|
+
},
|
|
19
|
+
username: user,
|
|
20
|
+
password: passwd
|
|
18
21
|
}
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
module.exports.external = function() {
|
|
22
25
|
return {
|
|
23
26
|
mechanism: 'EXTERNAL',
|
|
24
|
-
response: function() { return
|
|
27
|
+
response: function() { return Buffer.from(''); }
|
|
25
28
|
}
|
|
26
29
|
}
|