Skip to content

Commit e17125a

Browse files
committed
Initial work. some dirty work and dangling comments
1 parent e07c1d5 commit e17125a

File tree

8 files changed

+208
-11
lines changed

8 files changed

+208
-11
lines changed

packages/bolt-connection/src/bolt/handshake.js

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,58 @@ function parseNegotiatedResponse (buffer, log) {
7070
return Number(h[3] + '.' + h[2])
7171
}
7272

73+
function newNegotiation (channel, buffer, log) {
74+
const numVersions = buffer.readVarInt()
75+
let versions = []
76+
for (let i = 0; i < numVersions; i++) {
77+
const h = [
78+
buffer.readUInt8(),
79+
buffer.readUInt8(),
80+
buffer.readUInt8(),
81+
buffer.readUInt8()
82+
]
83+
versions = versions.concat([h])
84+
}
85+
buffer.readVarInt()
86+
// parse supported capabilities
87+
// select preferrable protocol and respond
88+
const major = versions[0][3]
89+
const minor = versions[0][2]
90+
91+
return new Promise((resolve, reject) => {
92+
try {
93+
const selectionBuffer = alloc(5)
94+
selectionBuffer.writeInt32((minor << 8) | major)
95+
// select capabilities and respond
96+
const capabilites = 0
97+
selectionBuffer.writeVarInt(capabilites)
98+
channel.write(selectionBuffer).then(() => {
99+
resolve({
100+
protocolVersion: Number(major + '.' + minor),
101+
capabilites: 0,
102+
consumeRemainingBuffer: consumer => {
103+
if (buffer.hasRemaining()) {
104+
consumer(buffer.readSlice(buffer.remaining()))
105+
}
106+
}
107+
})
108+
})
109+
} catch (e) {
110+
reject(e)
111+
}
112+
})
113+
}
114+
73115
/**
74116
* @return {BaseBuffer}
75117
* @private
76118
*/
77119
function newHandshakeBuffer () {
78120
return createHandshakeMessage([
79-
[version(5, 7), version(5, 0)],
80-
[version(4, 4), version(4, 2)],
81-
version(4, 1),
82-
version(3, 0)
121+
version(255, 1),
122+
version(5, 7),
123+
[version(5, 5), version(5, 0)],
124+
[version(4, 4), version(4, 1)]
83125
])
84126
}
85127

@@ -91,8 +133,10 @@ function newHandshakeBuffer () {
91133
/**
92134
* @typedef HandshakeResult
93135
* @property {number} protocolVersion The protocol version negotiated in the handshake
136+
* @property {number} capabilites A bitmask representing the capabilities negotiated in the handshake
94137
* @property {function(BufferConsumerCallback)} consumeRemainingBuffer A function to consume the remaining buffer if it exists
95138
*/
139+
96140
/**
97141
* Shake hands using the channel and return the protocol version
98142
*
@@ -101,6 +145,23 @@ function newHandshakeBuffer () {
101145
* @returns {Promise<HandshakeResult>} Promise of protocol version and consumeRemainingBuffer
102146
*/
103147
export default function handshake (channel, log) {
148+
return initialHandshake(channel, log).then((result) => {
149+
if (result.protocolVersion === 255.1) {
150+
return newNegotiation(channel, result.buffer, log)
151+
} else {
152+
return result
153+
}
154+
})
155+
}
156+
157+
/**
158+
* Shake hands using the channel and return the protocol version, or the improved handshake protocol if communicating with a newer server.
159+
*
160+
* @param {Channel} channel the channel use to shake hands
161+
* @param {Logger} log the log object
162+
* @returns {Promise<HandshakeResult>} Promise of protocol version and consumeRemainingBuffer
163+
*/
164+
function initialHandshake (channel, log) {
104165
return new Promise((resolve, reject) => {
105166
const handshakeErrorHandler = error => {
106167
reject(error)
@@ -115,9 +176,10 @@ export default function handshake (channel, log) {
115176
try {
116177
// read the response buffer and initialize the protocol
117178
const protocolVersion = parseNegotiatedResponse(buffer, log)
118-
119179
resolve({
120180
protocolVersion,
181+
capabilites: 0,
182+
buffer,
121183
consumeRemainingBuffer: consumer => {
122184
if (buffer.hasRemaining()) {
123185
consumer(buffer.readSlice(buffer.remaining()))

packages/bolt-connection/src/buf/base-buf.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ export default class BaseBuffer {
4747
throw new Error('Not implemented')
4848
}
4949

50+
getVarInt (position) {
51+
throw new Error('Not implemented')
52+
}
53+
5054
putUInt8 (position, val) {
5155
throw new Error('Not implemented')
5256
}
@@ -244,6 +248,15 @@ export default class BaseBuffer {
244248
return this.getFloat64(this._updatePos(8))
245249
}
246250

251+
/**
252+
* Read from state position
253+
*/
254+
readVarInt () {
255+
const int = this.getVarInt(this.position)
256+
this._updatePos(int.length)
257+
return int.value
258+
}
259+
247260
/**
248261
* Write to state position.
249262
* @param val
@@ -300,6 +313,17 @@ export default class BaseBuffer {
300313
this.putFloat64(this._updatePos(8), val)
301314
}
302315

316+
writeVarInt (val) {
317+
while (val > 1) {
318+
let int = val % 128
319+
if (val >= 128) {
320+
int += 128
321+
}
322+
val = val / 128
323+
this.putInt8(this._updatePos(1), int)
324+
}
325+
}
326+
303327
/**
304328
* Write to state position.
305329
* @param val

packages/bolt-connection/src/channel/channel-buf.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ export default class ChannelBuffer extends BaseBuffer {
3737
return this._buffer.readDoubleBE(position)
3838
}
3939

40+
getVarInt (position) {
41+
let i = 0
42+
let currentValue = this._buffer.readInt8(position + i)
43+
let total = currentValue % 128
44+
while (currentValue / 128 >= 1) {
45+
i += 1
46+
currentValue = this._buffer.readInt8(position + i)
47+
total += currentValue % 128
48+
}
49+
return { length: i + 1, value: total }
50+
}
51+
4052
putUInt8 (position, val) {
4153
this._buffer.writeUInt8(val, position)
4254
}

packages/neo4j-driver-deno/lib/bolt-connection/bolt/handshake.js

Lines changed: 67 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/neo4j-driver-deno/lib/bolt-connection/buf/base-buf.js

Lines changed: 24 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/neo4j-driver-deno/lib/bolt-connection/channel/channel-buf.js

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/testkit-backend/src/feature/common.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ const features = [
2727
'Feature:Bolt:5.5',
2828
'Feature:Bolt:5.6',
2929
'Feature:Bolt:5.7',
30+
'Feature:Bolt:HandshakeManifestV1',
3031
'Feature:Bolt:Patch:UTC',
3132
'Feature:API:ConnectionAcquisitionTimeout',
3233
'Feature:API:Driver.ExecuteQuery',

testkit/testkit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"testkit": {
33
"uri": "https://github.com/neo4j-drivers/testkit.git",
4-
"ref": "5.0"
4+
"ref": "bolt-handshake-v2"
55
}
66
}

0 commit comments

Comments
 (0)