From ebde1df00c27cc7df49e260af05982a62fd67457 Mon Sep 17 00:00:00 2001 From: Mark Cavage Date: Thu, 8 Dec 2011 14:54:40 -0800 Subject: [PATCH] Minor refactoring of PersistentSearchControl commit --- lib/controls/control.js | 25 ++- lib/controls/index.js | 54 ++++--- lib/controls/persistent_search_control.js | 146 ++++++++---------- lib/messages/message.js | 9 +- package.json | 2 +- .../persistent_search_control.test.js | 25 +-- 6 files changed, 132 insertions(+), 129 deletions(-) diff --git a/lib/controls/control.js b/lib/controls/control.js index 808c967..0ea2d05 100644 --- a/lib/controls/control.js +++ b/lib/controls/control.js @@ -7,9 +7,14 @@ var asn1 = require('asn1'); var Protocol = require('../protocol'); + + ///--- Globals + var Ber = asn1.Ber; + + ///--- API function Control(options) { @@ -28,7 +33,7 @@ function Control(options) { } this.type = options.type || ''; - this.criticality = options.criticality || false; + this.criticality = options.critical || options.criticality || false; this.value = options.value || undefined; var self = this; @@ -42,9 +47,6 @@ function Control(options) { } module.exports = Control; -Control.prototype.toString = function() { - return this.json; -}; Control.prototype.toBer = function(ber) { assert.ok(ber); @@ -52,7 +54,18 @@ Control.prototype.toBer = function(ber) { ber.startSequence(); ber.writeString(this.type || ''); ber.writeBoolean(this.criticality); - if (this.value) - ber.writeString(this.value); + if (typeof(this._toBer) === 'function') { + this._toBer(ber); + } else { + if (this.value) + ber.writeString(this.value); + } + ber.endSequence(); + return; +}; + + +Control.prototype.toString = function() { + return this.json; }; diff --git a/lib/controls/index.js b/lib/controls/index.js index 9c7d42c..41d0507 100644 --- a/lib/controls/index.js +++ b/lib/controls/index.js @@ -1,38 +1,56 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + var assert = require('assert'); var Control = require('./control'); var PersistentSearchControl = require('./persistent_search_control'); -var OID_PERSISTENT_SEARCH_CONTROL = '2.16.840.1.113730.3.4.3'; + ///--- API module.exports = { - getControl: function(ber) { + + getControl: function getControl(ber) { assert.ok(ber); if (ber.readSequence() === null) - return; + return null; + + var type; + var critical = false; + var value; - var end = ber.offset + ber.length; - var options = {}; if (ber.length) { - options.type = ber.readString(); + var end = ber.offset + ber.length; + + type = ber.readString(); if (ber.offset < end) { - if (ber.peek() === 0x01) // Boolean, optional - options.criticality = ber.readBoolean(); - } - if (ber.offset < end) { - if (options.type == OID_PERSISTENT_SEARCH_CONTROL) { - // send the buffer directly to the PSC - options.value = ber.readString(0x04, true); - return new PersistentSearchControl(options); - } else { - options.value = ber.readString(); - return new Control(options); - } + if (ber.peek() === 0x01) + critical = ber.readBoolean(); } + + if (ber.offset < end) + value = ber.readString(0x04, true); } + + var control; + switch (type) { + case PersistentSearchControl.OID: + control = new PersistentSearchControl({ + critical: critical, + value: value + }); + break; + default: + control = new Control({ + type: type, + critical: critical, + value: value.toString('utf8') + }); + } + + return control; }, Control: Control, diff --git a/lib/controls/persistent_search_control.js b/lib/controls/persistent_search_control.js index a2cf43e..e0da5cc 100644 --- a/lib/controls/persistent_search_control.js +++ b/lib/controls/persistent_search_control.js @@ -1,109 +1,87 @@ +// Copyright 2011 Mark Cavage, Inc. All rights reserved. + var assert = require('assert'); -var asn1 = require('asn1'); -var buffer = require('buffer'); -var Control = require('./control'); var util = require('util'); +var asn1 = require('asn1'); + +var Control = require('./control'); + + + +///--- Globals + +var BerReader = asn1.BerReader; +var BerWriter = asn1.BerWriter; + + + +///--- API + function PersistentSearchControl(options) { - if (options) { - if (typeof(options) !== 'object') - throw new TypeError('options must be an object'); - if (options.type && typeof(options.type) !== 'string') - throw new TypeError('options.type must be a string'); - if (options.criticality !== undefined && - typeof(options.criticality) !== 'boolean') - throw new TypeError('options.criticality must be a boolean'); - if (options.value && !Buffer.isBuffer(options.value)) - throw new TypeError('options.value must be a buffer'); - } else { + if (!options) options = {}; - } - - this.type = options.type || '2.16.840.1.113730.3.4.3'; - this.criticality = options.criticality || false; + options.type = PersistentSearchControl.OID; if (options.value) { - // parse out this.value into the PSC object - var ber = new asn1.BerReader(options.value); - if (ber.readSequence()) { - this.value = { - changeTypes: ber.readInt(), - changesOnly: ber.readBoolean(), - returnECs: ber.readBoolean() - }; + if (Buffer.isBuffer(options.value)) { + this.parse(options.value); + } else if (typeof(options.value) === 'object') { + this._value = options.value; + } else { + throw new TypeError('options.value must be a Buffer or Object'); } + options.value = null; } + Control.call(this, options); var self = this; + this.__defineGetter__('value', function() { + return self._value || {}; + }); this.__defineGetter__('json', function() { - return { - controlType: self.type, - criticality: self.criticality, - controlValue: self.value - }; + var json = Control.prototype.json.call(self); + json.controlValue = self.value; + return json; }); } +util.inherits(PersistentSearchControl, Control); module.exports = PersistentSearchControl; -// returns a psc given a fully populated psc object -PersistentSearchControl.prototype.get = function(options) { - if (options) { - if (typeof(options) !== 'object') - throw new TypeError('options must be an object'); - if (options.type && typeof(options.type) !== 'string') - throw new TypeError('options.type must be a string'); - if (options.criticality !== undefined && - typeof(options.criticality) !== 'boolean') - throw new TypeError('options.criticality must be a boolean'); - if (options.value && typeof(options.value) !== 'object') { - throw new TypeError('options.value must be an object'); - } else { - if (options.value.changeTypes && - typeof(options.value.changeTypes) !== 'number') - throw new TypeError('options.value.changeTypes must be a number'); - if (options.value.changesOnly !== undefined && - typeof(options.value.changesOnly) !== 'boolean') - throw new TypeError('options.value.changesOnly must be a boolean'); - if (options.value.returnECs !== undefined && - typeof(options.value.returnECs) !== 'boolean') - throw new TypeError('options.value.returnECs must be a boolean'); - } - } else { - options = {}; + +PersistentSearchControl.prototype.parse = function parse(buffer) { + assert.ok(buffer); + + var ber = new BerReader(buffer); + if (ber.readSequence()) { + this._value = { + changeTypes: ber.readInt(), + changesOnly: ber.readBoolean(), + returnECs: ber.readBoolean() + }; + + return true; } - this.type = options.type || ''; - this.criticality = options.criticality || false; - this.value = options.value || undefined; - - var self = this; - this.__defineGetter__('json', function() { - return { - controlType: self.type, - criticality: self.criticality, - controlValue: self.value - }; - }); + return false; }; -PersistentSearchControl.prototype.toBer = function(ber) { + +PersistentSearchControl.prototype._toBer = function(ber) { assert.ok(ber); - ber.startSequence(); - ber.writeString(this.type); - ber.writeBoolean(this.criticality); + if (!this._value) + return; - var pscWriter = new asn1.BerWriter(); + var writer = new BerWriter(); + writer.startSequence(); + writer.writeInt(this.value.changeTypes); + writer.writeBoolean(this.value.changesOnly); + writer.writeBoolean(this.value.returnECs); + writer.endSequence(); - // write the value subsequence - pscWriter.startSequence(); - pscWriter.writeInt(this.value.changeTypes); - pscWriter.writeBoolean(this.value.changesOnly); - pscWriter.writeBoolean(this.value.returnECs); - pscWriter.endSequence(); - - // write the pscValue as a octetstring to the ber - ber.writeBuffer(pscWriter.buffer, 0x04); - - ber.endSequence(); + ber.writeBuffer(writer.buffer, 0x04); }; + + +PersistentSearchControl.OID = '2.16.840.1.113730.3.4.3'; diff --git a/lib/messages/message.js b/lib/messages/message.js index 031904b..5ddaab7 100644 --- a/lib/messages/message.js +++ b/lib/messages/message.js @@ -5,17 +5,21 @@ var util = require('util'); var asn1 = require('asn1'); -var Control = require('../controls/index').Control; +var Control = require('../controls').Control; var Protocol = require('../protocol'); var logStub = require('../log_stub'); + + ///--- Globals var Ber = asn1.Ber; var BerReader = asn1.BerReader; var BerWriter = asn1.BerWriter; -var getControl = require('../controls/index').getControl; +var getControl = require('../controls').getControl; + + ///--- API @@ -76,7 +80,6 @@ LDAPMessage.prototype.parse = function(ber) { ber.readSequence(); var end = ber.offset + ber.length; while (ber.offset < end) { - var c = getControl(ber); if (c) this.controls.push(c); diff --git a/package.json b/package.json index 2930b6c..7758fa1 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "node": ">=0.4" }, "dependencies": { - "asn1": "0.1.8", + "asn1": "0.1.10", "buffertools": "1.0.5", "dtrace-provider": "0.0.3", "nopt": "1.0.10", diff --git a/tst/controls/persistent_search_control.test.js b/tst/controls/persistent_search_control.test.js index 6341e54..278e823 100644 --- a/tst/controls/persistent_search_control.test.js +++ b/tst/controls/persistent_search_control.test.js @@ -3,24 +3,21 @@ var test = require('tap').test; var asn1 = require('asn1'); -var log4js = require('log4js'); -var sys = require('sys'); var BerReader = asn1.BerReader; var BerWriter = asn1.BerWriter; var getControl; var PersistentSearchControl; -///--- Globals -var LOG = log4js.getLogger('persistent_search_control.test'); + ///--- Tests test('load library', function(t) { PersistentSearchControl = - require('../../lib/controls/index').PersistentSearchControl; + require('../../lib/controls').PersistentSearchControl; t.ok(PersistentSearchControl); - getControl = require('../../lib/controls/index').getControl; + getControl = require('../../lib/controls').getControl; t.ok(getControl); t.end(); }); @@ -33,7 +30,7 @@ test('new no args', function(t) { test('new with args', function(t) { - var options = { + var c = new PersistentSearchControl({ type: '2.16.840.1.113730.3.4.3', criticality: true, value: { @@ -41,10 +38,7 @@ test('new with args', function(t) { changesOnly: false, returnECs: false } - }; - - var c = new PersistentSearchControl(); - c.get(options); + }); t.ok(c); t.equal(c.type, '2.16.840.1.113730.3.4.3'); t.ok(c.criticality); @@ -87,7 +81,6 @@ test('getControl with args', function(t) { var ber = new BerReader(buf); var psc = getControl(ber); - LOG.info(psc.value); t.ok(psc); t.equal(psc.type, '2.16.840.1.113730.3.4.3'); t.equal(psc.criticality, false); @@ -98,8 +91,7 @@ test('getControl with args', function(t) { }); test('tober', function(t) { - var ber = new BerWriter(); - var options = { + var psc = new PersistentSearchControl({ type: '2.16.840.1.113730.3.4.3', criticality: true, value: { @@ -107,10 +99,9 @@ test('tober', function(t) { changesOnly: false, returnECs: false } - }; + }); - var psc = new PersistentSearchControl(); - psc.get(options); + var ber = new BerWriter(); psc.toBer(ber); var c = getControl(new BerReader(ber.buffer));