amqplib 0.10.6 → 0.10.8
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/.github/workflows/publish.yml +1 -1
- package/.github/workflows/test.yml +2 -2
- package/CHANGELOG.md +7 -0
- package/Makefile +1 -1
- package/README.md +13 -7
- package/lib/connection.js +1 -1
- package/lib/frame.js +119 -57
- package/package.json +1 -2
- package/test/frame.js +0 -6
|
@@ -24,9 +24,9 @@ jobs:
|
|
|
24
24
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
25
25
|
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v3
|
|
28
28
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
29
|
-
uses: actions/setup-node@
|
|
29
|
+
uses: actions/setup-node@v4
|
|
30
30
|
with:
|
|
31
31
|
node-version: ${{ matrix.node-version }}
|
|
32
32
|
cache: "npm"
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Change log for amqplib
|
|
2
2
|
|
|
3
|
+
## v0.10.8
|
|
4
|
+
- Updated README
|
|
5
|
+
|
|
6
|
+
## v0.10.7
|
|
7
|
+
- Remove bitsyntax dependency - See https://github.com/amqp-node/amqplib/pull/785. Thanks @ikenfin
|
|
8
|
+
- Stop checking if frame max is exceeded when parsing frames - See https://github.com/amqp-node/amqplib/pull/784. Thanks @ohroy
|
|
9
|
+
|
|
3
10
|
## v0.10.6
|
|
4
11
|
- Replace references to the old squaremo/amqp.name repo with ones to amqp-node/amqplib
|
|
5
12
|
- Use a frame_max of 131072 by default for RabbitMQ 4.1.0 compatibility
|
package/Makefile
CHANGED
|
@@ -2,7 +2,7 @@ RABBITMQ_SRC_VERSION=v3.12.13
|
|
|
2
2
|
JSON=amqp-rabbitmq-0.9.1.json
|
|
3
3
|
AMQP_JSON=https://raw.githubusercontent.com/rabbitmq/rabbitmq-server/$(RABBITMQ_SRC_VERSION)/deps/rabbitmq_codegen/$(JSON)
|
|
4
4
|
|
|
5
|
-
NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0' '20.10.0'
|
|
5
|
+
NODEJS_VERSIONS='10.21' '11.15' '12.18' '13.14' '14.5' '15.8' '16.3.0' '18.1.0' '20.10.0' '22.14.0'
|
|
6
6
|
|
|
7
7
|
MOCHA=./node_modules/.bin/mocha
|
|
8
8
|
_MOCHA=./node_modules/.bin/_mocha
|
package/README.md
CHANGED
|
@@ -5,21 +5,27 @@
|
|
|
5
5
|
[](https://github.com/amqp-node/amqplib/actions?query=workflow%3A%22Node.js+CI%22)
|
|
6
6
|
[](https://snyk.io/advisor/npm-package/amqplib)
|
|
7
7
|
|
|
8
|
+
A library for making AMQP 0-9-1 clients for Node.JS, and an AMQP 0-9-1 client for Node.JS v10+. This library does not implement [AMQP1.0](https://github.com/amqp-node/amqplib/issues/63) or [AMQP0-10](https://github.com/amqp-node/amqplib/issues/94).
|
|
9
|
+
|
|
8
10
|
npm install amqplib
|
|
9
11
|
|
|
12
|
+
## ❤️ Help Support Jack
|
|
13
|
+
One of my close friends, Jack, was recently diagnosed with terminal brain cancer (grade 4 astrocytoma). He’s a young father facing an unimaginably tough road with remarkable courage. Thanks to chemotherapy, radiotherapy, and your support, two of his tumours have stopped showing activity. Donations help Jack continue accessing promising complementary therapies, attend hospital appointments, and spend meaningful time with his children.
|
|
14
|
+
|
|
15
|
+
If you’ve benefited from amqplib, please consider supporting Jack’s journey through his [J Crushing Cancer](https://www.gofundme.com/f/j-crushing-cancer) gofundme page. Thank you - @cressie176
|
|
16
|
+
|
|
17
|
+
## RabbitMQ Compatibility
|
|
18
|
+
|
|
19
|
+
Only `0.10.7` and later versions of this library are compatible with RabbitMQ 4.1.0 (and later releases).
|
|
20
|
+
|
|
21
|
+
## Links
|
|
10
22
|
* [Change log][changelog]
|
|
11
23
|
* [GitHub pages][gh-pages]
|
|
12
24
|
* [API reference][gh-pages-apiref]
|
|
13
25
|
* [Troubleshooting][gh-pages-trouble]
|
|
14
26
|
* [Examples from RabbitMQ tutorials][tutes]
|
|
15
27
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
This library does not implement [AMQP
|
|
19
|
-
1.0](https://github.com/amqp-node/amqplib/issues/63) or [AMQP
|
|
20
|
-
0-10](https://github.com/amqp-node/amqplib/issues/94).
|
|
21
|
-
|
|
22
|
-
Project status:
|
|
28
|
+
## Project status
|
|
23
29
|
|
|
24
30
|
- Expected to work
|
|
25
31
|
- Complete high-level and low-level APIs (i.e., all bits of the protocol)
|
package/lib/connection.js
CHANGED
|
@@ -553,7 +553,7 @@ class Connection extends EventEmitter {
|
|
|
553
553
|
|
|
554
554
|
recvFrame () {
|
|
555
555
|
// %%% identifying invariants might help here?
|
|
556
|
-
var frame = parseFrame(this.rest
|
|
556
|
+
var frame = parseFrame(this.rest);
|
|
557
557
|
|
|
558
558
|
if (!frame) {
|
|
559
559
|
var incoming = this.stream.read();
|
package/lib/frame.js
CHANGED
|
@@ -4,12 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const ints = require('buffer-more-ints')
|
|
7
8
|
var defs = require('./defs');
|
|
8
9
|
var constants = defs.constants;
|
|
9
10
|
var decode = defs.decode;
|
|
10
11
|
|
|
11
|
-
var Bits = require('@acuminous/bitsyntax');
|
|
12
|
-
|
|
13
12
|
module.exports.PROTOCOL_HEADER = "AMQP" + String.fromCharCode(0, 0, 9, 1);
|
|
14
13
|
|
|
15
14
|
/*
|
|
@@ -33,74 +32,137 @@ FRAME_HEADER = constants.FRAME_HEADER,
|
|
|
33
32
|
FRAME_BODY = constants.FRAME_BODY,
|
|
34
33
|
FRAME_END = constants.FRAME_END;
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
// expected byte sizes for frame parts
|
|
36
|
+
const TYPE_BYTES = 1
|
|
37
|
+
const CHANNEL_BYTES = 2
|
|
38
|
+
const SIZE_BYTES = 4
|
|
39
|
+
const FRAME_HEADER_BYTES = TYPE_BYTES + CHANNEL_BYTES + SIZE_BYTES
|
|
40
|
+
const FRAME_END_BYTES = 1
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @typedef {{
|
|
44
|
+
* type: number,
|
|
45
|
+
* channel: number,
|
|
46
|
+
* size: number,
|
|
47
|
+
* payload: Buffer,
|
|
48
|
+
* rest: Buffer
|
|
49
|
+
* }} FrameStructure
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* This is a polyfill which will read a big int 64 bit as a number.
|
|
54
|
+
* @arg { Buffer } buffer
|
|
55
|
+
* @arg { number } offset
|
|
56
|
+
* @returns { number }
|
|
57
|
+
*/
|
|
58
|
+
function readInt64BE(buffer, offset) {
|
|
59
|
+
/**
|
|
60
|
+
* We try to use native implementation if available here because
|
|
61
|
+
* buffer-more-ints does not
|
|
62
|
+
*/
|
|
63
|
+
if (typeof Buffer.prototype.readBigInt64BE === 'function') {
|
|
64
|
+
return Number(buffer.readBigInt64BE(offset))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return ints.readInt64BE(buffer, offset)
|
|
68
|
+
}
|
|
40
69
|
|
|
41
70
|
// %%% TESTME possibly better to cons the first bit and write the
|
|
42
71
|
// second directly, in the absence of IO lists
|
|
43
|
-
|
|
44
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Make a frame header
|
|
74
|
+
* @arg { number } channel
|
|
75
|
+
* @arg { Buffer } payload
|
|
76
|
+
*/
|
|
77
|
+
module.exports.makeBodyFrame = function (channel, payload) {
|
|
78
|
+
const frameSize = FRAME_HEADER_BYTES + payload.length + FRAME_END_BYTES
|
|
79
|
+
|
|
80
|
+
const frame = Buffer.alloc(frameSize)
|
|
81
|
+
|
|
82
|
+
let offset = 0
|
|
83
|
+
|
|
84
|
+
offset = frame.writeUInt8(FRAME_BODY, offset)
|
|
85
|
+
offset = frame.writeUInt16BE(channel, offset)
|
|
86
|
+
offset = frame.writeInt32BE(payload.length, offset)
|
|
87
|
+
|
|
88
|
+
payload.copy(frame, offset)
|
|
89
|
+
offset += payload.length
|
|
90
|
+
|
|
91
|
+
frame.writeUInt8(FRAME_END, offset)
|
|
92
|
+
|
|
93
|
+
return frame
|
|
45
94
|
};
|
|
46
95
|
|
|
47
|
-
|
|
48
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Parse an AMQP frame
|
|
98
|
+
* @arg { Buffer } bin
|
|
99
|
+
* @arg { number } max
|
|
100
|
+
* @returns { FrameStructure | boolean }
|
|
101
|
+
*/
|
|
102
|
+
function parseFrame(bin) {
|
|
103
|
+
if (bin.length < FRAME_HEADER_BYTES) {
|
|
104
|
+
return false
|
|
105
|
+
}
|
|
49
106
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (rest[size] !== FRAME_END)
|
|
59
|
-
throw new Error('Invalid frame');
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
type: fh.type,
|
|
63
|
-
channel: fh.channel,
|
|
64
|
-
size: size,
|
|
65
|
-
payload: rest.slice(0, size),
|
|
66
|
-
rest: rest.slice(size + 1)
|
|
67
|
-
};
|
|
68
|
-
}
|
|
107
|
+
const type = bin.readUInt8(0)
|
|
108
|
+
const channel = bin.readUInt16BE(1)
|
|
109
|
+
const size = bin.readUInt32BE(3)
|
|
110
|
+
|
|
111
|
+
const totalSize = FRAME_HEADER_BYTES + size + FRAME_END_BYTES
|
|
112
|
+
|
|
113
|
+
if (bin.length < totalSize) {
|
|
114
|
+
return false
|
|
69
115
|
}
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
116
|
|
|
73
|
-
|
|
117
|
+
const frameEnd = bin.readUInt8(FRAME_HEADER_BYTES + size)
|
|
118
|
+
|
|
119
|
+
if (frameEnd !== FRAME_END) {
|
|
120
|
+
throw new Error('Invalid frame')
|
|
121
|
+
}
|
|
74
122
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
123
|
+
return {
|
|
124
|
+
type,
|
|
125
|
+
channel,
|
|
126
|
+
size,
|
|
127
|
+
payload: bin.subarray(FRAME_HEADER_BYTES, FRAME_HEADER_BYTES + size),
|
|
128
|
+
rest: bin.subarray(totalSize)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
79
131
|
|
|
80
|
-
|
|
132
|
+
module.exports.parseFrame = parseFrame;
|
|
81
133
|
|
|
82
134
|
var HEARTBEAT = {channel: 0};
|
|
83
135
|
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Decode AMQP frame into JS object
|
|
138
|
+
* @param { FrameStructure } frame
|
|
139
|
+
* @returns
|
|
140
|
+
*/
|
|
141
|
+
module.exports.decodeFrame = (frame) => {
|
|
142
|
+
const payload = frame.payload
|
|
143
|
+
const channel = frame.channel
|
|
144
|
+
|
|
86
145
|
switch (frame.type) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
146
|
+
case FRAME_METHOD: {
|
|
147
|
+
const id = payload.readUInt32BE(0)
|
|
148
|
+
const args = payload.subarray(4)
|
|
149
|
+
const fields = decode(id, args)
|
|
150
|
+
return { id, channel, fields }
|
|
151
|
+
}
|
|
152
|
+
case FRAME_HEADER: {
|
|
153
|
+
const id = payload.readUInt16BE(0)
|
|
154
|
+
// const weight = payload.readUInt16BE(2)
|
|
155
|
+
const size = readInt64BE(payload, 4)
|
|
156
|
+
const flagsAndfields = payload.subarray(12)
|
|
157
|
+
const fields = decode(id, flagsAndfields)
|
|
158
|
+
return { id, channel, size, fields }
|
|
159
|
+
}
|
|
160
|
+
case FRAME_BODY:
|
|
161
|
+
return { channel, content: payload }
|
|
162
|
+
case FRAME_HEARTBEAT:
|
|
163
|
+
return HEARTBEAT
|
|
164
|
+
default:
|
|
165
|
+
throw new Error('Unknown frame type ' + frame.type)
|
|
104
166
|
}
|
|
105
167
|
}
|
|
106
168
|
|
|
@@ -110,4 +172,4 @@ module.exports.HEARTBEAT_BUF = Buffer.from([constants.FRAME_HEARTBEAT,
|
|
|
110
172
|
0, 0, // channel = 0
|
|
111
173
|
constants.FRAME_END]);
|
|
112
174
|
|
|
113
|
-
module.exports.HEARTBEAT = HEARTBEAT;
|
|
175
|
+
module.exports.HEARTBEAT = HEARTBEAT;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "amqplib",
|
|
3
3
|
"homepage": "http://amqp-node.github.io/amqplib/",
|
|
4
4
|
"main": "./channel_api.js",
|
|
5
|
-
"version": "0.10.
|
|
5
|
+
"version": "0.10.8",
|
|
6
6
|
"description": "An AMQP 0-9-1 (e.g., RabbitMQ) library and client.",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
"node": ">=10"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@acuminous/bitsyntax": "^0.1.2",
|
|
16
15
|
"buffer-more-ints": "~1.0.0",
|
|
17
16
|
"url-parse": "~1.5.10"
|
|
18
17
|
},
|
package/test/frame.js
CHANGED
|
@@ -69,12 +69,6 @@ suite("Explicit parsing", function() {
|
|
|
69
69
|
0,0,0,0, // garbage ID
|
|
70
70
|
defs.constants.FRAME_END]);
|
|
71
71
|
|
|
72
|
-
testBogusFrame('> max frame',
|
|
73
|
-
[defs.constants.FRAME_BODY,
|
|
74
|
-
0,0, 0,0,0,6, // too big!
|
|
75
|
-
65,66,67,68,69,70,
|
|
76
|
-
defs.constants.FRAME_END]);
|
|
77
|
-
|
|
78
72
|
});
|
|
79
73
|
|
|
80
74
|
// Now for a bit more fun.
|