use poolee as the http client instead of request

This commit is contained in:
Danny Coates 2014-06-03 17:01:31 -07:00
Родитель 718d5a52f5
Коммит 80e91b922d
6 изменённых файлов: 323 добавлений и 366 удалений

Просмотреть файл

@ -3,28 +3,28 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var P = require('./promise')
var request = require('./requestp')
var Pool = require('./pool')
module.exports = function (log, error) {
function Customs(url) {
this.url = url
if (url === 'none') {
this.pool = { post: function () { return P({ block: false })}}
}
else {
this.pool = new Pool(url, { timeout: 1000 })
}
}
Customs.prototype.check = function (ip, agent, email, action) {
log.trace({ op: 'customs.check', email: email, action: action })
if (this.url === 'none') { return P() }
return request(
return this.pool.post(
'/check',
{
method: 'POST',
url: this.url + '/check',
json: {
ip: ip,
email: email,
action: action,
agent: agent
},
timeout: 1000
ip: ip,
email: email,
action: action,
agent: agent
}
)
.then(
@ -42,16 +42,11 @@
Customs.prototype.flag = function (ip, email) {
log.trace({ op: 'customs.flag', ip: ip, email: email })
if (this.url === 'none') { return P() }
return request(
return this.pool.post(
'/failedLoginAttempt',
{
method: 'POST',
url: this.url + '/failedLoginAttempt',
json: {
ip: ip,
email: email
},
timeout: 1000
ip: ip,
email: email
}
)
.then(

Просмотреть файл

@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var request = require('../requestp')
var Pool = require('../pool')
var butil = require('../crypto/butil')
var unbuffer = butil.unbuffer
@ -19,19 +19,13 @@ module.exports = function (
PasswordChangeToken) {
function DB(options) {
this.url = options.url
this.pool = new Pool(options.url)
}
DB.connect = function (options) {
var db = new DB(options)
return request(
{
method: 'GET',
url: db.url,
json: true
}
)
return db.pool.get('/')
.then(
function (api) {
// TODO: transition to api version
@ -48,11 +42,11 @@ module.exports = function (
}
DB.prototype.close = function () {
return P()
return P(this.pool.close())
}
DB.prototype.ping = function () {
return request(this.url + '/__heartbeat__')
return this.pool.get('/__heartbeat__')
}
// CREATE
@ -67,12 +61,9 @@ module.exports = function (
)
data.createdAt = data.verifierSetAt = Date.now()
data.normalizedEmail = data.email.toLowerCase()
return request(
{
method: 'PUT',
url: this.url + '/account/' + data.uid.toString('hex'),
json: unbuffer(data)
}
return this.pool.put(
'/account/' + data.uid.toString('hex'),
unbuffer(data)
)
.then(
function () {
@ -92,20 +83,17 @@ module.exports = function (
return SessionToken.create(authToken)
.then(
function (sessionToken) {
return request(
{
method: 'PUT',
url: this.url + '/sessionToken/' + sessionToken.id,
json: unbuffer(
{
tokenId: sessionToken.tokenId,
data: sessionToken.data,
uid: sessionToken.uid,
createdAt: sessionToken.createdAt
},
'inplace'
)
}
return this.pool.put(
'/sessionToken/' + sessionToken.id,
unbuffer(
{
tokenId: sessionToken.tokenId,
data: sessionToken.data,
uid: sessionToken.uid,
createdAt: sessionToken.createdAt
},
'inplace'
)
)
.then(
function () {
@ -121,21 +109,18 @@ module.exports = function (
return KeyFetchToken.create(authToken)
.then(
function (keyFetchToken) {
return request(
{
method: 'PUT',
url: this.url + '/keyFetchToken/' + keyFetchToken.id,
json: unbuffer(
{
tokenId: keyFetchToken.tokenId,
authKey: keyFetchToken.authKey,
uid: keyFetchToken.uid,
keyBundle: keyFetchToken.keyBundle,
createdAt: keyFetchToken.createdAt
},
'inplace'
)
}
return this.pool.put(
'/keyFetchToken/' + keyFetchToken.id,
unbuffer(
{
tokenId: keyFetchToken.tokenId,
authKey: keyFetchToken.authKey,
uid: keyFetchToken.uid,
keyBundle: keyFetchToken.keyBundle,
createdAt: keyFetchToken.createdAt
},
'inplace'
)
)
.then(
function () {
@ -151,20 +136,17 @@ module.exports = function (
return AccountResetToken.create(token)
.then(
function (accountResetToken) {
return request(
{
method: 'PUT',
url: this.url + '/accountResetToken/' + accountResetToken.id,
json: unbuffer(
{
tokenId: accountResetToken.tokenId,
data: accountResetToken.data,
uid: accountResetToken.uid,
createdAt: accountResetToken.createdAt
},
'inplace'
)
}
return this.pool.put(
'/accountResetToken/' + accountResetToken.id,
unbuffer(
{
tokenId: accountResetToken.tokenId,
data: accountResetToken.data,
uid: accountResetToken.uid,
createdAt: accountResetToken.createdAt
},
'inplace'
)
)
.then(
function () {
@ -180,22 +162,19 @@ module.exports = function (
return PasswordForgotToken.create(emailRecord)
.then(
function (passwordForgotToken) {
return request(
{
method: 'PUT',
url: this.url + '/passwordForgotToken/' + passwordForgotToken.id,
json: unbuffer(
{
tokenId: passwordForgotToken.tokenId,
data: passwordForgotToken.data,
uid: passwordForgotToken.uid,
passCode: passwordForgotToken.passCode,
createdAt: passwordForgotToken.createdAt,
tries: passwordForgotToken.tries
},
'inplace'
)
}
return this.pool.put(
'/passwordForgotToken/' + passwordForgotToken.id,
unbuffer(
{
tokenId: passwordForgotToken.tokenId,
data: passwordForgotToken.data,
uid: passwordForgotToken.uid,
passCode: passwordForgotToken.passCode,
createdAt: passwordForgotToken.createdAt,
tries: passwordForgotToken.tries
},
'inplace'
)
)
.then(
function () {
@ -211,20 +190,17 @@ module.exports = function (
return PasswordChangeToken.create(data)
.then(
function (passwordChangeToken) {
return request(
{
method: 'PUT',
url: this.url + '/passwordChangeToken/' + passwordChangeToken.id,
json: unbuffer(
{
tokenId: passwordChangeToken.tokenId,
data: passwordChangeToken.data,
uid: passwordChangeToken.uid,
createdAt: passwordChangeToken.createdAt
},
'inplace'
)
}
return this.pool.put(
'/passwordChangeToken/' + passwordChangeToken.id,
unbuffer(
{
tokenId: passwordChangeToken.tokenId,
data: passwordChangeToken.data,
uid: passwordChangeToken.uid,
createdAt: passwordChangeToken.createdAt
},
'inplace'
)
)
.then(
function () {
@ -239,211 +215,154 @@ module.exports = function (
DB.prototype.accountExists = function (email) {
log.trace({ op: 'DB.accountExists', email: email })
return request(
{
method: 'HEAD',
url: this.url + '/emailRecord/' + Buffer(email, 'utf8').toString('hex'),
json: true
}
)
.then(
function () {
return true
},
function (err) {
if (err.statusCode === 404) {
return false
return this.pool.head('/emailRecord/' + Buffer(email, 'utf8').toString('hex'))
.then(
function () {
return true
},
function (err) {
if (err.statusCode === 404) {
return false
}
throw err
}
throw err
}
)
)
}
DB.prototype.accountDevices = function (uid) {
log.trace({ op: 'DB.accountDevices', uid: uid })
return request(
{
method: 'GET',
url: this.url + '/account/' + uid.toString('hex') + '/devices',
json: true
}
)
return this.pool.get('/account/' + uid.toString('hex') + '/devices')
}
DB.prototype.sessionToken = function (id) {
log.trace({ op: 'DB.sessionToken', id: id })
return request(
{
method: 'GET',
url: this.url + '/sessionToken/' + id.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
return SessionToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
return this.pool.get('/sessionToken/' + id.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
return SessionToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
}
throw err
}
throw err
}
)
)
}
DB.prototype.keyFetchToken = function (id) {
log.trace({ op: 'DB.keyFetchToken', id: id })
return request(
{
method: 'GET',
url: this.url + '/keyFetchToken/' + id.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
return KeyFetchToken.fromId(id, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
return this.pool.get('/keyFetchToken/' + id.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
return KeyFetchToken.fromId(id, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
}
throw err
}
throw err
}
)
)
}
DB.prototype.accountResetToken = function (id) {
log.trace({ op: 'DB.accountResetToken', id: id })
return request(
{
method: 'GET',
url: this.url + '/accountResetToken/' + id.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
return AccountResetToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
return this.pool.get('/accountResetToken/' + id.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
return AccountResetToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
}
throw err
}
throw err
}
)
)
}
DB.prototype.passwordForgotToken = function (id) {
log.trace({ op: 'DB.passwordForgotToken', id: id })
return request(
{
method: 'GET',
url: this.url + '/passwordForgotToken/' + id.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
return PasswordForgotToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
return this.pool.get('/passwordForgotToken/' + id.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
return PasswordForgotToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
}
throw err
}
throw err
}
)
)
}
DB.prototype.passwordChangeToken = function (id) {
log.trace({ op: 'DB.passwordChangeToken', id: id })
return request(
{
method: 'GET',
url: this.url + '/passwordChangeToken/' + id.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
return PasswordChangeToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
return this.pool.get('/passwordChangeToken/' + id.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
return PasswordChangeToken.fromHex(data.tokenData, data)
},
function (err) {
if (err.statusCode === 404) {
err = error.invalidToken()
}
throw err
}
throw err
}
)
)
}
DB.prototype.emailRecord = function (email) {
log.trace({ op: 'DB.emailRecord', email: email })
return request(
{
method: 'GET',
url: this.url + '/emailRecord/' + Buffer(email, 'utf8').toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
data.emailVerified = !!data.emailVerified
return data
},
function (err) {
if (err.statusCode === 404) {
err = error.unknownAccount(email)
return this.pool.get('/emailRecord/' + Buffer(email, 'utf8').toString('hex'))
.then(
function (body) {
var data = bufferize(body)
data.emailVerified = !!data.emailVerified
return data
},
function (err) {
if (err.statusCode === 404) {
err = error.unknownAccount(email)
}
throw err
}
throw err
}
)
)
}
DB.prototype.account = function (uid) {
log.trace({ op: 'DB.account', uid: uid })
return request(
{
method: 'GET',
url: this.url + '/account/' + uid.toString('hex'),
json: true
}
)
.then(
function (body) {
var data = bufferize(body)
data.emailVerified = !!data.emailVerified
return data
},
function (err) {
if (err.statusCode === 404) {
err = error.unknownAccount()
return this.pool.get('/account/' + uid.toString('hex'))
.then(
function (body) {
var data = bufferize(body)
data.emailVerified = !!data.emailVerified
return data
},
function (err) {
if (err.statusCode === 404) {
err = error.unknownAccount()
}
throw err
}
throw err
}
)
)
}
// UPDATE
DB.prototype.updatePasswordForgotToken = function (token) {
log.trace({ op: 'DB.udatePasswordForgotToken', uid: token && token.uid })
return request(
return this.pool.post(
'/passwordForgotToken/' + token.id + '/update',
{
method: 'POST',
url: this.url + '/passwordForgotToken/' + token.id + '/update',
json: {
tries: token.tries
}
tries: token.tries
}
)
}
@ -452,13 +371,7 @@ module.exports = function (
DB.prototype.deleteAccount = function (authToken) {
log.trace({ op: 'DB.deleteAccount', uid: authToken && authToken.uid })
return request(
{
method: 'DELETE',
url: this.url + '/account/' + authToken.uid.toString('hex'),
json: true
}
)
return this.pool.del('/account/' + authToken.uid.toString('hex'))
}
DB.prototype.deleteSessionToken = function (sessionToken) {
@ -469,13 +382,7 @@ module.exports = function (
uid: sessionToken && sessionToken.uid
}
)
return request(
{
method: 'DELETE',
url: this.url + '/sessionToken/' + sessionToken.id,
json: true
}
)
return this.pool.del('/sessionToken/' + sessionToken.id)
}
DB.prototype.deleteKeyFetchToken = function (keyFetchToken) {
@ -486,13 +393,7 @@ module.exports = function (
uid: keyFetchToken && keyFetchToken.uid
}
)
return request(
{
method: 'DELETE',
url: this.url + '/keyFetchToken/' + keyFetchToken.id,
json: true
}
)
return this.pool.del('/keyFetchToken/' + keyFetchToken.id)
}
DB.prototype.deleteAccountResetToken = function (accountResetToken) {
@ -503,13 +404,7 @@ module.exports = function (
uid: accountResetToken && accountResetToken.uid
}
)
return request(
{
method: 'DELETE',
url: this.url + '/accountResetToken/' + accountResetToken.id,
json: true
}
)
return this.pool.del('/accountResetToken/' + accountResetToken.id)
}
DB.prototype.deletePasswordForgotToken = function (passwordForgotToken) {
@ -520,13 +415,7 @@ module.exports = function (
uid: passwordForgotToken && passwordForgotToken.uid
}
)
return request(
{
method: 'DELETE',
url: this.url + '/passwordForgotToken/' + passwordForgotToken.id,
json: true
}
)
return this.pool.del('/passwordForgotToken/' + passwordForgotToken.id)
}
DB.prototype.deletePasswordChangeToken = function (passwordChangeToken) {
@ -537,37 +426,22 @@ module.exports = function (
uid: passwordChangeToken && passwordChangeToken.uid
}
)
return request(
{
method: 'DELETE',
url: this.url + '/passwordChangeToken/' + passwordChangeToken.id,
json: true
}
)
return this.pool.del('/passwordChangeToken/' + passwordChangeToken.id)
}
// BATCH
DB.prototype.resetAccount = function (accountResetToken, data) {
log.trace({ op: 'DB.resetAccount', uid: accountResetToken && accountResetToken.uid })
return request(
{
method: 'POST',
url: this.url + '/account/' + accountResetToken.uid.toString('hex') + '/reset',
json: unbuffer(data)
}
return this.pool.post(
'/account/' + accountResetToken.uid.toString('hex') + '/reset',
unbuffer(data)
)
}
DB.prototype.verifyEmail = function (account) {
log.trace({ op: 'DB.verifyEmail', uid: account && account.uid })
return request(
{
method: 'POST',
url: this.url + '/account/' + account.uid.toString('hex') + '/verifyEmail',
json: true
}
)
return this.pool.post('/account/' + account.uid.toString('hex') + '/verifyEmail')
}
DB.prototype.forgotPasswordVerified = function (passwordForgotToken) {
@ -575,20 +449,17 @@ module.exports = function (
return AccountResetToken.create(passwordForgotToken)
.then(
function (accountResetToken) {
return request(
{
method: 'POST',
url: this.url + '/passwordForgotToken/' + passwordForgotToken.id + '/verified',
json: unbuffer(
{
tokenId: accountResetToken.tokenId,
data: accountResetToken.data,
uid: accountResetToken.uid,
createdAt: accountResetToken.createdAt
},
'inplace'
)
}
return this.pool.post(
'/passwordForgotToken/' + passwordForgotToken.id + '/verified',
unbuffer(
{
tokenId: accountResetToken.tokenId,
data: accountResetToken.data,
uid: accountResetToken.uid,
createdAt: accountResetToken.createdAt
},
'inplace'
)
)
.then(
function () {

16
npm-shrinkwrap.json сгенерированный
Просмотреть файл

@ -1,6 +1,6 @@
{
"name": "fxa-auth-server",
"version": "0.14.0",
"version": "0.14.1",
"dependencies": {
"ass": {
"version": "0.0.4",
@ -1579,7 +1579,7 @@
},
"mime": {
"version": "1.2.11",
"from": "mime@~1.2.11",
"from": "mime@1.2.11",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz"
},
"negotiator": {
@ -2873,6 +2873,18 @@
"from": "p-promise@0.2.5",
"resolved": "https://registry.npmjs.org/p-promise/-/p-promise-0.2.5.tgz"
},
"poolee": {
"version": "0.4.13",
"from": "poolee@0.4.13",
"resolved": "https://registry.npmjs.org/poolee/-/poolee-0.4.13.tgz",
"dependencies": {
"keep-alive-agent": {
"version": "0.0.1",
"from": "keep-alive-agent@*",
"resolved": "https://registry.npmjs.org/keep-alive-agent/-/keep-alive-agent-0.0.1.tgz"
}
}
},
"request": {
"version": "2.34.0",
"from": "request@2.34.0",

Просмотреть файл

@ -36,19 +36,19 @@
"bunyan": "0.22.1",
"compute-cluster": "git://github.com/dannycoates/node-compute-cluster.git#0222a742",
"convict": "0.4.2",
"fxa-auth-mailer": "git://github.com/dannycoates/fxa-auth-mailer.git#35b7f29e0a",
"fxa-customs-server": "git://github.com/mozilla/fxa-customs-server.git#74d7b8d6",
"hapi": "3.0.2",
"hapi-auth-hawk": "git://github.com/dannycoates/hapi-auth-hawk.git#146758e444",
"hkdf": "0.0.2",
"jwcrypto": "0.4.4",
"mysql": "2.1.1",
"p-promise": "0.2.5",
"request": "2.34.0",
"poolee": "0.4.13",
"scrypt-hash": "1.1.8",
"through": "2.3.4",
"toobusy": "0.2.4",
"uuid": "1.4.1",
"fxa-customs-server": "git://github.com/mozilla/fxa-customs-server.git#74d7b8d6",
"fxa-auth-mailer": "git://github.com/dannycoates/fxa-auth-mailer.git#35b7f29e0a"
"uuid": "1.4.1"
},
"devDependencies": {
"ass": "0.0.4",
@ -63,6 +63,7 @@
"lazysmtp": "git://github.com/dannycoates/node-lazysmtp.git#9bb3712992",
"load-grunt-tasks": "0.4.0",
"mailparser": "0.4.1",
"request": "2.34.0",
"sjcl": "1.0.0",
"tap": "0.4.8"
}

99
pool.js Normal file
Просмотреть файл

@ -0,0 +1,99 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var P = require('./promise')
var Poolee = require('poolee')
function parseUrl(url) {
var match = /([a-zA-Z]+):\/\/(\S+)/.exec(url)
if (match) {
return {
protocol: match[1],
host: match[2]
}
}
}
function Pool(url, options) {
options = options || {}
var foo = parseUrl(url)
var protocol = require(foo.protocol)
this.poolee = new Poolee(
protocol,
[foo.host],
{
timeout: options.timeout || 5000,
keepAlive: true,
maxRetries: 2
}
)
}
Pool.prototype.request = function (method, path, data) {
var d = P.defer()
this.poolee.request(
{
method: method || 'GET',
path: path,
headers: {
"Content-Type": "application/json"
},
data: data ? JSON.stringify(data) : undefined
},
function (err, res, body) {
if (err || Math.floor(res && res.statusCode / 100) !== 2) {
return d.reject({ error: err, statusCode: res && res.statusCode, body: body })
}
var json = null
try {
json = JSON.parse(body)
}
catch (e) {}
d.resolve(json)
}
)
return d.promise
}
Pool.prototype.post = function (path, data) {
return this.request('POST', path, data)
}
Pool.prototype.put = function (path, data) {
return this.request('PUT', path, data)
}
Pool.prototype.get = function (path) {
return this.request('GET', path)
}
Pool.prototype.del = function (path) {
return this.request('DELETE', path)
}
Pool.prototype.head = function (path) {
return this.request('HEAD', path)
}
Pool.prototype.close = function () {
/*/
This is a hack to coax the server to close its existing connections
/*/
var socketCount = this.poolee.options.maxSockets || 20
function noop() {}
for (var i = 0; i < socketCount; i++) {
this.poolee.request(
{
method: 'GET',
path: '/',
headers: {
"Connection": "close"
}
},
noop
)
}
}
module.exports = Pool

Просмотреть файл

@ -1,21 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var request = require('request')
var P = require('./promise')
module.exports = function requestp(options) {
var d = P.defer()
var r = (typeof(options) === 'string') ? { url: options, method: 'GET'} : options
request(
r,
function (err, res, body) {
if (err || Math.floor(res && res.statusCode / 100) !== 2) {
return d.reject({ error: err, statusCode: res && res.statusCode, body: body })
}
return d.resolve(body)
}
)
return d.promise
}