lib/request.js
function dispatch(url, httpMethod, data, headers, hostInfo, credentials,
		logger, callback) {

	hostInfo.port = hostInfo.port || 80;

	var apiRequest, prop, hasErrored;
	var mergedHeaders = createHeaders(hostInfo.host, headers);
	var apiPath = url;

	data = prepare(data, credentials.consumerkey);

	// Special case for track previews: we explicitly request to be given
	// the XML response back instead of a redirect to the track download.
	if (url.indexOf('track/preview') >= 0) {
		data.redirect = 'false';
	}

	if (httpMethod === 'GET') {
		url = url + '?' + qs.stringify(data);
	}

	logger.info(util.format('%s: http://%s:%s%s', httpMethod,
		hostInfo.host, hostInfo.port, url));
	logHeaders(logger, mergedHeaders);

	// Make the request
	apiRequest = http.request({
		method: httpMethod,
		hostname: hostInfo.host,
		// Force scheme to http for browserify otherwise it will pick up the
		// scheme from window.location.protocol which is app:// in firefoxos
		scheme: 'http',
		// Set this so browserify doesn't set it to true on the xhr, which
		// causes an http status of 0 and empty response text as it forces
		// the XHR to do a pre-flight access-control check and the API
		// currently does not set CORS headers.
		withCredentials: false,
		path: url,
		port: hostInfo.port,
		headers: mergedHeaders
	}, function handleResponse(response) {
		var responseBuffer = '';

		if (typeof response.setEncoding === 'function') {
			response.setEncoding('utf8');
		}

		response.on('data', function bufferData(chunk) {
			responseBuffer += chunk;
		});

		response.on('end', function endResponse() {
			if (+response.statusCode >= 400) {
				return callback(new ApiHttpError(
					response.statusCode, responseBuffer, apiPath));
			}

			if (!hasErrored) {
				return callback(null, responseBuffer, response);
			}
		});
	});

	apiRequest.on('error', function logErrorAndCallback(err) {
		// Flag that we've errored so we don't call the callback twice
		// if we get an end event on the response.
		hasErrored = true;
		logger.info('Error fetching [' + url + ']. Body:\n' + err);

		return callback(new RequestError(err, url));
	});

	if (httpMethod === 'GET') {
		apiRequest.end();
	} else {
		apiRequest.end(data);
	}
}
function dispatch(url, httpMethod, data, headers, hostInfo, credentials,
		logger, callback) {

	hostInfo.port = hostInfo.port || 80;

	var apiRequest, prop, hasErrored;
	var mergedHeaders = createHeaders(hostInfo.host, headers);
	var apiPath = url;

	data = prepare(data, credentials.consumerkey);

	// Special case for track previews: we explicitly request to be given
	// the XML response back instead of a redirect to the track download.
	if (url.indexOf('track/preview') >= 0) {
		data.redirect = 'false';
	}

	if (httpMethod === 'GET') {
		url = url + '?' + qs.stringify(data);
	}

	logger.info(util.format('%s: http://%s:%s%s', httpMethod,
		hostInfo.host, hostInfo.port, url));
	logHeaders(logger, mergedHeaders);

	// Make the request
	apiRequest = http.request({
		method: httpMethod,
		hostname: hostInfo.host,
		// Force scheme to http for browserify otherwise it will pick up the
		// scheme from window.location.protocol which is app:// in firefoxos
		scheme: 'http',
		// Set this so browserify doesn't set it to true on the xhr, which
		// causes an http status of 0 and empty response text as it forces
		// the XHR to do a pre-flight access-control check and the API
		// currently does not set CORS headers.
		withCredentials: false,
		path: url,
		port: hostInfo.port,
		headers: mergedHeaders
	}, function handleResponse(response) {
		var responseBuffer = '';

		if (typeof response.setEncoding === 'function') {
			response.setEncoding('utf8');
		}

		response.on('data', function bufferData(chunk) {
			responseBuffer += chunk;
		});

		response.on('end', function endResponse() {
			if (+response.statusCode >= 400) {
				return callback(new ApiHttpError(
					response.statusCode, responseBuffer, apiPath));
			}

			if (!hasErrored) {
				return callback(null, responseBuffer, response);
			}
		});
	});

	apiRequest.on('error', function logErrorAndCallback(err) {
		// Flag that we've errored so we don't call the callback twice
		// if we get an end event on the response.
		hasErrored = true;
		logger.info('Error fetching [' + url + ']. Body:\n' + err);

		return callback(new RequestError(err, url));
	});

	if (httpMethod === 'GET') {
		apiRequest.end();
	} else {
		apiRequest.end(data);
	}
}
function dispatch ( url , httpMethod , data , headers , hostInfo , credentials , logger , callback ) { hostInfo . port = hostInfo . port || 80 ; var apiRequest , prop , hasErrored ; var mergedHeaders = createHeaders ( hostInfo . host , headers ) ; var apiPath = url ; data = prepare ( data , credentials . consumerkey ) ; // Special case for track previews: we explicitly request to be given // the XML response back instead of a redirect to the track download. if ( url . indexOf ( 'track/preview' ) >= 0 ) { data . redirect = 'false' ; } if ( httpMethod === 'GET' ) { url = url + '?' + qs . stringify ( data ) ; } logger . info ( util . format ( '%s: http://%s:%s%s' , httpMethod , hostInfo . host , hostInfo . port , url ) ) ; logHeaders ( logger , mergedHeaders ) ; // Make the request apiRequest = http . request ( { method : httpMethod , hostname : hostInfo . host , // Force scheme to http for browserify otherwise it will pick up the // scheme from window.location.protocol which is app:// in firefoxos scheme : 'http' , // Set this so browserify doesn't set it to true on the xhr, which // causes an http status of 0 and empty response text as it forces // the XHR to do a pre-flight access-control check and the API // currently does not set CORS headers. withCredentials : false , path : url , port : hostInfo . port , headers : mergedHeaders } , function handleResponse ( response ) { var responseBuffer = '' ; if ( typeof response . setEncoding === 'function' ) { response . setEncoding ( 'utf8' ) ; } response . on ( 'data' , function bufferData ( chunk ) { responseBuffer += chunk ; } ) ; response . on ( 'end' , function endResponse ( ) { if ( + response . statusCode >= 400 ) { return callback ( new ApiHttpError ( response . statusCode , responseBuffer , apiPath ) ) ; } if ( ! hasErrored ) { return callback ( null , responseBuffer , response ) ; } } ) ; } ) ; apiRequest . on ( 'error' , function logErrorAndCallback ( err ) { // Flag that we've errored so we don't call the callback twice // if we get an end event on the response. hasErrored = true ; logger . info ( 'Error fetching [' + url + ']. Body:\n' + err ) ; return callback ( new RequestError ( err , url ) ) ; } ) ; if ( httpMethod === 'GET' ) { apiRequest . end ( ) ; } else { apiRequest . end ( data ) ; } }
Dispatches requests to the API.  Serializes the data in keeping with the API specification and applies approriate HTTP headers.  - @param {String} url - the URL on the API to make the request to. - @param {String} httpMethod - @param {Object} data - hash of the parameters for the request. - @param {Object} headers - Headers for this request. - @param {Object} hostInfo - hash of host, port and prefix - @param {Object} credentials - hash of oauth consumer key and secret - @param {Object} logger - an object implementing the npm log levels - @param {Function} callback
Dispatches requests to the API . Serializes the data in keeping with the API specification and applies approriate HTTP headers . -