Skip to content

Instantly share code, notes, and snippets.

@darkyen
Created February 17, 2016 15:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darkyen/c29f07771d763602f5c6 to your computer and use it in GitHub Desktop.
Save darkyen/c29f07771d763602f5c6 to your computer and use it in GitHub Desktop.
cannot parse
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
(function (process){
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _plivo = require('plivo');
var _plivo2 = _interopRequireDefault(_plivo);
var _express = require('express');
var _express2 = _interopRequireDefault(_express);
var _bodyParser = require('body-parser');
var _bodyParser2 = _interopRequireDefault(_bodyParser);
var _webtaskTools = require('webtask-tools');
var _webtaskTools2 = _interopRequireDefault(_webtaskTools);
var app = (0, _express2['default'])();
app.use(_bodyParser2['default'].urlencoded({ extended: true }));
app.set('port', process.env.PORT || 5000);
// This file will be played when a caller presses 2.
var PLIVO_SONG = "https://s3.amazonaws.com/plivocloud/music.mp3";
// This is the message that Plivo reads when the caller dials in
var IVR_MESSAGE1 = "Welcome to the Plivo IVR Demo App. Press 1 to listen to a pre recorded text in different languages. Press 2 to listen to a song.";
var IVR_MESSAGE2 = "Press 1 for English. Press 2 for French. Press 3 for Russian";
// This is the message that Plivo reads when the caller does nothing at all
var NO_INPUT_MESSAGE = "Sorry, I didn't catch that. Please hangup and try again later.";
// This is the message that Plivo reads when the caller inputs a wrong number.
var WRONG_INPUT_MESSAGE = "Sorry, you've entered an invalid input.";
app.get('/response/ivr/', function (request, response) {
var r = _plivo2['default'].Response();
var getdigits_action_url, params, getDigits;
getdigits_action_url = request.protocol + '://' + request.headers.host + '/response/ivr/';
params = {
'action': getdigits_action_url,
'method': 'POST',
'timeout': '7',
'numDigits': '1',
'retries': '1'
};
getDigits = r.addGetDigits(params);
getDigits.addSpeak(IVR_MESSAGE1);
r.addSpeak(NO_INPUT_MESSAGE);
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.send(r.toXML());
});
app.post('/response/ivr/', function (request, response) {
var r = _plivo2['default'].Response();
var getdigits_action_url, params, getDigits;
var digit = request.body.Digits;
console.log(digit);
if (digit === '1') {
getdigits_action_url = request.protocol + '://' + request.headers.host + '/response/tree/';
params = {
'action': getdigits_action_url,
'method': 'POST',
'timeout': '7',
'numDigits': '1',
'retries': '1'
};
getDigits = r.addGetDigits(params);
getDigits.addSpeak(IVR_MESSAGE2);
r.addSpeak(NO_INPUT_MESSAGE);
} else if (digit === '2') {
r.addPlay(PLIVO_SONG);
} else {
r.addSpeak(WRONG_INPUT_MESSAGE);
}
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.send(r.toXML());
});
app.all('/response/tree/', function (request, response) {
var r = _plivo2['default'].Response();
var text, params;
var digit = request.body.Digits || request.query.Digits;
if (digit === "1") {
text = "This message is being read out in English";
params = { 'language': 'en-US' };
r.addSpeak(text, params);
} else if (digit === "2") {
text = "Ce message est lu en français";
params = { 'language': 'fr-FR' };
r.addSpeak(text, params);
} else if (digit === "3") {
text = "Это сообщение было прочитано в России";
params = { 'language': 'ru-RU' };
r.addSpeak(text, params);
} else {
r.addSpeak(WRONG_INPUT_MESSAGE);
}
console.log(r.toXML());
response.set({ 'Content-Type': 'text/xml' });
response.send(r.toXML());
});
module.exports = _webtaskTools2['default'].fromExpress(app);
}).call(this,require('_process'))
},{"_process":undefined,"body-parser":undefined,"express":undefined,"plivo":2,"webtask-tools":undefined}],2:[function(require,module,exports){
(function (process,Buffer){
//Get required modules
var util = require('util');
var crypto = require('crypto');
var Request = require('request');
var qs = require('querystring');
var xmlBuilder = require('xmlbuilder');
var doc = xmlBuilder.create();
var plivo = {};
plivo.options = {};
plivo.options.host = 'api.plivo.com';
plivo.options.version = 'v1';
plivo.options.authId = '';
plivo.options.authToken = '';
var UserAgent = 'NodePlivo';
// Generic Plivo Error
function PlivoError(msg) {
Error.call(this);
Error.captureStackTrace(this, arguments.callee);
this.message = (msg || '') + '\n';
this.name = 'PlivoError';
}
PlivoError.prototype = Error.prototype;
// Main request function
var request = function (action, method, params, callback, optional) {
if (optional) {
if (typeof params != 'object') {
if (typeof params == 'function') {
var callback = params;
}
var params = {};
}
}
if (!callback) {
var callback = function() {};
}
var err = null;
var path = 'https://' + plivo.options.host + '/' + plivo.options.version + '/Account/' + plivo.options.authId + '/' + action;
var auth = 'Basic ' + new Buffer(plivo.options.authId + ':' + plivo.options.authToken)
.toString('base64');
var headers = {
'Authorization': auth,
'User-Agent': UserAgent,
'Content-Type': 'application/json'
};
var request_options = {
uri: path,
headers: headers,
json: true,
};
if (method == 'POST') {
var body = JSON.stringify(params);
request_options.json = true;
request_options.body = body;
Request.post(request_options, function (error, response, body) {
if (error || !response) {
return callback(500, body)
}
if (response.statusCode != 201) {
err = new PlivoError(error);
}
callback(response.statusCode, body);
});
} else if (method == 'GET') {
request_options.qs = params;
Request.get(request_options, function (error, response, body) {
callback(response.statusCode, body);
});
} else if (method == 'DELETE') {
Request.del(request_options, function (error, response, body) {
callback(response.statusCode, body);
});
} else if (method == 'PUT') {
var body = JSON.stringify(params);
request_options.json = true;
request_options.body = body,
Request.put(request_options, function (error, response, body) {
callback(response.statusCode, body);
});
}
};
// Exposing generic request functionality as well.
plivo.request = request;
// For verifying the plivo server signature
plivo.create_signature = function (url, params) {
var toSign = url;
Object.keys(params).sort().forEach(function(key) {
toSign += key + params[key];
});
var signature = crypto
.createHmac('sha1', plivo.options.authToken)
.update(new Buffer(toSign, 'utf-8'))
.digest('base64');
return signature;
};
// Express middleware for verifying signature
plivo.middleware = function(options) {
return function (req, res, next) {
if (process.env.NODE_ENV === 'test') return next()
var toSign;
if (options && options.host) {
toSign = options.host;
} else {
toSign = req.protocol + '://' + req.host;
}
toSign += req.originalUrl;
var expectedSignature = plivo.create_signature(toSign, req.body);
if (expectedSignature === req.header('X-Plivo-Signature')) {
next();
} else {
var msg = 'Invalid Plivo Signature toSign=' + toSign + ', ' +
'expected=' + expectedSignature + ', ' +
'actual=' + req.header('X-Plivo-Signature');
next(new Error(msg));
}
};
};
// Calls
plivo.make_call = function (params, callback) {
var action = 'Call/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.get_cdrs = function (params, callback) {
var action = 'Call/';
var method = 'GET';
request(action, method, params, callback, true);
};
plivo.get_cdr = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/';
delete params.call_uuid;
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_live_calls = function (params, callback) {
var action = 'Call/';
var method = 'GET';
params.status = 'live';
request(action, method, params, callback, true);
};
plivo.get_live_call = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/';
delete params.call_uuid;
var method = 'GET';
params.status = 'live';
request(action, method, params, callback);
};
plivo.transfer_call = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/';
delete params.call_uuid;
var method = 'POST';
request(action, method, params, callback);
};
plivo.hangup_all_calls = function (callback) {
var action = 'Call/';
var method = 'DELETE';
var params = {};
request(action, method, params, callback);
};
plivo.hangup_call = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/';
delete params.call_uuid;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.record = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Record/';
delete params.call_uuid;
var method = 'POST';
request(action, method, params, callback);
};
plivo.record_stop = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Record/';
delete params.call_uuid;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.play = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Play/';
delete params.call_uuid;
var method = 'POST';
request(action, method, params, callback);
};
plivo.play_stop = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Play/';
delete params.call_uuid;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.speak = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Speak/';
delete params.call_uuid;
var method = 'POST';
request(action, method, params, callback);
};
plivo.speak_stop = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/Speak/';
delete params.call_uuid;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.send_digits = function (params, callback) {
var action = 'Call/' + params['call_uuid'] + '/DTMF/';
delete params.call_uuid;
var method = 'POST';
request(action, method, params, callback);
};
// Request
plivo.hangup_request = function (params, callback) {
var action = 'Request/' + params['request_uuid'] + '/';
delete params.request_uuid;
var method = 'DELETE';
request(action, method, params, callback);
};
// Conferences
plivo.get_live_conferences = function (params, callback) {
var action = 'Conference/';
var method = 'GET';
request(action, method, params, callback, true);
};
plivo.get_live_conference = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/';
delete params.conference_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.hangup_all_conferences = function (callback) {
var action = 'Conference/';
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.hangup_conference = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/';
delete params.conference_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.hangup_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/';
delete params.conference_id;
delete params.member_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.play_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Play/';
delete params.conference_id;
delete params.member_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.stop_play_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Play/';
delete params.conference_id;
delete params.member_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.speak_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Speak/';
console.log(action);
delete params.conference_id;
delete params.member_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.stop_speak_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Speak/';
delete params.conference_id;
delete params.member_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.deaf_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Deaf/';
delete params.conference_id;
delete params.member_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.undeaf_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Deaf/';
delete params.conference_id;
delete params.member_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.mute_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Mute/';
delete params.conference_id;
delete params.member_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.unmute_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Mute/';
delete params.conference_id;
delete params.member_id;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.kick_conference_member = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Member/' + params['member_id'] + '/Kick/';
delete params.conference_id;
delete params.member_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.record_conference = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Record/';
delete params.conference_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.stop_record_conference = function (params, callback) {
var action = 'Conference/' + params['conference_id'] + '/Record/';
delete params.conference_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Accounts
plivo.get_account = function (params, callback) {
var action = '';
var method = 'GET';
request(action, method, params, callback, true);
};
plivo.modify_account = function (params, callback) {
var action = '';
var method = 'POST';
request(action, method, params, callback);
};
plivo.get_subaccounts = function (params, callback) {
var action = 'Subaccount/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_subaccount = function (params, callback) {
var action = 'Subaccount/' + params['subauth_id'] + '/';
delete params.subauth_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_subaccount = function (params, callback) {
var action = 'Subaccount/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_subaccount = function (params, callback) {
var action = 'Subaccount/' + params['subauth_id'] + '/';
delete params.subauth_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_subaccount = function (params, callback) {
var action = 'Subaccount/' + params['subauth_id'] + '/';
delete params.subauth_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Applications
plivo.get_applications = function (params, callback) {
var action = 'Application/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_application = function (params, callback) {
var action = 'Application/' + params['app_id'] + '/';
delete params.app_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_application = function (params, callback) {
var action = 'Application/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_application = function (params, callback) {
var action = 'Application/' + params['app_id'] + '/';
delete params.app_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_application = function (params, callback) {
var action = 'Application/' + params['app_id'] + '/';
delete params.app_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Recordings
plivo.get_recordings = function (params, callback) {
var action = 'Recording/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_recording = function (params, callback) {
var action = 'Recording/' + params['recording_id'] + '/';
delete params.recording_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.delete_recording = function (params, callback) {
var action = 'Recording/' + params['recording_id'] + '/';
delete params.recording_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Endpoints
plivo.get_endpoints = function (params, callback) {
var action = 'Endpoint/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_endpoint = function (params, callback) {
var action = 'Endpoint/' + params['endpoint_id'] + '/';
delete params.endpoint_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_endpoint = function (params, callback) {
var action = 'Endpoint/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_endpoint = function (params, callback) {
var action = 'Endpoint/' + params['endpoint_id'] + '/';
delete params.endpoint_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_endpoint = function (params, callback) {
var action = 'Endpoint/' + params['endpoint_id'] + '/';
delete params.endpoint_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Numbers
plivo.get_numbers = function (params, callback) {
var action = 'Number/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_number_details = function (params, callback) {
var action = 'Number/' + params['number'] + '/';
delete params.number;
var method = 'GET';
request(action, method, params, callback);
};
plivo.unrent_number = function (params, callback) {
var action = 'Number/' + params['number'] + '/';
delete params.number;
var method = 'DELETE';
request(action, method, params, callback);
};
plivo.get_number_group = function (params, callback) {
var action = 'AvailableNumberGroup/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_number_group_details = function (params, callback) {
var action = 'AvailableNumberGroup/' + params['group_id'] + '/';
delete params.group_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.rent_from_number_group = function (params, callback) {
var action = 'AvailableNumberGroup/' + params['group_id'] + '/';
delete params.group_id;
var method = 'POST';
request(action, method, params, callback, true);
};
plivo.edit_number = function (params, callback) {
var action = 'Number/' + params['number'] + '/';
delete params.number;
var method = 'POST';
request(action, method, params, callback);
};
plivo.link_application_number = function (params, callback) {
this.edit_number(params, callback);
};
plivo.unlink_application_number = function (params, callback) {
params.app_id = null;
this.edit_number(params, callback);
};
plivo.search_phone_numbers = function (params, callback) {
var action = 'PhoneNumber/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.buy_phone_number = function (params, callback) {
var action = 'PhoneNumber/' + params['number'] + '/';
delete params.number;
var method = 'POST';
request(action, method, params, callback, true);
};
// Message
plivo.send_message = function (params, callback) {
var action = 'Message/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.get_messages = function (params, callback) {
var action = 'Message/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_message = function (params, callback) {
var action = 'Message/' + params['record_id'] + '/';
delete params.record_id;
var method = 'GET';
request(action, method, params, callback);
};
// Incoming Carriers
plivo.get_incoming_carriers = function (params, callback) {
var action = 'IncomingCarrier/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_incoming_carrier = function (params, callback) {
var action = 'IncomingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_incoming_carrier = function (params, callback) {
var action = 'IncomingCarrier/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_incoming_carrier = function (params, callback) {
var action = 'IncomingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_incoming_carrier = function (params, callback) {
var action = 'IncomingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Outgoing Carriers
plivo.get_outgoing_carriers = function (params, callback) {
var action = 'OutgoingCarrier/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_outgoing_carrier = function (params, callback) {
var action = 'OutgoingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_outgoing_carrier = function (params, callback) {
var action = 'OutgoingCarrier/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_outgoing_carrier = function (params, callback) {
var action = 'OutgoingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_outgoing_carrier = function (params, callback) {
var action = 'OutgoingCarrier/' + params['carrier_id'] + '/';
delete params.carrier_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Outgoing Carrier Routings
plivo.get_outgoing_carrier_routings = function (params, callback) {
var action = 'OutgoingCarrierRouting/';
var method = 'GET';
request(action, method, params, callback);
};
plivo.get_outgoing_carrier_routing = function (params, callback) {
var action = 'OutgoingCarrierRouting/' + params['routing_id'] + '/';
delete params.routing_id;
var method = 'GET';
request(action, method, params, callback);
};
plivo.create_outgoing_carrier_routing = function (params, callback) {
var action = 'OutgoingCarrierRouting/';
var method = 'POST';
request(action, method, params, callback);
};
plivo.modify_outgoing_carrier_routing = function (params, callback) {
var action = 'OutgoingCarrierRouting/' + params['routing_id'] + '/';
delete params.routing_id;
var method = 'POST';
request(action, method, params, callback);
};
plivo.delete_outgoing_carrier_routing = function (params, callback) {
var action = 'OutgoingCarrierRouting/' + params['routing_id'] + '/';
delete params.routing_id;
var method = 'DELETE';
request(action, method, params, callback);
};
// Pricing
plivo.get_pricing = function (params, callback) {
var action = 'Pricing/';
var method = 'GET';
request(action, method, params, callback);
};
/**
* XML Response Generation
*/
// Decalaring a class Response
function Response() {
this.element = 'Response';
this.nestables = ['Speak', 'Play', 'GetDigits', 'Record', 'Dial', 'Message',
'Redirect', 'Wait', 'Hangup', 'PreAnswer', 'Conference', 'DTMF'];
this.valid_attributes = [];
this.elem = doc.begin(this.element);
};
Response.prototype = {
init: function (name, body, attributes, parent) {
this.name = name;
this.body = body;
this.elem = '';
if (this.element != 'Response') {
this.elem.parent = parent;
this.elem = parent.ele(this.name);
} else {
this.elem = this.elem.ele(this.name);
}
if (!attributes) {
var attributes = {};
}
var keys = Object.keys(attributes);
for (var i = 0; i < keys.length; i++) {
if (this.valid_attributes.indexOf(keys[i]) == -1) {
throw new PlivoError('Not a valid attribute : "' + keys[i] + '" for "' + this.name + '" Element');
}
this.elem.att(keys[i], attributes[keys[i]])
}
if (body) {
this.elem.text(body)
}
},
add: function (new_element, body, attributes) {
if (body === undefined) {
throw new PlivoError('No text set for ' + new_element.element + '.');
}
if (this.nestables.indexOf(new_element.element) > -1) {
var parent = this.elem;
} else {
throw new PlivoError(new_element.element + ' cannot be nested in ' + this.element + '.');
}
new_element.init(new_element.element, body, attributes, parent);
return new_element;
},
addConference: function (body, attributes) {
return this.add(new Conference(Response), body, attributes);
},
addNumber: function (body, attributes) {
return this.add(new Number(Response), body, attributes);
},
addUser: function (body) {
return this.add(new User(Response), body, {});
},
addDial: function (attributes) {
return this.add(new Dial(Response), '', attributes);
},
addGetDigits: function (attributes) {
return this.add(new GetDigits(Response), '', attributes);
},
addHangup: function (attributes) {
return this.add(new Hangup(Response), '', attributes);
},
addMessage: function (body, attributes) {
return this.add(new Message(Response), body, attributes);
},
addPlay: function (body, attributes) {
return this.add(new Play(Response), body, attributes);
},
addPreAnswer: function () {
return this.add(new PreAnswer(Response), '', {});
},
addRecord: function (attributes) {
return this.add(new Record(Response),'', attributes);
},
addRedirect: function (body, attributes) {
return this.add(new Redirect(Response), body, attributes);
},
addSpeak: function (body, attributes) {
return this.add(new Speak(Response), body, attributes);
},
addWait: function (attributes) {
return this.add(new Wait(Response), '', attributes);
},
addDTMF: function (body, attributes) {
return this.add(new DTMF(Response), body, attributes);
},
toXML: function () {
return this.elem.toString();
}
}
function Conference(Response) {
this.element = 'Conference';
this.valid_attributes = ['muted', 'beep', 'startConferenceOnEnter',
'endConferenceOnExit', 'waitSound', 'enterSound', 'exitSound',
'timeLimit', 'hangupOnStar', 'maxMembers', 'record','recordWhenAlone',
'recordFileFormat', 'action', 'method', 'redirect',
'digitsMatch', 'callbackUrl', 'callbackMethod', 'stayAlone',
'floorEvent', 'transcriptionType', 'transcriptionUrl',
'transcriptionMethod', 'relayDTMF'];
this.nestables = [];
}
util.inherits(Conference, Response);
function Number(Response) {
this.element = 'Number';
this.valid_attributes = ['sendDigits', 'sendOnPreanswer', 'sendDigitsMode'];
this.nestables = [];
}
util.inherits(Number, Response);
function User(Response) {
this.element = 'User';
this.nestables = [];
this.valid_attributes = ['sendDigits', 'sendOnPreanswer', 'sipHeaders'];
}
util.inherits(User, Response);
function Dial(Response) {
this.element = 'Dial';
this.valid_attributes = ['action', 'method', 'timeout', 'hangupOnStar',
'timeLimit', 'callerId', 'callerName', 'confirmSound',
'dialMusic', 'confirmKey', 'redirect', 'callbackUrl',
'callbackMethod', 'digitsMatch', 'digitsMatchBLeg', 'sipHeaders'];
this.nestables = ['Number', 'User'];
}
util.inherits(Dial, Response);
function GetDigits(Response) {
this.element = 'GetDigits';
this.valid_attributes = ['action', 'method', 'timeout', 'digitTimeout',
'finishOnKey', 'numDigits', 'retries', 'invalidDigitsSound',
'validDigits', 'playBeep', 'redirect', 'log'];
this.nestables = ['Speak', 'Play', 'Wait'];
}
util.inherits(GetDigits, Response);
function Hangup(Response) {
this.element = 'Hangup';
this.valid_attributes = ['schedule', 'reason'];
this.nestables = [];
}
util.inherits(Hangup, Response);
function Message(Response) {
this.element = 'Message';
this.nestables = [];
this.valid_attributes = ['src', 'dst', 'type', 'callbackUrl',
'callbackMethod'];
}
util.inherits(Message, Response);
function Play(Response) {
this.element = 'Play';
this.valid_attributes = ['loop'];
this.nestables = [];
}
util.inherits(Play, Response);
function PreAnswer(Response) {
this.element = 'PreAnswer';
this.valid_attributes = [];
this.nestables = ['Play', 'Speak', 'GetDigits', 'Wait', 'Redirect',
'Message', 'DTMF'];
}
util.inherits(PreAnswer, Response);
function Record(Response) {
this.element = 'Record';
this.nestables = [];
this.valid_attributes = ['action', 'method', 'timeout', 'finishOnKey',
'maxLength', 'playBeep', 'recordSession',
'startOnDialAnswer', 'redirect', 'fileFormat',
'callbackUrl', 'callbackMethod', 'transcriptionType',
'transcriptionUrl', 'transcriptionMethod'];
}
util.inherits(Record, Response);
function Redirect(Response) {
this.element = 'Redirect';
this.valid_attributes = ['method'];
this.nestables = [];
}
util.inherits(Redirect, Response);
function Speak(Response) {
this.element = 'Speak';
this.valid_attributes = ['voice', 'language', 'loop'];
this.nestables = [];
}
util.inherits(Speak, Response);
function Wait(Response) {
this.element = 'Wait';
this.valid_attributes = ['length', 'silence', 'min_silence', 'minSilence', 'beep'];
this.nestables = [];
}
util.inherits(Wait, Response);
function DTMF(Response) {
this.element = 'DTMF';
this.nestables = [];
this.valid_attributes = ['digits', 'async'];
}
util.inherits(DTMF, Response);
/**
* Module Exports
*/
exports.Response = function () {
return new Response();
}
exports.RestAPI = function (config) {
if (!config) {
throw new PlivoError('Auth ID and Auth Token must be provided.');
}
if (typeof config != 'object') {
throw new PlivoError('Config for RestAPI must be provided as an object.');
}
if (!config.authId || !config.authToken) {
throw new PlivoError('Auth ID and Auth Token must be provided.');
}
// override default config according to the config provided.
for (key in config) {
plivo.options[key] = config[key];
}
return plivo;
}
}).call(this,require('_process'),require("buffer").Buffer)
},{"_process":undefined,"buffer":undefined,"crypto":undefined,"querystring":undefined,"request":5,"util":undefined,"xmlbuilder":19}],3:[function(require,module,exports){
/*!
* knox - auth
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var crypto = require('crypto')
, parse = require('url').parse
;
/**
* Valid keys.
*/
var keys =
[ 'acl'
, 'location'
, 'logging'
, 'notification'
, 'partNumber'
, 'policy'
, 'requestPayment'
, 'torrent'
, 'uploadId'
, 'uploads'
, 'versionId'
, 'versioning'
, 'versions'
, 'website'
]
/**
* Return an "Authorization" header value with the given `options`
* in the form of "AWS <key>:<signature>"
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.authorization = function(options){
return 'AWS ' + options.key + ':' + exports.sign(options)
}
/**
* Simple HMAC-SHA1 Wrapper
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.hmacSha1 = function(options){
return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
}
/**
* Create a base64 sha1 HMAC for `options`.
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.sign = function(options){
options.message = exports.stringToSign(options)
return exports.hmacSha1(options)
}
/**
* Create a base64 sha1 HMAC for `options`.
*
* Specifically to be used with S3 presigned URLs
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.signQuery = function(options){
options.message = exports.queryStringToSign(options)
return exports.hmacSha1(options)
}
/**
* Return a string for sign() with the given `options`.
*
* Spec:
*
* <verb>\n
* <md5>\n
* <content-type>\n
* <date>\n
* [headers\n]
* <resource>
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.stringToSign = function(options){
var headers = options.amazonHeaders || ''
if (headers) headers += '\n'
var r =
[ options.verb
, options.md5
, options.contentType
, options.date.toUTCString()
, headers + options.resource
]
return r.join('\n')
}
/**
* Return a string for sign() with the given `options`, but is meant exclusively
* for S3 presigned URLs
*
* Spec:
*
* <date>\n
* <resource>
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.queryStringToSign = function(options){
return 'GET\n\n\n' + options.date + '\n' + options.resource
};
/**
* Perform the following:
*
* - ignore non-amazon headers
* - lowercase fields
* - sort lexicographically
* - trim whitespace between ":"
* - join with newline
*
* @param {Object} headers
* @return {String}
* @api private
*/
exports.canonicalizeHeaders = function(headers){
var buf = []
, fields = Object.keys(headers)
;
for (var i = 0, len = fields.length; i < len; ++i) {
var field = fields[i]
, val = headers[field]
, field = field.toLowerCase()
;
if (0 !== field.indexOf('x-amz')) continue
buf.push(field + ':' + val)
}
return buf.sort().join('\n')
};
/**
* Perform the following:
*
* - ignore non sub-resources
* - sort lexicographically
*
* @param {String} resource
* @return {String}
* @api private
*/
exports.canonicalizeResource = function(resource){
var url = parse(resource, true)
, path = url.pathname
, buf = []
;
Object.keys(url.query).forEach(function(key){
if (!~keys.indexOf(key)) return
var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
buf.push(key + val)
})
return path + (buf.length ? '?' + buf.sort().join('&') : '')
};
},{"crypto":undefined,"url":undefined}],4:[function(require,module,exports){
module.exports = ForeverAgent
ForeverAgent.SSL = ForeverAgentSSL
var util = require('util')
, Agent = require('http').Agent
, net = require('net')
, tls = require('tls')
, AgentSSL = require('https').Agent
function ForeverAgent(options) {
var self = this
self.options = options || {}
self.requests = {}
self.sockets = {}
self.freeSockets = {}
self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets
self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets
self.on('free', function(socket, host, port) {
var name = host + ':' + port
if (self.requests[name] && self.requests[name].length) {
self.requests[name].shift().onSocket(socket)
} else if (self.sockets[name].length < self.minSockets) {
if (!self.freeSockets[name]) self.freeSockets[name] = []
self.freeSockets[name].push(socket)
// if an error happens while we don't use the socket anyway, meh, throw the socket away
function onIdleError() {
socket.destroy()
}
socket._onIdleError = onIdleError
socket.on('error', onIdleError)
} else {
// If there are no pending requests just destroy the
// socket and it will get removed from the pool. This
// gets us out of timeout issues and allows us to
// default to Connection:keep-alive.
socket.destroy()
}
})
}
util.inherits(ForeverAgent, Agent)
ForeverAgent.defaultMinSockets = 5
ForeverAgent.prototype.createConnection = net.createConnection
ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest
ForeverAgent.prototype.addRequest = function(req, host, port) {
var name = host + ':' + port
if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) {
var idleSocket = this.freeSockets[name].pop()
idleSocket.removeListener('error', idleSocket._onIdleError)
delete idleSocket._onIdleError
req._reusedSocket = true
req.onSocket(idleSocket)
} else {
this.addRequestNoreuse(req, host, port)
}
}
ForeverAgent.prototype.removeSocket = function(s, name, host, port) {
if (this.sockets[name]) {
var index = this.sockets[name].indexOf(s)
if (index !== -1) {
this.sockets[name].splice(index, 1)
}
} else if (this.sockets[name] && this.sockets[name].length === 0) {
// don't leak
delete this.sockets[name]
delete this.requests[name]
}
if (this.freeSockets[name]) {
var index = this.freeSockets[name].indexOf(s)
if (index !== -1) {
this.freeSockets[name].splice(index, 1)
if (this.freeSockets[name].length === 0) {
delete this.freeSockets[name]
}
}
}
if (this.requests[name] && this.requests[name].length) {
// If we have pending requests and a socket gets closed a new one
// needs to be created to take over in the pool for the one that closed.
this.createSocket(name, host, port).emit('free')
}
}
function ForeverAgentSSL (options) {
ForeverAgent.call(this, options)
}
util.inherits(ForeverAgentSSL, ForeverAgent)
ForeverAgentSSL.prototype.createConnection = createConnectionSSL
ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest
function createConnectionSSL (port, host, options) {
options.port = port
options.host = host
return tls.connect(options)
}
},{"http":undefined,"https":undefined,"net":undefined,"tls":undefined,"util":undefined}],5:[function(require,module,exports){
(function (process,Buffer){
// Copyright 2010-2012 Mikeal Rogers
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
var http = require('http')
, https = false
, tls = false
, url = require('url')
, util = require('util')
, stream = require('stream')
, qs = require('querystring')
, oauth = require('./oauth')
, uuid = require('./uuid')
, ForeverAgent = require('./forever')
, Cookie = require('./vendor/cookie')
, CookieJar = require('./vendor/cookie/jar')
, cookieJar = new CookieJar
, tunnel = require('./tunnel')
, aws = require('./aws')
, mime = require('mime')
, FormData = require('form-data')
;
if (process.logging) {
var log = process.logging('request')
}
try {
https = require('https')
} catch (e) {}
try {
tls = require('tls')
} catch (e) {}
function toBase64 (str) {
return (new Buffer(str || "", "ascii")).toString("base64")
}
// Hacky fix for pre-0.4.4 https
if (https && !https.Agent) {
https.Agent = function (options) {
http.Agent.call(this, options)
}
util.inherits(https.Agent, http.Agent)
https.Agent.prototype._getConnection = function (host, port, cb) {
var s = tls.connect(port, host, this.options, function () {
// do other checks here?
if (cb) cb()
})
return s
}
}
function isReadStream (rs) {
if (rs.readable && rs.path && rs.mode) {
return true
}
}
function copy (obj) {
var o = {}
Object.keys(obj).forEach(function (i) {
o[i] = obj[i]
})
return o
}
var isUrl = /^https?:/
var globalPool = {}
function Request (options) {
stream.Stream.call(this)
this.readable = true
this.writable = true
if (typeof options === 'string') {
options = {uri:options}
}
var reserved = Object.keys(Request.prototype)
for (var i in options) {
if (reserved.indexOf(i) === -1) {
this[i] = options[i]
} else {
if (typeof options[i] === 'function') {
delete options[i]
}
}
}
options = copy(options)
this.init(options)
}
util.inherits(Request, stream.Stream)
Request.prototype.init = function (options) {
var self = this
if (!options) options = {}
if (process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG)) console.error('REQUEST', options)
if (!self.pool && self.pool !== false) self.pool = globalPool
self.dests = []
self.__isRequestRequest = true
// Protect against double callback
if (!self._callback && self.callback) {
self._callback = self.callback
self.callback = function () {
if (self._callbackCalled) return // Print a warning maybe?
self._callback.apply(self, arguments)
self._callbackCalled = true
}
self.on('error', self.callback.bind())
self.on('complete', self.callback.bind(self, null))
}
if (self.url) {
// People use this property instead all the time so why not just support it.
self.uri = self.url
delete self.url
}
if (!self.uri) {
// this will throw if unhandled but is handleable when in a redirect
return self.emit('error', new Error("options.uri is a required argument"))
} else {
if (typeof self.uri == "string") self.uri = url.parse(self.uri)
}
if (self.proxy) {
if (typeof self.proxy == 'string') self.proxy = url.parse(self.proxy)
// do the HTTP CONNECT dance using koichik/node-tunnel
if (http.globalAgent && self.uri.protocol === "https:") {
var tunnelFn = self.proxy.protocol === "http:"
? tunnel.httpsOverHttp : tunnel.httpsOverHttps
var tunnelOptions = { proxy: { host: self.proxy.hostname
, port: +self.proxy.port
, proxyAuth: self.proxy.auth }
, ca: this.ca }
self.agent = tunnelFn(tunnelOptions)
self.tunnel = true
}
}
if (!self.uri.host || !self.uri.pathname) {
// Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar
// Detect and reject it as soon as possible
var faultyUri = url.format(self.uri)
var message = 'Invalid URI "' + faultyUri + '"'
if (Object.keys(options).length === 0) {
// No option ? This can be the sign of a redirect
// As this is a case where the user cannot do anything (he didn't call request directly with this URL)
// he should be warned that it can be caused by a redirection (can save some hair)
message += '. This can be caused by a crappy redirection.'
}
self.emit('error', new Error(message))
return // This error was fatal
}
self._redirectsFollowed = self._redirectsFollowed || 0
self.maxRedirects = (self.maxRedirects !== undefined) ? self.maxRedirects : 10
self.followRedirect = (self.followRedirect !== undefined) ? self.followRedirect : true
self.followAllRedirects = (self.followAllRedirects !== undefined) ? self.followAllRedirects : false
if (self.followRedirect || self.followAllRedirects)
self.redirects = self.redirects || []
self.headers = self.headers ? copy(self.headers) : {}
self.setHost = false
if (!self.headers.host) {
self.headers.host = self.uri.hostname
if (self.uri.port) {
if ( !(self.uri.port === 80 && self.uri.protocol === 'http:') &&
!(self.uri.port === 443 && self.uri.protocol === 'https:') )
self.headers.host += (':'+self.uri.port)
}
self.setHost = true
}
self.jar(self._jar || options.jar)
if (!self.uri.pathname) {self.uri.pathname = '/'}
if (!self.uri.port) {
if (self.uri.protocol == 'http:') {self.uri.port = 80}
else if (self.uri.protocol == 'https:') {self.uri.port = 443}
}
if (self.proxy && !self.tunnel) {
self.port = self.proxy.port
self.host = self.proxy.hostname
} else {
self.port = self.uri.port
self.host = self.uri.hostname
}
self.clientErrorHandler = function (error) {
if (self._aborted) return
if (self.setHost) delete self.headers.host
if (self.req._reusedSocket && error.code === 'ECONNRESET'
&& self.agent.addRequestNoreuse) {
self.agent = { addRequest: self.agent.addRequestNoreuse.bind(self.agent) }
self.start()
self.req.end()
return
}
if (self.timeout && self.timeoutTimer) {
clearTimeout(self.timeoutTimer)
self.timeoutTimer = null
}
self.emit('error', error)
}
self._parserErrorHandler = function (error) {
if (this.res) {
if (this.res.request) {
this.res.request.emit('error', error)
} else {
this.res.emit('error', error)
}
} else {
this._httpMessage.emit('error', error)
}
}
if (options.form) {
self.form(options.form)
}
if (options.oauth) {
self.oauth(options.oauth)
}
if (options.aws) {
self.aws(options.aws)
}
if (self.uri.auth && !self.headers.authorization) {
self.headers.authorization = "Basic " + toBase64(self.uri.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
}
if (self.proxy && self.proxy.auth && !self.headers['proxy-authorization'] && !self.tunnel) {
self.headers['proxy-authorization'] = "Basic " + toBase64(self.proxy.auth.split(':').map(function(item){ return qs.unescape(item)}).join(':'))
}
if (options.qs) self.qs(options.qs)
if (self.uri.path) {
self.path = self.uri.path
} else {
self.path = self.uri.pathname + (self.uri.search || "")
}
if (self.path.length === 0) self.path = '/'
if (self.proxy && !self.tunnel) self.path = (self.uri.protocol + '//' + self.uri.host + self.path)
if (options.json) {
self.json(options.json)
} else if (options.multipart) {
self.boundary = uuid()
self.multipart(options.multipart)
}
if (self.body) {
var length = 0
if (!Buffer.isBuffer(self.body)) {
if (Array.isArray(self.body)) {
for (var i = 0; i < self.body.length; i++) {
length += self.body[i].length
}
} else {
self.body = new Buffer(self.body)
length = self.body.length
}
} else {
length = self.body.length
}
if (length) {
if(!self.headers['content-length'] && !self.headers['Content-Length'])
self.headers['content-length'] = length
} else {
throw new Error('Argument error, options.body.')
}
}
var protocol = self.proxy && !self.tunnel ? self.proxy.protocol : self.uri.protocol
, defaultModules = {'http:':http, 'https:':https}
, httpModules = self.httpModules || {}
;
self.httpModule = httpModules[protocol] || defaultModules[protocol]
if (!self.httpModule) return this.emit('error', new Error("Invalid protocol"))
if (options.ca) self.ca = options.ca
if (!self.agent) {
if (options.agentOptions) self.agentOptions = options.agentOptions
if (options.agentClass) {
self.agentClass = options.agentClass
} else if (options.forever) {
self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
} else {
self.agentClass = self.httpModule.Agent
}
}
if (self.pool === false) {
self.agent = false
} else {
self.agent = self.agent || self.getAgent()
if (self.maxSockets) {
// Don't use our pooling if node has the refactored client
self.agent.maxSockets = self.maxSockets
}
if (self.pool.maxSockets) {
// Don't use our pooling if node has the refactored client
self.agent.maxSockets = self.pool.maxSockets
}
}
self.once('pipe', function (src) {
if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.")
self.src = src
if (isReadStream(src)) {
if (!self.headers['content-type'] && !self.headers['Content-Type'])
self.headers['content-type'] = mime.lookup(src.path)
} else {
if (src.headers) {
for (var i in src.headers) {
if (!self.headers[i]) {
self.headers[i] = src.headers[i]
}
}
}
if (self._json && !self.headers['content-type'] && !self.headers['Content-Type'])
self.headers['content-type'] = 'application/json'
if (src.method && !self.method) {
self.method = src.method
}
}
self.on('pipe', function () {
console.error("You have already piped to this stream. Pipeing twice is likely to break the request.")
})
})
process.nextTick(function () {
if (self._aborted) return
if (self._form) {
self.setHeaders(self._form.getHeaders())
self._form.pipe(self)
}
if (self.body) {
if (Array.isArray(self.body)) {
self.body.forEach(function (part) {
self.write(part)
})
} else {
self.write(self.body)
}
self.end()
} else if (self.requestBodyStream) {
console.warn("options.requestBodyStream is deprecated, please pass the request object to stream.pipe.")
self.requestBodyStream.pipe(self)
} else if (!self.src) {
if (self.method !== 'GET' && typeof self.method !== 'undefined') {
self.headers['content-length'] = 0
}
self.end()
}
self.ntick = true
})
}
// Must call this when following a redirect from https to http or vice versa
// Attempts to keep everything as identical as possible, but update the
// httpModule, Tunneling agent, and/or Forever Agent in use.
Request.prototype._updateProtocol = function () {
var self = this
var protocol = self.uri.protocol
if (protocol === 'https:') {
// previously was doing http, now doing https
// if it's https, then we might need to tunnel now.
if (self.proxy) {
self.tunnel = true
var tunnelFn = self.proxy.protocol === 'http:'
? tunnel.httpsOverHttp : tunnel.httpsOverHttps
var tunnelOptions = { proxy: { host: self.proxy.hostname
, post: +self.proxy.port
, proxyAuth: self.proxy.auth }
, ca: self.ca }
self.agent = tunnelFn(tunnelOptions)
return
}
self.httpModule = https
switch (self.agentClass) {
case ForeverAgent:
self.agentClass = ForeverAgent.SSL
break
case http.Agent:
self.agentClass = https.Agent
break
default:
// nothing we can do. Just hope for the best.
return
}
// if there's an agent, we need to get a new one.
if (self.agent) self.agent = self.getAgent()
} else {
if (log) log('previously https, now http')
// previously was doing https, now doing http
// stop any tunneling.
if (self.tunnel) self.tunnel = false
self.httpModule = http
switch (self.agentClass) {
case ForeverAgent.SSL:
self.agentClass = ForeverAgent
break
case https.Agent:
self.agentClass = http.Agent
break
default:
// nothing we can do. just hope for the best
return
}
// if there's an agent, then get a new one.
if (self.agent) {
self.agent = null
self.agent = self.getAgent()
}
}
}
Request.prototype.getAgent = function () {
var Agent = this.agentClass
var options = {}
if (this.agentOptions) {
for (var i in this.agentOptions) {
options[i] = this.agentOptions[i]
}
}
if (this.ca) options.ca = this.ca
var poolKey = ''
// different types of agents are in different pools
if (Agent !== this.httpModule.Agent) {
poolKey += Agent.name
}
if (!this.httpModule.globalAgent) {
// node 0.4.x
options.host = this.host
options.port = this.port
if (poolKey) poolKey += ':'
poolKey += this.host + ':' + this.port
}
// ca option is only relevant if proxy or destination are https
var proxy = this.proxy
if (typeof proxy === 'string') proxy = url.parse(proxy)
var caRelevant = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:'
if (options.ca && caRelevant) {
if (poolKey) poolKey += ':'
poolKey += options.ca
}
if (!poolKey && Agent === this.httpModule.Agent && this.httpModule.globalAgent) {
// not doing anything special. Use the globalAgent
return this.httpModule.globalAgent
}
// we're using a stored agent. Make sure it's protocol-specific
poolKey = this.uri.protocol + poolKey
// already generated an agent for this setting
if (this.pool[poolKey]) return this.pool[poolKey]
return this.pool[poolKey] = new Agent(options)
}
Request.prototype.start = function () {
var self = this
if (self._aborted) return
self._started = true
self.method = self.method || 'GET'
self.href = self.uri.href
if (log) log('%method %href', self)
if (self.src && self.src.stat && self.src.stat.size && !self.headers['content-length'] && !self.headers['Content-Length']) {
self.headers['content-length'] = self.src.stat.size
}
if (self._aws) {
self.aws(self._aws, true)
}
self.req = self.httpModule.request(self, function (response) {
if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) {
response.connection.once('error', self._parserErrorHandler)
}
if (self._aborted) return
if (self._paused) response.pause()
self.response = response
response.request = self
response.toJSON = toJSON
if (self.httpModule === https &&
self.strictSSL &&
!response.client.authorized) {
var sslErr = response.client.authorizationError
self.emit('error', new Error('SSL Error: '+ sslErr))
return
}
if (self.setHost) delete self.headers.host
if (self.timeout && self.timeoutTimer) {
clearTimeout(self.timeoutTimer)
self.timeoutTimer = null
}
var addCookie = function (cookie) {
if (self._jar) self._jar.add(new Cookie(cookie))
else cookieJar.add(new Cookie(cookie))
}
if (response.headers['set-cookie'] && (!self._disableCookies)) {
if (Array.isArray(response.headers['set-cookie'])) response.headers['set-cookie'].forEach(addCookie)
else addCookie(response.headers['set-cookie'])
}
if (response.statusCode >= 300 && response.statusCode < 400 &&
(self.followAllRedirects ||
(self.followRedirect && (self.method !== 'PUT' && self.method !== 'POST' && self.method !== 'DELETE'))) &&
response.headers.location) {
if (self._redirectsFollowed >= self.maxRedirects) {
self.emit('error', new Error("Exceeded maxRedirects. Probably stuck in a redirect loop "+self.uri.href))
return
}
self._redirectsFollowed += 1
if (!isUrl.test(response.headers.location)) {
response.headers.location = url.resolve(self.uri.href, response.headers.location)
}
var uriPrev = self.uri
self.uri = url.parse(response.headers.location)
// handle the case where we change protocol from https to http or vice versa
if (self.uri.protocol !== uriPrev.protocol) {
self._updateProtocol()
}
self.redirects.push(
{ statusCode : response.statusCode
, redirectUri: response.headers.location
}
)
if (self.followAllRedirects) self.method = 'GET'
// self.method = 'GET' // Force all redirects to use GET || commented out fixes #215
delete self.src
delete self.req
delete self.agent
delete self._started
delete self.body
delete self._form
if (self.headers) {
delete self.headers.host
delete self.headers['content-type']
delete self.headers['content-length']
}
if (log) log('Redirect to %uri', self)
self.init()
return // Ignore the rest of the response
} else {
self._redirectsFollowed = self._redirectsFollowed || 0
// Be a good stream and emit end when the response is finished.
// Hack to emit end on close because of a core bug that never fires end
response.on('close', function () {
if (!self._ended) self.response.emit('end')
})
if (self.encoding) {
if (self.dests.length !== 0) {
console.error("Ingoring encoding parameter as this stream is being piped to another stream which makes the encoding option invalid.")
} else {
response.setEncoding(self.encoding)
}
}
self.dests.forEach(function (dest) {
self.pipeDest(dest)
})
response.on("data", function (chunk) {
self._destdata = true
self.emit("data", chunk)
})
response.on("end", function (chunk) {
self._ended = true
self.emit("end", chunk)
})
response.on("close", function () {self.emit("close")})
self.emit('response', response)
if (self.callback) {
var buffer = []
var bodyLen = 0
self.on("data", function (chunk) {
buffer.push(chunk)
bodyLen += chunk.length
})
self.on("end", function () {
if (self._aborted) return
if (buffer.length && Buffer.isBuffer(buffer[0])) {
var body = new Buffer(bodyLen)
var i = 0
buffer.forEach(function (chunk) {
chunk.copy(body, i, 0, chunk.length)
i += chunk.length
})
if (self.encoding === null) {
response.body = body
} else {
response.body = body.toString(self.encoding)
}
} else if (buffer.length) {
response.body = buffer.join('')
}
if (self._json) {
try {
response.body = JSON.parse(response.body)
} catch (e) {}
}
self.emit('complete', response, response.body)
})
}
}
})
if (self.timeout && !self.timeoutTimer) {
self.timeoutTimer = setTimeout(function () {
self.req.abort()
var e = new Error("ETIMEDOUT")
e.code = "ETIMEDOUT"
self.emit("error", e)
}, self.timeout)
// Set additional timeout on socket - in case if remote
// server freeze after sending headers
if (self.req.setTimeout) { // only works on node 0.6+
self.req.setTimeout(self.timeout, function () {
if (self.req) {
self.req.abort()
var e = new Error("ESOCKETTIMEDOUT")
e.code = "ESOCKETTIMEDOUT"
self.emit("error", e)
}
})
}
}
self.req.on('error', self.clientErrorHandler)
self.req.on('drain', function() {
self.emit('drain')
})
self.on('end', function() {
if ( self.req.connection ) self.req.connection.removeListener('error', self._parserErrorHandler)
})
self.emit('request', self.req)
}
Request.prototype.abort = function () {
this._aborted = true
if (this.req) {
this.req.abort()
}
else if (this.response) {
this.response.abort()
}
this.emit("abort")
}
Request.prototype.pipeDest = function (dest) {
var response = this.response
// Called after the response is received
if (dest.headers) {
dest.headers['content-type'] = response.headers['content-type']
if (response.headers['content-length']) {
dest.headers['content-length'] = response.headers['content-length']
}
}
if (dest.setHeader) {
for (var i in response.headers) {
dest.setHeader(i, response.headers[i])
}
dest.statusCode = response.statusCode
}
if (this.pipefilter) this.pipefilter(response, dest)
}
// Composable API
Request.prototype.setHeader = function (name, value, clobber) {
if (clobber === undefined) clobber = true
if (clobber || !this.headers.hasOwnProperty(name)) this.headers[name] = value
else this.headers[name] += ',' + value
return this
}
Request.prototype.setHeaders = function (headers) {
for (var i in headers) {this.setHeader(i, headers[i])}
return this
}
Request.prototype.qs = function (q, clobber) {
var base
if (!clobber && this.uri.query) base = qs.parse(this.uri.query)
else base = {}
for (var i in q) {
base[i] = q[i]
}
this.uri = url.parse(this.uri.href.split('?')[0] + '?' + qs.stringify(base))
this.url = this.uri
return this
}
Request.prototype.form = function (form) {
if (form) {
this.headers['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8'
this.body = qs.stringify(form).toString('utf8')
return this
}
// create form-data object
this._form = new FormData()
return this._form
}
Request.prototype.multipart = function (multipart) {
var self = this
self.body = []
if (!self.headers['content-type']) {
self.headers['content-type'] = 'multipart/related; boundary=' + self.boundary
} else {
self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary
}
if (!multipart.forEach) throw new Error('Argument error, options.multipart.')
if (self.preambleCRLF) {
self.body.push(new Buffer('\r\n'))
}
multipart.forEach(function (part) {
var body = part.body
if(body == null) throw Error('Body attribute missing in multipart.')
delete part.body
var preamble = '--' + self.boundary + '\r\n'
Object.keys(part).forEach(function (key) {
preamble += key + ': ' + part[key] + '\r\n'
})
preamble += '\r\n'
self.body.push(new Buffer(preamble))
self.body.push(new Buffer(body))
self.body.push(new Buffer('\r\n'))
})
self.body.push(new Buffer('--' + self.boundary + '--'))
return self
}
Request.prototype.json = function (val) {
this.setHeader('accept', 'application/json')
this._json = true
if (typeof val === 'boolean') {
if (typeof this.body === 'object') {
this.setHeader('content-type', 'application/json')
this.body = JSON.stringify(this.body)
}
} else {
this.setHeader('content-type', 'application/json')
this.body = JSON.stringify(val)
}
return this
}
function getHeader(name, headers) {
var result, re, match
Object.keys(headers).forEach(function (key) {
re = new RegExp(name, 'i')
match = key.match(re)
if (match) result = headers[key]
})
return result
}
Request.prototype.aws = function (opts, now) {
if (!now) {
this._aws = opts
return this
}
var date = new Date()
this.setHeader('date', date.toUTCString())
var auth =
{ key: opts.key
, secret: opts.secret
, verb: this.method.toUpperCase()
, date: date
, contentType: getHeader('content-type', this.headers) || ''
, md5: getHeader('content-md5', this.headers) || ''
, amazonHeaders: aws.canonicalizeHeaders(this.headers)
}
if (opts.bucket && this.path) {
auth.resource = '/' + opts.bucket + this.path
} else if (opts.bucket && !this.path) {
auth.resource = '/' + opts.bucket
} else if (!opts.bucket && this.path) {
auth.resource = this.path
} else if (!opts.bucket && !this.path) {
auth.resource = '/'
}
auth.resource = aws.canonicalizeResource(auth.resource)
this.setHeader('authorization', aws.authorization(auth))
return this
}
Request.prototype.oauth = function (_oauth) {
var form
if (this.headers['content-type'] &&
this.headers['content-type'].slice(0, 'application/x-www-form-urlencoded'.length) ===
'application/x-www-form-urlencoded'
) {
form = qs.parse(this.body)
}
if (this.uri.query) {
form = qs.parse(this.uri.query)
}
if (!form) form = {}
var oa = {}
for (var i in form) oa[i] = form[i]
for (var i in _oauth) oa['oauth_'+i] = _oauth[i]
if (!oa.oauth_version) oa.oauth_version = '1.0'
if (!oa.oauth_timestamp) oa.oauth_timestamp = Math.floor( (new Date()).getTime() / 1000 ).toString()
if (!oa.oauth_nonce) oa.oauth_nonce = uuid().replace(/-/g, '')
oa.oauth_signature_method = 'HMAC-SHA1'
var consumer_secret = oa.oauth_consumer_secret
delete oa.oauth_consumer_secret
var token_secret = oa.oauth_token_secret
delete oa.oauth_token_secret
var baseurl = this.uri.protocol + '//' + this.uri.host + this.uri.pathname
var signature = oauth.hmacsign(this.method, baseurl, oa, consumer_secret, token_secret)
// oa.oauth_signature = signature
for (var i in form) {
if ( i.slice(0, 'oauth_') in _oauth) {
// skip
} else {
delete oa['oauth_'+i]
if (i !== 'x_auth_mode') delete oa[i]
}
}
this.headers.Authorization =
'OAuth '+Object.keys(oa).sort().map(function (i) {return i+'="'+oauth.rfc3986(oa[i])+'"'}).join(',')
this.headers.Authorization += ',oauth_signature="' + oauth.rfc3986(signature) + '"'
return this
}
Request.prototype.jar = function (jar) {
var cookies
if (this._redirectsFollowed === 0) {
this.originalCookieHeader = this.headers.cookie
}
if (jar === false) {
// disable cookies
cookies = false
this._disableCookies = true
} else if (jar) {
// fetch cookie from the user defined cookie jar
cookies = jar.get({ url: this.uri.href })
} else {
// fetch cookie from the global cookie jar
cookies = cookieJar.get({ url: this.uri.href })
}
if (cookies && cookies.length) {
var cookieString = cookies.map(function (c) {
return c.name + "=" + c.value
}).join("; ")
if (this.originalCookieHeader) {
// Don't overwrite existing Cookie header
this.headers.cookie = this.originalCookieHeader + '; ' + cookieString
} else {
this.headers.cookie = cookieString
}
}
this._jar = jar
return this
}
// Stream API
Request.prototype.pipe = function (dest, opts) {
if (this.response) {
if (this._destdata) {
throw new Error("You cannot pipe after data has been emitted from the response.")
} else if (this._ended) {
throw new Error("You cannot pipe after the response has been ended.")
} else {
stream.Stream.prototype.pipe.call(this, dest, opts)
this.pipeDest(dest)
return dest
}
} else {
this.dests.push(dest)
stream.Stream.prototype.pipe.call(this, dest, opts)
return dest
}
}
Request.prototype.write = function () {
if (!this._started) this.start()
return this.req.write.apply(this.req, arguments)
}
Request.prototype.end = function (chunk) {
if (chunk) this.write(chunk)
if (!this._started) this.start()
this.req.end()
}
Request.prototype.pause = function () {
if (!this.response) this._paused = true
else this.response.pause.apply(this.response, arguments)
}
Request.prototype.resume = function () {
if (!this.response) this._paused = false
else this.response.resume.apply(this.response, arguments)
}
Request.prototype.destroy = function () {
if (!this._ended) this.end()
}
// organize params for post, put, head, del
function initParams(uri, options, callback) {
if ((typeof options === 'function') && !callback) callback = options
if (options && typeof options === 'object') {
options.uri = uri
} else if (typeof uri === 'string') {
options = {uri:uri}
} else {
options = uri
uri = options.uri
}
return { uri: uri, options: options, callback: callback }
}
function request (uri, options, callback) {
if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.')
if ((typeof options === 'function') && !callback) callback = options
if (options && typeof options === 'object') {
options.uri = uri
} else if (typeof uri === 'string') {
options = {uri:uri}
} else {
options = uri
}
if (callback) options.callback = callback
var r = new Request(options)
return r
}
module.exports = request
request.initParams = initParams
request.defaults = function (options, requester) {
var def = function (method) {
var d = function (uri, opts, callback) {
var params = initParams(uri, opts, callback)
for (var i in options) {
if (params.options[i] === undefined) params.options[i] = options[i]
}
if(typeof requester === 'function') {
if(method === request) {
method = requester
} else {
params.options._requester = requester
}
}
return method(params.options, params.callback)
}
return d
}
var de = def(request)
de.get = def(request.get)
de.post = def(request.post)
de.put = def(request.put)
de.head = def(request.head)
de.del = def(request.del)
de.cookie = def(request.cookie)
de.jar = request.jar
return de
}
request.forever = function (agentOptions, optionsArg) {
var options = {}
if (optionsArg) {
for (option in optionsArg) {
options[option] = optionsArg[option]
}
}
if (agentOptions) options.agentOptions = agentOptions
options.forever = true
return request.defaults(options)
}
request.get = request
request.post = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'POST'
return request(params.uri || null, params.options, params.callback)
}
request.put = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'PUT'
return request(params.uri || null, params.options, params.callback)
}
request.head = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'HEAD'
if (params.options.body ||
params.options.requestBodyStream ||
(params.options.json && typeof params.options.json !== 'boolean') ||
params.options.multipart) {
throw new Error("HTTP HEAD requests MUST NOT include a request body.")
}
return request(params.uri || null, params.options, params.callback)
}
request.del = function (uri, options, callback) {
var params = initParams(uri, options, callback)
params.options.method = 'DELETE'
if(typeof params.options._requester === 'function') {
request = params.options._requester
}
return request(params.uri || null, params.options, params.callback)
}
request.jar = function () {
return new CookieJar
}
request.cookie = function (str) {
if (str && str.uri) str = str.uri
if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param")
return new Cookie(str)
}
// Safe toJSON
function getSafe (self, uuid) {
if (typeof self === 'object' || typeof self === 'function') var safe = {}
if (Array.isArray(self)) var safe = []
var recurse = []
Object.defineProperty(self, uuid, {})
var attrs = Object.keys(self).filter(function (i) {
if (i === uuid) return false
if ( (typeof self[i] !== 'object' && typeof self[i] !== 'function') || self[i] === null) return true
return !(Object.getOwnPropertyDescriptor(self[i], uuid))
})
for (var i=0;i<attrs.length;i++) {
if ( (typeof self[attrs[i]] !== 'object' && typeof self[attrs[i]] !== 'function') ||
self[attrs[i]] === null
) {
safe[attrs[i]] = self[attrs[i]]
} else {
recurse.push(attrs[i])
Object.defineProperty(self[attrs[i]], uuid, {})
}
}
for (var i=0;i<recurse.length;i++) {
safe[recurse[i]] = getSafe(self[recurse[i]], uuid)
}
return safe
}
function toJSON () {
return getSafe(this, (((1+Math.random())*0x10000)|0).toString(16))
}
Request.prototype.toJSON = toJSON
}).call(this,require('_process'),require("buffer").Buffer)
},{"./aws":3,"./forever":4,"./oauth":12,"./tunnel":13,"./uuid":14,"./vendor/cookie":15,"./vendor/cookie/jar":16,"_process":undefined,"buffer":undefined,"form-data":6,"http":undefined,"https":undefined,"mime":11,"querystring":undefined,"stream":undefined,"tls":undefined,"url":undefined,"util":undefined}],6:[function(require,module,exports){
(function (process,Buffer){
var CombinedStream = require('combined-stream');
var util = require('util');
var path = require('path');
var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var fs = require('fs');
var mime = require('mime');
var async = require('async');
module.exports = FormData;
function FormData() {
this._overheadLength = 0;
this._valueLength = 0;
this._lengthRetrievers = [];
CombinedStream.call(this);
}
util.inherits(FormData, CombinedStream);
FormData.LINE_BREAK = '\r\n';
FormData.prototype.append = function(field, value) {
var append = CombinedStream.prototype.append.bind(this);
// all that streamy business can't handle numbers
if (typeof value == 'number') value = ''+value;
var header = this._multiPartHeader(field, value);
var footer = this._multiPartFooter(field, value);
append(header);
append(value);
append(footer);
this._trackLength(header, value)
};
FormData.prototype._trackLength = function(header, value) {
var valueLength = 0;
if (Buffer.isBuffer(value)) {
valueLength = value.length;
} else if (typeof value === 'string') {
valueLength = Buffer.byteLength(value);
}
this._valueLength += valueLength;
this._overheadLength +=
Buffer.byteLength(header) +
+ FormData.LINE_BREAK.length;
// empty or ethier doesn't have path or not an http response
if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) {
return;
}
this._lengthRetrievers.push(function(next) {
// check if it's local file
if (value.hasOwnProperty('fd')) {
fs.stat(value.path, function(err, stat) {
if (err) {
next(err);
return;
}
next(null, stat.size);
});
// or http response
} else if (value.hasOwnProperty('httpVersion')) {
next(null, +value.headers['content-length']);
// or request stream http://github.com/mikeal/request
} else if (value.hasOwnProperty('httpModule')) {
// wait till response come back
value.on('response', function(response) {
value.pause();
next(null, +response.headers['content-length']);
});
value.resume();
// something else
} else {
next('Unknown stream');
}
});
};
FormData.prototype._multiPartHeader = function(field, value) {
var boundary = this.getBoundary();
var header =
'--' + boundary + FormData.LINE_BREAK +
'Content-Disposition: form-data; name="' + field + '"';
// fs- and request- streams have path property
// TODO: Use request's response mime-type
if (value.path) {
header +=
'; filename="' + path.basename(value.path) + '"' + FormData.LINE_BREAK +
'Content-Type: ' + mime.lookup(value.path);
// http response has not
} else if (value.readable && value.hasOwnProperty('httpVersion')) {
header +=
'; filename="' + path.basename(value.client._httpMessage.path) + '"' + FormData.LINE_BREAK +
'Content-Type: ' + value.headers['content-type'];
}
header += FormData.LINE_BREAK + FormData.LINE_BREAK;
return header;
};
FormData.prototype._multiPartFooter = function(field, value) {
return function(next) {
var footer = FormData.LINE_BREAK;
var lastPart = (this._streams.length === 0);
if (lastPart) {
footer += this._lastBoundary();
}
next(footer);
}.bind(this);
};
FormData.prototype._lastBoundary = function() {
return '--' + this.getBoundary() + '--';
};
FormData.prototype.getHeaders = function(userHeaders) {
var formHeaders = {
'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
};
for (var header in userHeaders) {
formHeaders[header.toLowerCase()] = userHeaders[header];
}
return formHeaders;
}
FormData.prototype.getCustomHeaders = function(contentType) {
contentType = contentType ? contentType : 'multipart/form-data';
var formHeaders = {
'content-type': contentType + '; boundary=' + this.getBoundary(),
'content-length': this.getLengthSync()
};
return formHeaders;
}
FormData.prototype.getBoundary = function() {
if (!this._boundary) {
this._generateBoundary();
}
return this._boundary;
};
FormData.prototype._generateBoundary = function() {
// This generates a 50 character boundary similar to those used by Firefox.
// They are optimized for boyer-moore parsing.
var boundary = '--------------------------';
for (var i = 0; i < 24; i++) {
boundary += Math.floor(Math.random() * 10).toString(16);
}
this._boundary = boundary;
};
FormData.prototype.getLengthSync = function() {
var knownLength = this._overheadLength + this._valueLength;
if (this._streams.length) {
knownLength += this._lastBoundary().length;
}
return knownLength;
};
FormData.prototype.getLength = function(cb) {
var knownLength = this._overheadLength + this._valueLength;
if (this._streams.length) {
knownLength += this._lastBoundary().length;
}
if (!this._lengthRetrievers.length) {
process.nextTick(cb.bind(this, null, knownLength));
return;
}
async.parallel(this._lengthRetrievers, function(err, values) {
if (err) {
cb(err);
return;
}
values.forEach(function(length) {
knownLength += length;
});
cb(null, knownLength);
});
};
FormData.prototype.submit = function(url, cb) {
this.getLength(function(err, length) {
var request
, parsedUrl = parseUrl(url)
, options = {
method: 'post',
port: parsedUrl.port || 80,
path: parsedUrl.pathname,
headers: this.getHeaders({'Content-Length': length}),
host: parsedUrl.hostname
};
if (parsedUrl.protocol == 'https:') {
// override default port
if (!parsedUrl.port) options.port = 443;
request = https.request(options);
} else {
request = http.request(options);
}
this.pipe(request);
if (cb) {
request.on('error', cb);
request.on('response', cb.bind(this, null));
}
return request;
}.bind(this));
};
}).call(this,require('_process'),require("buffer").Buffer)
},{"_process":undefined,"async":7,"buffer":undefined,"combined-stream":9,"fs":undefined,"http":undefined,"https":undefined,"mime":11,"path":undefined,"url":undefined,"util":undefined}],7:[function(require,module,exports){
// This file is just added for convenience so this repository can be
// directly checked out into a project's deps folder
module.exports = require('./lib/async');
},{"./lib/async":8}],8:[function(require,module,exports){
(function (process){
/*global setTimeout: false, console: false */
(function () {
var async = {};
// global on the server, window in the browser
var root = this,
previous_async = root.async;
if (typeof module !== 'undefined' && module.exports) {
module.exports = async;
}
else {
root.async = async;
}
async.noConflict = function () {
root.async = previous_async;
return async;
};
//// cross-browser compatiblity functions ////
var _forEach = function (arr, iterator) {
if (arr.forEach) {
return arr.forEach(iterator);
}
for (var i = 0; i < arr.length; i += 1) {
iterator(arr[i], i, arr);
}
};
var _map = function (arr, iterator) {
if (arr.map) {
return arr.map(iterator);
}
var results = [];
_forEach(arr, function (x, i, a) {
results.push(iterator(x, i, a));
});
return results;
};
var _reduce = function (arr, iterator, memo) {
if (arr.reduce) {
return arr.reduce(iterator, memo);
}
_forEach(arr, function (x, i, a) {
memo = iterator(memo, x, i, a);
});
return memo;
};
var _keys = function (obj) {
if (Object.keys) {
return Object.keys(obj);
}
var keys = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
keys.push(k);
}
}
return keys;
};
var _indexOf = function (arr, item) {
if (arr.indexOf) {
return arr.indexOf(item);
}
for (var i = 0; i < arr.length; i += 1) {
if (arr[i] === item) {
return i;
}
}
return -1;
};
//// exported async module functions ////
//// nextTick implementation with browser-compatible fallback ////
if (typeof process === 'undefined' || !(process.nextTick)) {
async.nextTick = function (fn) {
setTimeout(fn, 0);
};
}
else {
async.nextTick = process.nextTick;
}
async.forEach = function (arr, iterator, callback) {
if (!arr.length) {
return callback();
}
var completed = 0;
_forEach(arr, function (x) {
iterator(x, function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed === arr.length) {
callback();
}
}
});
});
};
async.forEachSeries = function (arr, iterator, callback) {
if (!arr.length) {
return callback();
}
var completed = 0;
var iterate = function () {
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed === arr.length) {
callback();
}
else {
iterate();
}
}
});
};
iterate();
};
var doParallel = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.forEach].concat(args));
};
};
var doSeries = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.forEachSeries].concat(args));
};
};
var _asyncMap = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (err, v) {
results[x.index] = v;
callback(err);
});
}, function (err) {
callback(err, results);
});
};
async.map = doParallel(_asyncMap);
async.mapSeries = doSeries(_asyncMap);
// reduce only has a series version, as doing reduce in parallel won't
// work in many situations.
async.reduce = function (arr, memo, iterator, callback) {
async.forEachSeries(arr, function (x, callback) {
iterator(memo, x, function (err, v) {
memo = v;
callback(err);
});
}, function (err) {
callback(err, memo);
});
};
// inject alias
async.inject = async.reduce;
// foldl alias
async.foldl = async.reduce;
async.reduceRight = function (arr, memo, iterator, callback) {
var reversed = _map(arr, function (x) {
return x;
}).reverse();
async.reduce(reversed, memo, iterator, callback);
};
// foldr alias
async.foldr = async.reduceRight;
var _filter = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.filter = doParallel(_filter);
async.filterSeries = doSeries(_filter);
// select alias
async.select = async.filter;
async.selectSeries = async.filterSeries;
var _reject = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (!v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.reject = doParallel(_reject);
async.rejectSeries = doSeries(_reject);
var _detect = function (eachfn, arr, iterator, main_callback) {
eachfn(arr, function (x, callback) {
iterator(x, function (result) {
if (result) {
main_callback(x);
}
else {
callback();
}
});
}, function (err) {
main_callback();
});
};
async.detect = doParallel(_detect);
async.detectSeries = doSeries(_detect);
async.some = function (arr, iterator, main_callback) {
async.forEach(arr, function (x, callback) {
iterator(x, function (v) {
if (v) {
main_callback(true);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(false);
});
};
// any alias
async.any = async.some;
async.every = function (arr, iterator, main_callback) {
async.forEach(arr, function (x, callback) {
iterator(x, function (v) {
if (!v) {
main_callback(false);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(true);
});
};
// all alias
async.all = async.every;
async.sortBy = function (arr, iterator, callback) {
async.map(arr, function (x, callback) {
iterator(x, function (err, criteria) {
if (err) {
callback(err);
}
else {
callback(null, {value: x, criteria: criteria});
}
});
}, function (err, results) {
if (err) {
return callback(err);
}
else {
var fn = function (left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
};
callback(null, _map(results.sort(fn), function (x) {
return x.value;
}));
}
});
};
async.auto = function (tasks, callback) {
callback = callback || function () {};
var keys = _keys(tasks);
if (!keys.length) {
return callback(null);
}
var completed = [];
var listeners = [];
var addListener = function (fn) {
listeners.unshift(fn);
};
var removeListener = function (fn) {
for (var i = 0; i < listeners.length; i += 1) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
return;
}
}
};
var taskComplete = function () {
_forEach(listeners, function (fn) {
fn();
});
};
addListener(function () {
if (completed.length === keys.length) {
callback(null);
}
});
_forEach(keys, function (k) {
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
var taskCallback = function (err) {
if (err) {
callback(err);
// stop subsequent errors hitting callback multiple times
callback = function () {};
}
else {
completed.push(k);
taskComplete();
}
};
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
var ready = function () {
return _reduce(requires, function (a, x) {
return (a && _indexOf(completed, x) !== -1);
}, true);
};
if (ready()) {
task[task.length - 1](taskCallback);
}
else {
var listener = function () {
if (ready()) {
removeListener(listener);
task[task.length - 1](taskCallback);
}
};
addListener(listener);
}
});
};
async.waterfall = function (tasks, callback) {
if (!tasks.length) {
return callback();
}
callback = callback || function () {};
var wrapIterator = function (iterator) {
return function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
var args = Array.prototype.slice.call(arguments, 1);
var next = iterator.next();
if (next) {
args.push(wrapIterator(next));
}
else {
args.push(callback);
}
async.nextTick(function () {
iterator.apply(null, args);
});
}
};
};
wrapIterator(async.iterator(tasks))();
};
async.parallel = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.map(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
async.forEach(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.series = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.mapSeries(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
async.forEachSeries(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.iterator = function (tasks) {
var makeCallback = function (index) {
var fn = function () {
if (tasks.length) {
tasks[index].apply(null, arguments);
}
return fn.next();
};
fn.next = function () {
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
};
return fn;
};
return makeCallback(0);
};
async.apply = function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
return fn.apply(
null, args.concat(Array.prototype.slice.call(arguments))
);
};
};
var _concat = function (eachfn, arr, fn, callback) {
var r = [];
eachfn(arr, function (x, cb) {
fn(x, function (err, y) {
r = r.concat(y || []);
cb(err);
});
}, function (err) {
callback(err, r);
});
};
async.concat = doParallel(_concat);
async.concatSeries = doSeries(_concat);
async.whilst = function (test, iterator, callback) {
if (test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
async.whilst(test, iterator, callback);
});
}
else {
callback();
}
};
async.until = function (test, iterator, callback) {
if (!test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
async.until(test, iterator, callback);
});
}
else {
callback();
}
};
async.queue = function (worker, concurrency) {
var workers = 0;
var tasks = [];
var q = {
concurrency: concurrency,
saturated: null,
empty: null,
drain: null,
push: function (data, callback) {
tasks.push({data: data, callback: callback});
if(q.saturated && tasks.length == concurrency) q.saturated();
async.nextTick(q.process);
},
process: function () {
if (workers < q.concurrency && tasks.length) {
var task = tasks.splice(0, 1)[0];
if(q.empty && tasks.length == 0) q.empty();
workers += 1;
worker(task.data, function () {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if(q.drain && tasks.length + workers == 0) q.drain();
q.process();
});
}
},
length: function () {
return tasks.length;
},
running: function () {
return workers;
}
};
return q;
};
var _console_fn = function (name) {
return function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
fn.apply(null, args.concat([function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (typeof console !== 'undefined') {
if (err) {
if (console.error) {
console.error(err);
}
}
else if (console[name]) {
_forEach(args, function (x) {
console[name](x);
});
}
}
}]));
};
};
async.log = _console_fn('log');
async.dir = _console_fn('dir');
/*async.info = _console_fn('info');
async.warn = _console_fn('warn');
async.error = _console_fn('error');*/
async.memoize = function (fn, hasher) {
var memo = {};
hasher = hasher || function (x) {
return x;
};
return function () {
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
var key = hasher.apply(null, args);
if (key in memo) {
callback.apply(null, memo[key]);
}
else {
fn.apply(null, args.concat([function () {
memo[key] = arguments;
callback.apply(null, arguments);
}]));
}
};
};
}());
}).call(this,require('_process'))
},{"_process":undefined}],9:[function(require,module,exports){
(function (Buffer){
var util = require('util');
var Stream = require('stream').Stream;
var DelayedStream = require('delayed-stream');
module.exports = CombinedStream;
function CombinedStream() {
this.writable = false;
this.readable = true;
this.dataSize = 0;
this.maxDataSize = 2 * 1024 * 1024;
this.pauseStreams = true;
this._released = false;
this._streams = [];
this._currentStream = null;
}
util.inherits(CombinedStream, Stream);
CombinedStream.create = function(options) {
var combinedStream = new this();
options = options || {};
for (var option in options) {
combinedStream[option] = options[option];
}
return combinedStream;
};
CombinedStream.isStreamLike = function(stream) {
return (typeof stream !== 'function')
&& (typeof stream !== 'string')
&& (!Buffer.isBuffer(stream));
};
CombinedStream.prototype.append = function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
if (!(stream instanceof DelayedStream)) {
stream.on('data', this._checkDataSize.bind(this));
stream = DelayedStream.create(stream, {
maxDataSize: Infinity,
pauseStream: this.pauseStreams,
});
}
this._handleErrors(stream);
if (this.pauseStreams) {
stream.pause();
}
}
this._streams.push(stream);
return this;
};
CombinedStream.prototype.pipe = function(dest, options) {
Stream.prototype.pipe.call(this, dest, options);
this.resume();
};
CombinedStream.prototype._getNext = function() {
this._currentStream = null;
var stream = this._streams.shift();
if (!stream) {
this.end();
return;
}
if (typeof stream !== 'function') {
this._pipeNext(stream);
return;
}
var getStream = stream;
getStream(function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('data', this._checkDataSize.bind(this));
this._handleErrors(stream);
}
this._pipeNext(stream);
}.bind(this));
};
CombinedStream.prototype._pipeNext = function(stream) {
this._currentStream = stream;
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('end', this._getNext.bind(this))
stream.pipe(this, {end: false});
return;
}
var value = stream;
this.write(value);
this._getNext();
};
CombinedStream.prototype._handleErrors = function(stream) {
var self = this;
stream.on('error', function(err) {
self._emitError(err);
});
};
CombinedStream.prototype.write = function(data) {
this.emit('data', data);
};
CombinedStream.prototype.pause = function() {
if (!this.pauseStreams) {
return;
}
this.emit('pause');
};
CombinedStream.prototype.resume = function() {
if (!this._released) {
this._released = true;
this.writable = true;
this._getNext();
}
this.emit('resume');
};
CombinedStream.prototype.end = function() {
this._reset();
this.emit('end');
};
CombinedStream.prototype.destroy = function() {
this._reset();
this.emit('close');
};
CombinedStream.prototype._reset = function() {
this.writable = false;
this._streams = [];
this._currentStream = null;
};
CombinedStream.prototype._checkDataSize = function() {
this._updateDataSize();
if (this.dataSize <= this.maxDataSize) {
return;
}
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
this._emitError(new Error(message));
};
CombinedStream.prototype._updateDataSize = function() {
this.dataSize = 0;
var self = this;
this._streams.forEach(function(stream) {
if (!stream.dataSize) {
return;
}
self.dataSize += stream.dataSize;
});
if (this._currentStream && this._currentStream.dataSize) {
this.dataSize += this._currentStream.dataSize;
}
};
CombinedStream.prototype._emitError = function(err) {
this._reset();
this.emit('error', err);
};
}).call(this,{"isBuffer":require("../../../../../../../../../../../work/webtask-pen/node_modules/is-buffer/index.js")})
},{"../../../../../../../../../../../work/webtask-pen/node_modules/is-buffer/index.js":20,"delayed-stream":10,"stream":undefined,"util":undefined}],10:[function(require,module,exports){
var Stream = require('stream').Stream;
var util = require('util');
module.exports = DelayedStream;
function DelayedStream() {
this.source = null;
this.dataSize = 0;
this.maxDataSize = 1024 * 1024;
this.pauseStream = true;
this._maxDataSizeExceeded = false;
this._released = false;
this._bufferedEvents = [];
}
util.inherits(DelayedStream, Stream);
DelayedStream.create = function(source, options) {
var delayedStream = new this();
options = options || {};
for (var option in options) {
delayedStream[option] = options[option];
}
delayedStream.source = source;
var realEmit = source.emit;
source.emit = function() {
delayedStream._handleEmit(arguments);
return realEmit.apply(source, arguments);
};
source.on('error', function() {});
if (delayedStream.pauseStream) {
source.pause();
}
return delayedStream;
};
DelayedStream.prototype.__defineGetter__('readable', function() {
return this.source.readable;
});
DelayedStream.prototype.resume = function() {
if (!this._released) {
this.release();
}
this.source.resume();
};
DelayedStream.prototype.pause = function() {
this.source.pause();
};
DelayedStream.prototype.release = function() {
this._released = true;
this._bufferedEvents.forEach(function(args) {
this.emit.apply(this, args);
}.bind(this));
this._bufferedEvents = [];
};
DelayedStream.prototype.pipe = function() {
var r = Stream.prototype.pipe.apply(this, arguments);
this.resume();
return r;
};
DelayedStream.prototype._handleEmit = function(args) {
if (this._released) {
this.emit.apply(this, args);
return;
}
if (args[0] === 'data') {
this.dataSize += args[1].length;
this._checkIfMaxDataSizeExceeded();
}
this._bufferedEvents.push(args);
};
DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
if (this._maxDataSizeExceeded) {
return;
}
if (this.dataSize <= this.maxDataSize) {
return;
}
this._maxDataSizeExceeded = true;
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
this.emit('error', new Error(message));
};
},{"stream":undefined,"util":undefined}],11:[function(require,module,exports){
(function (__dirname){
var path = require('path');
var fs = require('fs');
function Mime() {
// Map of extension -> mime type
this.types = Object.create(null);
// Map of mime type -> extension
this.extensions = Object.create(null);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* @param map (Object) type definitions
*/
Mime.prototype.define = function (map) {
for (var type in map) {
var exts = map[type];
for (var i = 0; i < exts.length; i++) {
this.types[exts[i]] = type;
}
// Default extension is the first one we encounter
if (!this.extensions[type]) {
this.extensions[type] = exts[0];
}
}
};
/**
* Load an Apache2-style ".types" file
*
* This may be called multiple times (it's expected). Where files declare
* overlapping types/extensions, the last file wins.
*
* @param file (String) path of file to load.
*/
Mime.prototype.load = function(file) {
// Read file and split into lines
var map = {},
content = fs.readFileSync(file, 'ascii'),
lines = content.split(/[\r\n]+/);
lines.forEach(function(line) {
// Clean up whitespace/comments, and split into fields
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
map[fields.shift()] = fields;
});
this.define(map);
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.lookup = function(path, fallback) {
var ext = path.replace(/.*[\.\/]/, '').toLowerCase();
return this.types[ext] || fallback || this.default_type;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.extension = function(mimeType) {
return this.extensions[mimeType];
};
// Default instance
var mime = new Mime();
// Load local copy of
// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
mime.load(path.join(__dirname, 'types/mime.types'));
// Load additional types from node.js community
mime.load(path.join(__dirname, 'types/node.types'));
// Default type
mime.default_type = mime.lookup('bin');
//
// Additional API specific to the default instance
//
mime.Mime = Mime;
/**
* Lookup a charset based on mime type.
*/
mime.charsets = {
lookup: function(mimeType, fallback) {
// Assume text types are utf8
return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
}
}
module.exports = mime;
}).call(this,"/node_modules\\request\\node_modules\\mime")
},{"fs":undefined,"path":undefined}],12:[function(require,module,exports){
var crypto = require('crypto')
, qs = require('querystring')
;
function sha1 (key, body) {
return crypto.createHmac('sha1', key).update(body).digest('base64')
}
function rfc3986 (str) {
return encodeURIComponent(str)
.replace(/!/g,'%21')
.replace(/\*/g,'%2A')
.replace(/\(/g,'%28')
.replace(/\)/g,'%29')
.replace(/'/g,'%27')
;
}
function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) {
// adapted from https://dev.twitter.com/docs/auth/oauth and
// https://dev.twitter.com/docs/auth/creating-signature
var querystring = Object.keys(params).sort().map(function(key){
// big WTF here with the escape + encoding but it's what twitter wants
return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key]))
}).join('%26')
var base = [
httpMethod ? httpMethod.toUpperCase() : 'GET',
rfc3986(base_uri),
querystring
].join('&')
var key = [
consumer_secret,
token_secret || ''
].map(rfc3986).join('&')
return sha1(key, base)
}
exports.hmacsign = hmacsign
exports.rfc3986 = rfc3986
},{"crypto":undefined,"querystring":undefined}],13:[function(require,module,exports){
(function (process,Buffer){
'use strict'
var net = require('net')
, tls = require('tls')
, http = require('http')
, https = require('https')
, events = require('events')
, assert = require('assert')
, util = require('util')
;
exports.httpOverHttp = httpOverHttp
exports.httpsOverHttp = httpsOverHttp
exports.httpOverHttps = httpOverHttps
exports.httpsOverHttps = httpsOverHttps
function httpOverHttp(options) {
var agent = new TunnelingAgent(options)
agent.request = http.request
return agent
}
function httpsOverHttp(options) {
var agent = new TunnelingAgent(options)
agent.request = http.request
agent.createSocket = createSecureSocket
return agent
}
function httpOverHttps(options) {
var agent = new TunnelingAgent(options)
agent.request = https.request
return agent
}
function httpsOverHttps(options) {
var agent = new TunnelingAgent(options)
agent.request = https.request
agent.createSocket = createSecureSocket
return agent
}
function TunnelingAgent(options) {
var self = this
self.options = options || {}
self.proxyOptions = self.options.proxy || {}
self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets
self.requests = []
self.sockets = []
self.on('free', function onFree(socket, host, port) {
for (var i = 0, len = self.requests.length; i < len; ++i) {
var pending = self.requests[i]
if (pending.host === host && pending.port === port) {
// Detect the request to connect same origin server,
// reuse the connection.
self.requests.splice(i, 1)
pending.request.onSocket(socket)
return
}
}
socket.destroy()
self.removeSocket(socket)
})
}
util.inherits(TunnelingAgent, events.EventEmitter)
TunnelingAgent.prototype.addRequest = function addRequest(req, host, port) {
var self = this
if (self.sockets.length >= this.maxSockets) {
// We are over limit so we'll add it to the queue.
self.requests.push({host: host, port: port, request: req})
return
}
// If we are under maxSockets create a new one.
self.createSocket({host: host, port: port, request: req}, function(socket) {
socket.on('free', onFree)
socket.on('close', onCloseOrRemove)
socket.on('agentRemove', onCloseOrRemove)
req.onSocket(socket)
function onFree() {
self.emit('free', socket, host, port)
}
function onCloseOrRemove(err) {
self.removeSocket()
socket.removeListener('free', onFree)
socket.removeListener('close', onCloseOrRemove)
socket.removeListener('agentRemove', onCloseOrRemove)
}
})
}
TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
var self = this
var placeholder = {}
self.sockets.push(placeholder)
var connectOptions = mergeOptions({}, self.proxyOptions,
{ method: 'CONNECT'
, path: options.host + ':' + options.port
, agent: false
}
)
if (connectOptions.proxyAuth) {
connectOptions.headers = connectOptions.headers || {}
connectOptions.headers['Proxy-Authorization'] = 'Basic ' +
new Buffer(connectOptions.proxyAuth).toString('base64')
}
debug('making CONNECT request')
var connectReq = self.request(connectOptions)
connectReq.useChunkedEncodingByDefault = false // for v0.6
connectReq.once('response', onResponse) // for v0.6
connectReq.once('upgrade', onUpgrade) // for v0.6
connectReq.once('connect', onConnect) // for v0.7 or later
connectReq.once('error', onError)
connectReq.end()
function onResponse(res) {
// Very hacky. This is necessary to avoid http-parser leaks.
res.upgrade = true
}
function onUpgrade(res, socket, head) {
// Hacky.
process.nextTick(function() {
onConnect(res, socket, head)
})
}
function onConnect(res, socket, head) {
connectReq.removeAllListeners()
socket.removeAllListeners()
if (res.statusCode === 200) {
assert.equal(head.length, 0)
debug('tunneling connection has established')
self.sockets[self.sockets.indexOf(placeholder)] = socket
cb(socket)
} else {
debug('tunneling socket could not be established, statusCode=%d', res.statusCode)
var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode)
error.code = 'ECONNRESET'
options.request.emit('error', error)
self.removeSocket(placeholder)
}
}
function onError(cause) {
connectReq.removeAllListeners()
debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack)
var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message)
error.code = 'ECONNRESET'
options.request.emit('error', error)
self.removeSocket(placeholder)
}
}
TunnelingAgent.prototype.removeSocket = function removeSocket(socket) {
var pos = this.sockets.indexOf(socket)
if (pos === -1) return
this.sockets.splice(pos, 1)
var pending = this.requests.shift()
if (pending) {
// If we have pending requests and a socket gets closed a new one
// needs to be created to take over in the pool for the one that closed.
this.createSocket(pending, function(socket) {
pending.request.onSocket(socket)
})
}
}
function createSecureSocket(options, cb) {
var self = this
TunnelingAgent.prototype.createSocket.call(self, options, function(socket) {
// 0 is dummy port for v0.6
var secureSocket = tls.connect(0, mergeOptions({}, self.options,
{ servername: options.host
, socket: socket
}
))
cb(secureSocket)
})
}
function mergeOptions(target) {
for (var i = 1, len = arguments.length; i < len; ++i) {
var overrides = arguments[i]
if (typeof overrides === 'object') {
var keys = Object.keys(overrides)
for (var j = 0, keyLen = keys.length; j < keyLen; ++j) {
var k = keys[j]
if (overrides[k] !== undefined) {
target[k] = overrides[k]
}
}
}
}
return target
}
var debug
if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) {
debug = function() {
var args = Array.prototype.slice.call(arguments)
if (typeof args[0] === 'string') {
args[0] = 'TUNNEL: ' + args[0]
} else {
args.unshift('TUNNEL:')
}
console.error.apply(console, args)
}
} else {
debug = function() {}
}
exports.debug = debug // for test
}).call(this,require('_process'),require("buffer").Buffer)
},{"_process":undefined,"assert":undefined,"buffer":undefined,"events":undefined,"http":undefined,"https":undefined,"net":undefined,"tls":undefined,"util":undefined}],14:[function(require,module,exports){
module.exports = function () {
var s = [], itoh = '0123456789ABCDEF'
// Make array of random hex digits. The UUID only has 32 digits in it, but we
// allocate an extra items to make room for the '-'s we'll be inserting.
for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10)
// Conform to RFC-4122, section 4.4
s[14] = 4; // Set 4 high bits of time_high field to version
s[19] = (s[19] & 0x3) | 0x8 // Specify 2 high bits of clock sequence
// Convert to hex chars
for (var i = 0; i <36; i++) s[i] = itoh[s[i]]
// Insert '-'s
s[8] = s[13] = s[18] = s[23] = '-'
return s.join('')
}
},{}],15:[function(require,module,exports){
/*!
* Tobi - Cookie
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var url = require('url');
/**
* Initialize a new `Cookie` with the given cookie `str` and `req`.
*
* @param {String} str
* @param {IncomingRequest} req
* @api private
*/
var Cookie = exports = module.exports = function Cookie(str, req) {
this.str = str;
// Map the key/val pairs
str.split(/ *; */).reduce(function(obj, pair){
var p = pair.indexOf('=');
var key = p > 0 ? pair.substring(0, p).trim() : pair.trim();
var lowerCasedKey = key.toLowerCase();
var value = p > 0 ? pair.substring(p + 1).trim() : true;
if (!obj.name) {
// First key is the name
obj.name = key;
obj.value = value;
}
else if (lowerCasedKey === 'httponly') {
obj.httpOnly = value;
}
else {
obj[lowerCasedKey] = value;
}
return obj;
}, this);
// Expires
this.expires = this.expires
? new Date(this.expires)
: Infinity;
// Default or trim path
this.path = this.path
? this.path.trim(): req
? url.parse(req.url).pathname: '/';
};
/**
* Return the original cookie string.
*
* @return {String}
* @api public
*/
Cookie.prototype.toString = function(){
return this.str;
};
},{"url":undefined}],16:[function(require,module,exports){
/*!
* Tobi - CookieJar
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var url = require('url');
/**
* Initialize a new `CookieJar`.
*
* @api private
*/
var CookieJar = exports = module.exports = function CookieJar() {
this.cookies = [];
};
/**
* Add the given `cookie` to the jar.
*
* @param {Cookie} cookie
* @api private
*/
CookieJar.prototype.add = function(cookie){
this.cookies = this.cookies.filter(function(c){
// Avoid duplication (same path, same name)
return !(c.name == cookie.name && c.path == cookie.path);
});
this.cookies.push(cookie);
};
/**
* Get cookies for the given `req`.
*
* @param {IncomingRequest} req
* @return {Array}
* @api private
*/
CookieJar.prototype.get = function(req){
var path = url.parse(req.url).pathname
, now = new Date
, specificity = {};
return this.cookies.filter(function(cookie){
if (0 == path.indexOf(cookie.path) && now < cookie.expires
&& cookie.path.length > (specificity[cookie.name] || 0))
return specificity[cookie.name] = cookie.path.length;
});
};
/**
* Return Cookie string for the given `req`.
*
* @param {IncomingRequest} req
* @return {String}
* @api private
*/
CookieJar.prototype.cookieString = function(req){
var cookies = this.get(req);
if (cookies.length) {
return cookies.map(function(cookie){
return cookie.name + '=' + cookie.value;
}).join('; ');
}
};
},{"url":undefined}],17:[function(require,module,exports){
// Generated by CoffeeScript 1.3.3
(function() {
var XMLBuilder, XMLFragment,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
XMLFragment = require('./XMLFragment');
XMLBuilder = (function() {
function XMLBuilder(name, xmldec, doctype, options) {
this.assertLegalChar = __bind(this.assertLegalChar, this);
var att, child, _ref;
this.children = [];
this.rootObject = null;
if (this.is(name, 'Object')) {
_ref = [name, xmldec], xmldec = _ref[0], doctype = _ref[1];
name = null;
}
if (name != null) {
name = '' + name || '';
if (xmldec == null) {
xmldec = {
'version': '1.0'
};
}
}
this.allowSurrogateChars = options != null ? options.allowSurrogateChars : void 0;
if ((xmldec != null) && !(xmldec.version != null)) {
throw new Error("Version number is required");
}
if (xmldec != null) {
xmldec.version = '' + xmldec.version || '';
if (!xmldec.version.match(/1\.[0-9]+/)) {
throw new Error("Invalid version number: " + xmldec.version);
}
att = {
version: xmldec.version
};
if (xmldec.encoding != null) {
xmldec.encoding = '' + xmldec.encoding || '';
if (!xmldec.encoding.match(/[A-Za-z](?:[A-Za-z0-9._-]|-)*/)) {
throw new Error("Invalid encoding: " + xmldec.encoding);
}
att.encoding = xmldec.encoding;
}
if (xmldec.standalone != null) {
att.standalone = xmldec.standalone ? "yes" : "no";
}
child = new XMLFragment(this, '?xml', att);
this.children.push(child);
}
if (doctype != null) {
att = {};
if (name != null) {
att.name = name;
}
if (doctype.ext != null) {
doctype.ext = '' + doctype.ext || '';
att.ext = doctype.ext;
}
child = new XMLFragment(this, '!DOCTYPE', att);
this.children.push(child);
}
if (name != null) {
this.begin(name);
}
}
XMLBuilder.prototype.begin = function(name, xmldec, doctype) {
var doc, root;
if (!(name != null)) {
throw new Error("Root element needs a name");
}
if (this.rootObject) {
this.children = [];
this.rootObject = null;
}
if (xmldec != null) {
doc = new XMLBuilder(name, xmldec, doctype);
return doc.root();
}
name = '' + name || '';
root = new XMLFragment(this, name, {});
root.isRoot = true;
root.documentObject = this;
this.children.push(root);
this.rootObject = root;
return root;
};
XMLBuilder.prototype.root = function() {
return this.rootObject;
};
XMLBuilder.prototype.end = function(options) {
return toString(options);
};
XMLBuilder.prototype.toString = function(options) {
var child, r, _i, _len, _ref;
r = '';
_ref = this.children;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
child = _ref[_i];
r += child.toString(options);
}
return r;
};
XMLBuilder.prototype.is = function(obj, type) {
var clas;
clas = Object.prototype.toString.call(obj).slice(8, -1);
return (obj != null) && clas === type;
};
XMLBuilder.prototype.assertLegalChar = function(str) {
var chars, chr;
if (this.allowSurrogateChars) {
chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uFFFE-\uFFFF]/;
} else {
chars = /[\u0000-\u0008\u000B-\u000C\u000E-\u001F\uD800-\uDFFF\uFFFE-\uFFFF]/;
}
chr = str.match(chars);
if (chr) {
throw new Error("Invalid character (" + chr + ") in string: " + str + " at index " + chr.index);
}
};
return XMLBuilder;
})();
module.exports = XMLBuilder;
}).call(this);
},{"./XMLFragment":18}],18:[function(require,module,exports){
// Generated by CoffeeScript 1.3.3
(function() {
var XMLFragment,
__hasProp = {}.hasOwnProperty;
XMLFragment = (function() {
function XMLFragment(parent, name, attributes, text) {
this.isRoot = false;
this.documentObject = null;
this.parent = parent;
this.name = name;
this.attributes = attributes;
this.value = text;
this.children = [];
this.assertLegalChar = parent.assertLegalChar;
}
XMLFragment.prototype.element = function(name, attributes, text) {
var child, key, val, _ref, _ref1;
if (!(name != null)) {
throw new Error("Missing element name");
}
name = '' + name || '';
this.assertLegalChar(name);
if (attributes == null) {
attributes = {};
}
if (this.is(attributes, 'String') && this.is(text, 'Object')) {
_ref = [text, attributes], attributes = _ref[0], text = _ref[1];
} else if (this.is(attributes, 'String')) {
_ref1 = [{}, attributes], attributes = _ref1[0], text = _ref1[1];
}
for (key in attributes) {
if (!__hasProp.call(attributes, key)) continue;
val = attributes[key];
val = '' + val || '';
attributes[key] = this.escape(val);
}
child = new XMLFragment(this, name, attributes);
if (text != null) {
text = '' + text || '';
text = this.escape(text);
this.assertLegalChar(text);
child.raw(text);
}
this.children.push(child);
return child;
};
XMLFragment.prototype.insertBefore = function(name, attributes, text) {
var child, i, key, val, _ref, _ref1;
if (this.isRoot) {
throw new Error("Cannot insert elements at root level");
}
if (!(name != null)) {
throw new Error("Missing element name");
}
name = '' + name || '';
this.assertLegalChar(name);
if (attributes == null) {
attributes = {};
}
if (this.is(attributes, 'String') && this.is(text, 'Object')) {
_ref = [text, attributes], attributes = _ref[0], text = _ref[1];
} else if (this.is(attributes, 'String')) {
_ref1 = [{}, attributes], attributes = _ref1[0], text = _ref1[1];
}
for (key in attributes) {
if (!__hasProp.call(attributes, key)) continue;
val = attributes[key];
val = '' + val || '';
attributes[key] = this.escape(val);
}
child = new XMLFragment(this.parent, name, attributes);
if (text != null) {
text = '' + text || '';
text = this.escape(text);
this.assertLegalChar(text);
child.raw(text);
}
i = this.parent.children.indexOf(this);
this.parent.children.splice(i, 0, child);
return child;
};
XMLFragment.prototype.insertAfter = function(name, attributes, text) {
var child, i, key, val, _ref, _ref1;
if (this.isRoot) {
throw new Error("Cannot insert elements at root level");
}
if (!(name != null)) {
throw new Error("Missing element name");
}
name = '' + name || '';
this.assertLegalChar(name);
if (attributes == null) {
attributes = {};
}
if (this.is(attributes, 'String') && this.is(text, 'Object')) {
_ref = [text, attributes], attributes = _ref[0], text = _ref[1];
} else if (this.is(attributes, 'String')) {
_ref1 = [{}, attributes], attributes = _ref1[0], text = _ref1[1];
}
for (key in attributes) {
if (!__hasProp.call(attributes, key)) continue;
val = attributes[key];
val = '' + val || '';
attributes[key] = this.escape(val);
}
child = new XMLFragment(this.parent, name, attributes);
if (text != null) {
text = '' + text || '';
text = this.escape(text);
this.assertLegalChar(text);
child.raw(text);
}
i = this.parent.children.indexOf(this);
this.parent.children.splice(i + 1, 0, child);
return child;
};
XMLFragment.prototype.remove = function() {
var i, _ref;
if (this.isRoot) {
throw new Error("Cannot remove the root element");
}
i = this.parent.children.indexOf(this);
[].splice.apply(this.parent.children, [i, i - i + 1].concat(_ref = [])), _ref;
return this.parent;
};
XMLFragment.prototype.text = function(value) {
var child;
if (!(value != null)) {
throw new Error("Missing element text");
}
value = '' + value || '';
value = this.escape(value);
this.assertLegalChar(value);
child = new XMLFragment(this, '', {}, value);
this.children.push(child);
return this;
};
XMLFragment.prototype.cdata = function(value) {
var child;
if (!(value != null)) {
throw new Error("Missing CDATA text");
}
value = '' + value || '';
this.assertLegalChar(value);
if (value.match(/]]>/)) {
throw new Error("Invalid CDATA text: " + value);
}
child = new XMLFragment(this, '', {}, '<![CDATA[' + value + ']]>');
this.children.push(child);
return this;
};
XMLFragment.prototype.comment = function(value) {
var child;
if (!(value != null)) {
throw new Error("Missing comment text");
}
value = '' + value || '';
value = this.escape(value);
this.assertLegalChar(value);
if (value.match(/--/)) {
throw new Error("Comment text cannot contain double-hypen: " + value);
}
child = new XMLFragment(this, '', {}, '<!-- ' + value + ' -->');
this.children.push(child);
return this;
};
XMLFragment.prototype.raw = function(value) {
var child;
if (!(value != null)) {
throw new Error("Missing raw text");
}
value = '' + value || '';
child = new XMLFragment(this, '', {}, value);
this.children.push(child);
return this;
};
XMLFragment.prototype.up = function() {
if (this.isRoot) {
throw new Error("This node has no parent. Use doc() if you need to get the document object.");
}
return this.parent;
};
XMLFragment.prototype.root = function() {
var child;
if (this.isRoot) {
return this;
}
child = this.parent;
while (!child.isRoot) {
child = child.parent;
}
return child;
};
XMLFragment.prototype.document = function() {
return this.root().documentObject;
};
XMLFragment.prototype.end = function(options) {
return this.document().toString(options);
};
XMLFragment.prototype.prev = function() {
var i;
if (this.isRoot) {
throw new Error("Root node has no siblings");
}
i = this.parent.children.indexOf(this);
if (i < 1) {
throw new Error("Already at the first node");
}
return this.parent.children[i - 1];
};
XMLFragment.prototype.next = function() {
var i;
if (this.isRoot) {
throw new Error("Root node has no siblings");
}
i = this.parent.children.indexOf(this);
if (i === -1 || i === this.parent.children.length - 1) {
throw new Error("Already at the last node");
}
return this.parent.children[i + 1];
};
XMLFragment.prototype.clone = function(deep) {
var clonedSelf;
clonedSelf = new XMLFragment(this.parent, this.name, this.attributes, this.value);
if (deep) {
this.children.forEach(function(child) {
var clonedChild;
clonedChild = child.clone(deep);
clonedChild.parent = clonedSelf;
return clonedSelf.children.push(clonedChild);
});
}
return clonedSelf;
};
XMLFragment.prototype.importXMLBuilder = function(xmlbuilder) {
var clonedRoot;
clonedRoot = xmlbuilder.root().clone(true);
clonedRoot.parent = this;
this.children.push(clonedRoot);
clonedRoot.isRoot = false;
return this;
};
XMLFragment.prototype.attribute = function(name, value) {
var _ref;
if (!(name != null)) {
throw new Error("Missing attribute name");
}
if (!(value != null)) {
throw new Error("Missing attribute value");
}
name = '' + name || '';
value = '' + value || '';
if ((_ref = this.attributes) == null) {
this.attributes = {};
}
this.attributes[name] = this.escape(value);
return this;
};
XMLFragment.prototype.removeAttribute = function(name) {
if (!(name != null)) {
throw new Error("Missing attribute name");
}
name = '' + name || '';
delete this.attributes[name];
return this;
};
XMLFragment.prototype.toString = function(options, level) {
var attName, attValue, child, indent, newline, pretty, r, space, _i, _len, _ref, _ref1;
pretty = (options != null) && options.pretty || false;
indent = (options != null) && options.indent || ' ';
newline = (options != null) && options.newline || '\n';
level || (level = 0);
space = new Array(level + 1).join(indent);
r = '';
if (pretty) {
r += space;
}
if (!(this.value != null)) {
r += '<' + this.name;
} else {
r += '' + this.value;
}
_ref = this.attributes;
for (attName in _ref) {
if (!__hasProp.call(_ref, attName)) continue;
attValue = _ref[attName];
if (this.name === '!DOCTYPE') {
r += ' ' + attValue;
} else {
r += ' ' + attName + '="' + attValue + '"';
}
}
if (this.children.length === 0) {
if (!(this.value != null)) {
r += this.name === '?xml' ? '?>' : this.name === '!DOCTYPE' ? '>' : '/>';
}
if (pretty) {
r += newline;
}
} else if (pretty && this.children.length === 1 && (this.children[0].value != null)) {
r += '>';
r += this.children[0].value;
r += '</' + this.name + '>';
r += newline;
} else {
r += '>';
if (pretty) {
r += newline;
}
_ref1 = this.children;
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
child = _ref1[_i];
r += child.toString(options, level + 1);
}
if (pretty) {
r += space;
}
r += '</' + this.name + '>';
if (pretty) {
r += newline;
}
}
return r;
};
XMLFragment.prototype.escape = function(str) {
return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/'/g, '&apos;').replace(/"/g, '&quot;');
};
XMLFragment.prototype.is = function(obj, type) {
var clas;
clas = Object.prototype.toString.call(obj).slice(8, -1);
return (obj != null) && clas === type;
};
XMLFragment.prototype.ele = function(name, attributes, text) {
return this.element(name, attributes, text);
};
XMLFragment.prototype.txt = function(value) {
return this.text(value);
};
XMLFragment.prototype.dat = function(value) {
return this.cdata(value);
};
XMLFragment.prototype.att = function(name, value) {
return this.attribute(name, value);
};
XMLFragment.prototype.com = function(value) {
return this.comment(value);
};
XMLFragment.prototype.doc = function() {
return this.document();
};
XMLFragment.prototype.e = function(name, attributes, text) {
return this.element(name, attributes, text);
};
XMLFragment.prototype.t = function(value) {
return this.text(value);
};
XMLFragment.prototype.d = function(value) {
return this.cdata(value);
};
XMLFragment.prototype.a = function(name, value) {
return this.attribute(name, value);
};
XMLFragment.prototype.c = function(value) {
return this.comment(value);
};
XMLFragment.prototype.r = function(value) {
return this.raw(value);
};
XMLFragment.prototype.u = function() {
return this.up();
};
return XMLFragment;
})();
module.exports = XMLFragment;
}).call(this);
},{}],19:[function(require,module,exports){
// Generated by CoffeeScript 1.3.3
(function() {
var XMLBuilder;
XMLBuilder = require('./XMLBuilder');
module.exports.create = function(name, xmldec, doctype, options) {
if (name != null) {
return new XMLBuilder(name, xmldec, doctype, options).root();
} else {
return new XMLBuilder();
}
};
}).call(this);
},{"./XMLBuilder":17}],20:[function(require,module,exports){
/**
* Determine if an object is Buffer
*
* Author: Feross Aboukhadijeh <feross@feross.org> <http://feross.org>
* License: MIT
*
* `npm install is-buffer`
*/
module.exports = function (obj) {
return !!(obj != null &&
(obj._isBuffer || // For Safari 5-7 (missing Object.prototype.constructor)
(obj.constructor &&
typeof obj.constructor.isBuffer === 'function' &&
obj.constructor.isBuffer(obj))
))
}
},{}]},{},[1]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment