Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,22 @@ exports.compileTrust = function(val) {

if (typeof val === 'string') {
// Support comma-separated values
// use lazy compilation for large IP lists
// to avoid blocking the event loop during app initialization
val = val.split(',')
.map(function (v) { return v.trim() })

// For large lists (>1000 IPs), use lazy compilation
if (val.length > 1000) {
let compiledFn = null;
return function(address, i) {
// compile on first access to avoid startup delay
if (!compiledFn) {
compiledFn = proxyaddr.compile(val);
}
return compiledFn(address, i);
};
}
}

return proxyaddr.compile(val || []);
Expand Down
106 changes: 106 additions & 0 deletions test/utils.compileTrust.perf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
'use strict'

const utils = require('../lib/utils')

describe('utils.compileTrust', function () {
describe('performance', function () {
it('should use lazy compilation for large IP lists', function (done) {
// Test with large IP list (10,000 IPs)
const largeIpList = Array(10000).fill('127.0.0.1').join(',')

// Measure compileTrust time (should be fast with lazy compilation)
const start = Date.now()
const trustFn = utils.compileTrust(largeIpList)
const compileTime = Date.now() - start

// CompileTrust should be fast (< 10ms) with lazy compilation
if (compileTime > 10) {
return done(new Error(`compileTrust took ${compileTime}ms, expected < 10ms with lazy compilation`))
}

// First call should trigger compilation (will be slower)
const firstCallStart = Date.now()
const result1 = trustFn('127.0.0.1', 0)
const firstCallTime = Date.now() - firstCallStart

// Subsequent calls should be fast (cached)
const secondCallStart = Date.now()
const result2 = trustFn('192.168.1.1', 0)
const secondCallTime = Date.now() - secondCallStart

// Verify results
if (result1 !== true) {
return done(new Error('Expected first call to return true'))
}
if (result2 !== false) {
return done(new Error('Expected second call to return false'))
}

// Second call should be much faster than first
if (secondCallTime >= firstCallTime) {
return done(new Error(`Second call (${secondCallTime}ms) should be faster than first call (${firstCallTime}ms)`))
}

console.log(`Performance test results:`)
console.log(` compileTrust: ${compileTime}ms (lazy)`)
console.log(` First call: ${firstCallTime}ms (compilation)`)
console.log(` Second call: ${secondCallTime}ms (cached)`)

done()
})

it('should work correctly with small IP lists', function (done) {
// Test with small IP list (should use immediate compilation)
const smallIpList = '127.0.0.1,192.168.1.1,10.0.0.1'

const trustFn = utils.compileTrust(smallIpList)

// Test various IPs
if (trustFn('127.0.0.1', 0) !== true) {
return done(new Error('Expected 127.0.0.1 to be trusted'))
}
if (trustFn('192.168.1.1', 0) !== true) {
return done(new Error('Expected 192.168.1.1 to be trusted'))
}
if (trustFn('8.8.8.8', 0) !== false) {
return done(new Error('Expected 8.8.8.8 to not be trusted'))
}

done()
})

it('should maintain backward compatibility', function (done) {
// Test all existing functionality still works

// Boolean true
const trueFn = utils.compileTrust(true)
if (trueFn() !== true) {
return done(new Error('Boolean true should return true'))
}

// Number (hop count)
const hopFn = utils.compileTrust(2)
if (hopFn('127.0.0.1', 0) !== true) {
return done(new Error('Hop count 0 should be trusted'))
}
if (hopFn('127.0.0.1', 2) !== false) {
return done(new Error('Hop count 2 should not be trusted'))
}

// Function
const customFn = function() { return 'custom' }
const returnedFn = utils.compileTrust(customFn)
if (returnedFn !== customFn) {
return done(new Error('Custom function should be returned as-is'))
}

// Array
const arrayFn = utils.compileTrust(['127.0.0.1', '192.168.1.1'])
if (arrayFn('127.0.0.1', 0) !== true) {
return done(new Error('Array IP should be trusted'))
}

done()
})
})
})