"use strict";
var request = require('request');
var errors = require('./../errors');
var utils = require('../../utils');
var applyTypeToBuffer = require('./applyTypeToBuffer');
var defaultBody = require('./defaultBody');
function ajax(options, adapterCallback) {
var requestCompleted = false;
var callback = utils.getArguments(function (args) {
Iif (requestCompleted) {
return;
}
adapterCallback.apply(this, args);
requestCompleted = true;
});
Iif (typeof options === "function") {
callback = options;
options = {};
}
options = utils.clone(options);
var defaultOptions = {
method : "GET",
headers: {},
json: true,
processData: true,
timeout: 10000,
cache: false
};
options = utils.extend(true, defaultOptions, options);
function onSuccess(obj, resp, cb) {
Iif (!options.binary && !options.json && options.processData &&
typeof obj !== 'string') {
obj = JSON.stringify(obj);
} else if (!options.binary && options.json && typeof obj === 'string') {
try {
obj = JSON.parse(obj);
} catch (e) {
// Probably a malformed JSON from server
return cb(e);
}
}
if (Array.isArray(obj)) {
obj = obj.map(function (v) {
if (v.error || v.missing) {
return errors.generateErrorFromResponse(v);
} else {
return v;
}
});
}
if (options.binary) {
applyTypeToBuffer(obj, resp);
}
cb(null, obj, resp);
}
function onError(err, cb) {
var errParsed, errObj;
Eif (err.code && err.status) {
var err2 = new Error(err.message || err.code);
err2.status = err.status;
return cb(err2);
}
try {
errParsed = JSON.parse(err.responseText);
//would prefer not to have a try/catch clause
errObj = errors.generateErrorFromResponse(errParsed);
} catch (e) {
errObj = errors.generateErrorFromResponse(err);
}
cb(errObj);
}
Eif (options.json) {
if (!options.binary) {
options.headers.Accept = 'application/json';
}
options.headers['Content-Type'] = options.headers['Content-Type'] ||
'application/json';
}
if (options.binary) {
options.encoding = null;
options.json = false;
}
if (!options.processData) {
options.json = false;
}
return request(options, function (err, response, body) {
if (err) {
err.status = response ? response.statusCode : 400;
return onError(err, callback);
}
var error;
var content_type = response.headers && response.headers['content-type'];
var data = body || defaultBody();
// CouchDB doesn't always return the right content-type for JSON data, so
// we check for ^{ and }$ (ignoring leading/trailing whitespace)
if (!options.binary && (options.json || !options.processData) &&
typeof data !== 'object' &&
(/json/.test(content_type) ||
(/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) {
data = JSON.parse(data);
}
if (response.statusCode >= 200 && response.statusCode < 300) {
onSuccess(data, response, callback);
} else {
try {
// See if we received an error message from the server
// If the connection was interrupted, the data might be nothing
// that's why we have the try/catch
data = JSON.parse(data.toString());
} catch(e) {}
error = errors.generateErrorFromResponse(data);
error.status = response.statusCode;
callback(error);
}
});
}
module.exports = ajax;
|