| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * Utilities: A classic collection of JavaScript utilities
- * Copyright 2112 Matthew Eernisse ([email protected])
- *
- * 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 = require('https')
- , url = require('url')
- , uri = require('./uri')
- , log = require('./log')
- , core = require('./core');
- /**
- @name request
- @namespace request
- @public
- @function
- @description Sends requests to the given url sending any data if the method is POST or PUT
- @param {Object} opts The options to use for the request
- @param {String} [opts.url] The URL to send the request to
- @param {String} [opts.method=GET] The method to use for the request
- @param {Object} [opts.headers] Headers to send on requests
- @param {String} [opts.data] Data to send on POST and PUT requests
- @param {String} [opts.dataType] The type of data to send
- @param {Function} callback the function to call after, args are `error, data`
- */
- var request = function (opts, callback) {
- var client
- , options = opts || {}
- , parsed = url.parse(options.url)
- , path
- , requester = parsed.protocol == 'http:' ? http : https
- , method = (options.method && options.method.toUpperCase()) || 'GET'
- , headers = core.mixin({}, options.headers || {})
- , data = options.data
- , contentLength
- , port
- , clientOpts;
- if (parsed.port) {
- port = parsed.port;
- }
- else {
- port = parsed.protocol == 'http:' ? '80' : '443';
- }
- path = parsed.pathname;
- if (method == 'POST' || method == 'PUT') {
- // Handle the payload and content-length
- if (data) {
- // JSON data
- if (options.dataType == 'json') {
- if (typeof data == 'object') {
- data = JSON.stringify(data);
- }
- headers['Content-Type'] = headers['Content-Type'] ||
- headers['content-type'] || 'application/json';
- }
- // Form data
- else {
- if (typeof data == 'object') {
- data = uri.paramify(data);
- }
- // FIXME: What is the prefix for form-urlencoded?
- headers['Content-Type'] = headers['Content-Type'] ||
- headers['content-type'] || 'form-urlencoded';
- }
- contentLength = Buffer.byteLength(data);
- }
- else {
- contentLength = 0
- }
- headers['Content-Length'] = contentLength;
- if (parsed.search) {
- path += parsed.search;
- }
- }
- else {
- if (data) {
- // Data is an object, parse into querystring
- if (typeof data == 'object') {
- data = uri.paramify(data);
- }
- // Create querystring or append to existing
- if (parsed.search) {
- path += parsed.search; // search includes question mark
- path += '&' + data;
- }
- else {
- path += '?' + data;
- }
- }
- }
- clientOpts = {
- host: parsed.hostname
- , port: port
- , method: method
- , agent: false
- , path: path
- , headers: headers
- };
- client = requester.request(clientOpts);
- client.addListener('response', function (resp) {
- var data = '';
- resp.addListener('data', function (chunk) {
- data += chunk.toString();
- });
- resp.addListener('end', function () {
- var stat = resp.statusCode
- , contentType
- , err;
- // Successful response
- if ((stat > 199 && stat < 300) || stat == 304) {
- if (data) {
- contentType = resp.headers['Content-Type'];
- if (contentType == 'application/json' || contentType == 'text/json' ||
- uri.getFileExtension(parsed.pathname) == 'json') {
- try {
- data = JSON.parse(data);
- }
- catch (e) {
- return callback(e, null);
- }
- }
- callback(null, data);
- }
- else {
- callback(null, null);
- }
- }
- // Something failed
- else {
- err = new Error(data);
- err.statusCode = resp.statusCode;
- callback(err, null);
- }
- });
- });
- client.addListener('error', function (e) {
- callback(e, null);
- });
- if ((method == 'POST' || method == 'PUT') && data) {
- client.write(data);
- }
- client.end();
- };
- module.exports = request;
|