Permalink
Browse files

First commit

  • Loading branch information...
chriso committed Jan 2, 2012
0 parents commit 1a4646b7309c474a7e28476dc773ab32c487c5a9
Showing with 169 additions and 0 deletions.
  1. +20 −0 LICENSE
  2. +133 −0 index.js
  3. +16 −0 package.json
20 LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2012 Chris O'Hara <cohara87@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
133 index.js
@@ -0,0 +1,133 @@
+var child = require('child_process');
+
+/**
+ * Make a request with cURL.
+ *
+ * @param {Object|String} options (optional) - sent as --<key> <value> to curl
+ * @param {Function} callback (optional)
+ * @api public
+ */
+
+module.exports = function (options, callback) {
+ if (arguments.length === 1) {
+ if (typeof options === 'function') {
+ callback = options;
+ options = {};
+ } else {
+ var defaults = options, prev = this;
+ return function (options, callback) {
+ if (typeof options === 'object') {
+ for (var key in defaults) {
+ if (typeof options[key] === 'undefined') {
+ options[key] = defaults[key];
+ }
+ }
+ }
+ prev.apply(prev, arguments);
+ };
+ }
+ }
+
+ if (typeof options === 'string') {
+ options = { url: options };
+ }
+
+ var curl
+ , args = ['--silent', '--show-error', '--no-buffer']
+ , start = new Date
+ , stderr = ''
+ , stdoutlen
+ , stdout = new Buffer(stdoutlen = 0)
+ , encoding
+ , complete
+ , cleanup
+ , chunk
+ , timeout;
+
+ //Follow location by default
+ if (!options['max-redirs']) {
+ options.location = true;
+ options['max-redirs'] = 3;
+ }
+
+ //Add an additional setTimeout for max-time
+ if (options['max-time']) {
+ timeout = setTimeout(function () {
+ if (complete) return;
+ callback('timeout', null, {
+ cmd: 'curl ' + args.join(' ')
+ , time: (new Date().getTime() - start.getTime())
+ });
+ complete = true;
+ if (curl && curl.kill) curl.kill('SIGKILL');
+ }, 1000 * options['max-time']);
+ }
+
+ //If no encoding is specified just return a buffer
+ if (options.encoding) {
+ encoding = options.encoding;
+ if (encoding === 'ascii') {
+ options['use-ascii'] = true;
+ }
+ delete options.encoding;
+ }
+
+ //Call the callback each time we receive a chunk?
+ if (options.chunk) {
+ chunk = true;
+ delete options.chunk;
+ }
+
+ //Prepare curl args
+ var key, values;
+ for (key in options) {
+ values = Array.isArray(options[key]) ? options[key] : [options[key]];
+ values.forEach(function (value) {
+ args.push('--' + key);
+ if (true !== value) {
+ args.push(value);
+ }
+ });
+ }
+
+ //Spawn the curl process
+ curl = child.spawn('curl', args, { cwd: process.cwd() });
+
+ //Collection stdout
+ curl.stdout.on('data', function (data) {
+ if (complete) return;
+ if (chunk) {
+ return callback(null, encoding ? data.toString(encoding) : data);
+ }
+ var len = data.length, prev = stdout;
+ stdout = new Buffer(len + stdoutlen);
+ prev.copy(stdout, 0, 0, stdoutlen);
+ data.copy(stdout, stdoutlen, 0, len);
+ stdoutlen += len;
+ });
+
+ //Collect stderr
+ curl.stderr.setEncoding('utf8');
+ curl.stderr.on('data', function (data) {
+ if (complete) return;
+ stderr += data;
+ });
+
+ //Handle exit
+ curl.on('exit', function () {
+ if (complete) return;
+ complete = true;
+ stderr = stderr.length ? stderr.trim().split('\n',1)[0] : null;
+ var debug = {
+ cmd: 'curl ' + args.join(' ')
+ , time: (new Date().getTime() - start.getTime())
+ }
+ if (chunk) {
+ callback(stderr, null, debug);
+ } else {
+ callback(stderr, encoding ? stdout.toString(encoding) : stdout, debug);
+ }
+ if (timeout) clearTimeout(timeout);
+ });
+};
+
@@ -0,0 +1,16 @@
+{ "name" : "curlrequest",
+ "description" : "A curl wrapper for node",
+ "version" : "0.1.1",
+ "homepage" : "https://github.com/chriso/curlrequest",
+ "author" : "Chris O'Hara <cohara87@gmail.com>",
+ "main" : "index",
+ "repository": {
+ "type": "git",
+ "url": "http://github.com/chriso/curlrequest.git"
+ },
+ "engines": { "node": ">= 0.4.0" },
+ "licenses": [{
+ "type": "MIT",
+ "url": "http://github.com/chriso/curlrequest/raw/master/LICENSE"
+ }]
+}

0 comments on commit 1a4646b

Please sign in to comment.