Skip to content

Commit a22a9da

Browse files
committed
Added doc and test case for connection.headers
1 parent 95d9cf8 commit a22a9da

4 files changed

Lines changed: 49 additions & 39 deletions

File tree

Connection.js

Lines changed: 36 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ function Connection(socket, parentOrUrl, callback) {
4545
this.frameBuffer = null // string for text frames and InStream for binary frames
4646
this.outStream = null // current allocated OutStream object for sending binary frames
4747
this.key = null // the Sec-WebSocket-Key header
48+
this.headers = {} // read only map of header names and values. Header names are lower-cased
4849

4950
// Set listeners
5051
socket.on('readable', function () {
@@ -244,14 +245,31 @@ Connection.prototype.startHandshake = function () {
244245
this.socket.write(str)
245246
}
246247

248+
/**
249+
* Read headers from HTTP protocol
250+
* Update the Connection#headers property
251+
* @param {string[]} lines one for each '\r\n'-separated HTTP request line
252+
*/
253+
Connection.prototype.readHeaders = function (lines) {
254+
var i, match
255+
256+
// Extract all headers
257+
// Ignore bad-formed lines and ignore the first line (HTTP header)
258+
for (i = 1; i < lines.length; i++) {
259+
if ((match = lines[i].match(/^([a-z-]+): (.+)$/i))) {
260+
this.headers[match[1].toLowerCase()] = match[2]
261+
}
262+
}
263+
}
264+
247265
/**
248266
* Process and check a handshake answered by a server
249267
* @param {string[]} lines one for each '\r\n'-separated HTTP request line
250268
* @returns {boolean} if the handshake was sucessful. If not, the connection must be closed
251269
* @private
252270
*/
253271
Connection.prototype.checkHandshake = function (lines) {
254-
var headers, i, temp, key, sha1
272+
var key, sha1
255273

256274
// First line
257275
if (lines.length < 4) {
@@ -262,30 +280,20 @@ Connection.prototype.checkHandshake = function (lines) {
262280
}
263281

264282
// Extract all headers
265-
headers = {}
266-
for (i = 1; i < lines.length; i++) {
267-
if (!lines[i].trim()) {
268-
continue
269-
}
270-
temp = lines[i].match(/^([a-z-]+): (.+)$/i)
271-
if (!temp) {
272-
return false
273-
}
274-
headers[temp[1].toLowerCase()] = temp[2]
275-
}
283+
this.readHeaders(lines)
276284

277285
// Validate necessary headers
278-
if (!('upgrade' in headers) ||
279-
!('sec-websocket-accept' in headers) ||
280-
!('connection' in headers)) {
286+
if (!('upgrade' in this.headers) ||
287+
!('sec-websocket-accept' in this.headers) ||
288+
!('connection' in this.headers)) {
281289
return false
282290
}
283-
if (headers.upgrade.toLowerCase() !== 'websocket' ||
284-
headers.connection.toLowerCase().split(', ').indexOf('upgrade') === -1) {
291+
if (this.headers.upgrade.toLowerCase() !== 'websocket' ||
292+
this.headers.connection.toLowerCase().split(', ').indexOf('upgrade') === -1) {
285293
return false
286294
}
287-
key = headers['sec-websocket-accept']
288-
this.headers = headers
295+
key = this.headers['sec-websocket-accept']
296+
289297
// Check the key
290298
sha1 = crypto.createHash('sha1')
291299
sha1.end(this.key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
@@ -302,7 +310,7 @@ Connection.prototype.checkHandshake = function (lines) {
302310
* @private
303311
*/
304312
Connection.prototype.answerHandshake = function (lines) {
305-
var path, headers, i, temp, key, sha1
313+
var path, key, sha1
306314

307315
// First line
308316
if (lines.length < 6) {
@@ -315,32 +323,22 @@ Connection.prototype.answerHandshake = function (lines) {
315323
this.path = path[1]
316324

317325
// Extract all headers
318-
headers = {}
319-
for (i = 1; i < lines.length; i++) {
320-
if (!lines[i].trim()) {
321-
continue
322-
}
323-
temp = lines[i].match(/^([a-z-]+): (.+)$/i)
324-
if (!temp) {
325-
return false
326-
}
327-
headers[temp[1].toLowerCase()] = temp[2]
328-
}
326+
this.readHeaders(lines)
329327

330328
// Validate necessary headers
331-
if (!('host' in headers) || !('sec-websocket-key' in headers)) {
329+
if (!('host' in this.headers) || !('sec-websocket-key' in this.headers)) {
332330
return false
333331
}
334-
if (headers.upgrade.toLowerCase() !== 'websocket' ||
335-
headers.connection.toLowerCase().split(', ').indexOf('upgrade') === -1) {
332+
if (this.headers.upgrade.toLowerCase() !== 'websocket' ||
333+
this.headers.connection.toLowerCase().split(', ').indexOf('upgrade') === -1) {
336334
return false
337335
}
338-
if (headers['sec-websocket-version'] !== '13') {
336+
if (this.headers['sec-websocket-version'] !== '13') {
339337
return false
340338
}
341339

342-
this.key = headers['sec-websocket-key']
343-
this.headers = headers
340+
this.key = this.headers['sec-websocket-key']
341+
344342
// Build and send the response
345343
sha1 = crypto.createHash('sha1')
346344
sha1.end(this.key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
@@ -521,4 +519,4 @@ Connection.prototype.processCloseFrame = function (payload) {
521519
this.socket.write(frame.createCloseFrame(code, reason, !this.server))
522520
this.readyState = this.CLOSED
523521
this.emit('close', code, reason)
524-
}
522+
}

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,9 @@ Stores the OutStream object returned by connection.beginBinary(). null if there
132132
## connection.path
133133
For a connection accepted by a server, it is a string representing the path to which the connection was made (example: "/chat"). null otherwise
134134

135+
## connection.headers
136+
Read only map of header names and values. Header names are lower-cased
137+
135138
## Event: 'close(code, reason)'
136139
Emitted when the connection is closed by any side
137140

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "nodejs-websocket",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"author": "Sitegui <sitegui@sitegui.com.br>",
55
"description": "Basic server&client approach to websocket (text and binary frames)",
66
"main": "./index.js",

test/test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,15 @@ describe('text frames', function () {
104104
// The server do nothing in this case
105105
getServer()
106106
})
107+
108+
it('should expose the headers', function () {
109+
var client = getClient()
110+
111+
// Send a string and wait
112+
client.headers.should.have.property('upgrade', 'websocket')
113+
client.headers.should.have.property('connection', 'Upgrade')
114+
client.headers.should.have.property('sec-websocket-accept')
115+
})
107116
})
108117

109118
function getClient() {

0 commit comments

Comments
 (0)