Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Determine error from exit code & pipe stderr to the main process

  • Loading branch information...
commit 2b7fe95846b73ed1cfa4555b35f1f4cbc0fc9569 1 parent 01cedcd
Chris O'Hara authored
Showing with 118 additions and 15 deletions.
  1. +10 −1 README.md
  2. +87 −0 errors.js
  3. +20 −13 index.js
  4. +1 −1  package.json
11 README.md
View
@@ -21,7 +21,7 @@ Note: don't use this if you need to stream the response - use
## Usage
-Make a request with curl - callback receives `(stderr, stdout)` on request
+Make a request with curl - callback receives `(err, stdout)` on request
completion
```javascript
@@ -45,6 +45,10 @@ request([options ,] callback);
The request url.
+`method` - *default: GET*
+
+The request method.
+
`encoding` - *default: utf8*
Encode the response body as either `utf` or `ascii`. Set to `null` return a
@@ -105,6 +109,11 @@ a higher level library has the chance to modify it.
Open a file and process it like a request response, useful if using
temporary files.
+`stderr` - *default: true*
+
+Pipe the stderr of each curl process to the main process. Set this to a
+string to write stderr to a file, or false to disable stderr.
+
### Passing options directly to curl
Any additional options are sent as command line options to curl. See `man
87 errors.js
View
@@ -0,0 +1,87 @@
+module.exports = [
+ null,
+ "Unsupported protocol. This build of curl has no support for this protocol.",
+ "Failed to initialize.",
+ "URL malformed. The syntax was not correct.",
+ null,
+ "Couldn't resolve proxy. The given proxy host could not be resolved.",
+ "Couldn't resolve host. The given remote host was not resolved.",
+ "Failed to connect to host.",
+ "FTP weird server reply. The server sent data curl couldn't parse.",
+ "FTP access denied. The server denied login or denied access to the particular resource or directory you wanted to reach. Most often you tried to change to a directory that doesn't exist on the server.",
+ null,
+ "FTP weird PASS reply. Curl couldn't parse the reply sent to the PASS request.",
+ null,
+ "FTP weird PASV reply, Curl couldn't parse the reply sent to the PASV request.",
+ "FTP weird 227 format. Curl couldn't parse the 227-line the server sent.",
+ "FTP can't get host. Couldn't resolve the host IP we got in the 227-line.",
+ null,
+ "FTP couldn't set binary. Couldn't change transfer method to binary.",
+ "Partial file. Only a part of the file was transferred.",
+ "FTP couldn't download/access the given file, the RETR (or similar) command failed.",
+ null,
+ "FTP quote error. A quote command returned error from the server.",
+ "HTTP page not retrieved. The requested url was not found or returned another error with the HTTP error code being 400 or above. This return code only appears if -f/--fail is used.",
+ "Write error. Curl couldn't write data to a local filesystem or similar.",
+ null,
+ "FTP couldn't STOR file. The server denied the STOR operation, used for FTP uploading.",
+ "Read error. Various reading problems.",
+ "Out of memory. A memory allocation request failed.",
+ "Operation timeout. The specified time-out period was reached according to the conditions.",
+ null,
+ "FTP PORT failed. The PORT command failed. Not all FTP servers support the PORT command, try doing a transfer using PASV instead!",
+ "FTP couldn't use REST. The REST command failed. This command is used for resumed FTP transfers.",
+ null,
+ "HTTP range error. The range command didn't work.",
+ "HTTP post error. Internal post-request generation error.",
+ "SSL connect error. The SSL handshaking failed.",
+ "FTP bad download resume. Couldn't continue an earlier aborted download.",
+ "FILE couldn't read file. Failed to open the file. Permissions?",
+ "LDAP cannot bind. LDAP bind operation failed.",
+ "LDAP search failed.",
+ null,
+ "Function not found. A required LDAP function was not found.",
+ "Aborted by callback. An application told curl to abort the operation.",
+ "Internal error. A function was called with a bad parameter.",
+ null,
+ "Interface error. A specified outgoing interface could not be used.",
+ null,
+ "Too many redirects. When following redirects, curl hit the maximum amount.",
+ "Unknown TELNET option specified.",
+ "Malformed telnet option.",
+ null,
+ "The peer's SSL certificate or SSH MD5 fingerprint was not ok.",
+ "The server didn't reply anything, which here is considered an error.",
+ "SSL crypto engine not found.",
+ "Cannot set SSL crypto engine as default.",
+ "Failed sending network data.",
+ "Failure in receiving network data.",
+ null,
+ "Problem with the local certificate.",
+ "Couldn't use specified SSL cipher.",
+ "Peer certificate cannot be authenticated with known CA certificates.",
+ "Unrecognized transfer encoding.",
+ "Invalid LDAP URL.",
+ "Maximum file size exceeded.",
+ "Requested FTP SSL level failed.",
+ "Sending the data requires a rewind that failed.",
+ "Failed to initialise SSL Engine.",
+ "The user name, password, or similar was not accepted and curl failed to log in.",
+ "File not found on TFTP server.",
+ "Permission problem on TFTP server.",
+ "Out of disk space on TFTP server.",
+ "Illegal TFTP operation.",
+ "Unknown TFTP transfer ID.",
+ "File already exists (TFTP).",
+ "No such user (TFTP).",
+ "Character conversion failed.",
+ "Character conversion functions required.",
+ "Problem with reading the SSL CA cert (path access rights).",
+ "The resource referenced in the URL does not exist.",
+ "An unspecified error occurred during the SSH session.",
+ "Failed to shut down the SSL connection.",
+ null,
+ "Could not load CRL file, missing or wrong format.",
+ "Issuer check failed."
+];
+
33 index.js
View
@@ -2,6 +2,7 @@ var child = require('child_process')
, util = require('util')
, fs = require('fs')
, proxy = require('./proxy')
+ , errors = require('./errors')
, cwd = process.cwd();
/**
@@ -11,6 +12,7 @@ var child = require('child_process')
var curl_map = {
timeout: 'max-time'
, redirects: 'max-redirs'
+ , method: 'request'
, useragent: 'user-agent'
};
@@ -92,9 +94,9 @@ exports.request = function (options, callback) {
}
var curl
- , args = ['--silent', '--show-error', '--no-buffer']
+ , args = ['--silent', '--show-error', '--no-buffer', '--no-keepalive']
, start = new Date
- , stderr = ''
+ , err
, stdoutlen
, stdout = new Buffer(stdoutlen = 0)
, encoding
@@ -108,7 +110,10 @@ exports.request = function (options, callback) {
, timeout;
function finish() {
- callback.call(scope, stderr, stdout, {
+ if (err in errors) {
+ err = errors[err];
+ }
+ callback.call(scope, err, stdout, {
cmd: cmd
, time: (new Date().getTime() - start.getTime())
});
@@ -244,17 +249,19 @@ exports.request = function (options, callback) {
stdoutlen += len;
});
- //Collect stderr
- curl.stderr.setEncoding('utf8');
- curl.stderr.on('data', function (data) {
- if (complete) return;
- stderr += data;
- });
+ //Pipe stderr to the current process
+ if (options.stderr) {
+ if (options.stderr === false) {
+ delete options.stderr;
+ }
+ } else {
+ curl.stderr.pipe(process.stderr);
+ }
//Handle curl exit
- curl.on('exit', function () {
+ curl.on('exit', function (code) {
+ err = code;
if (complete) return;
- stderr = stderr.length ? stderr.trim().split('\n',1)[0] : null;
if (encoding) {
stdout = stdout.toString(encoding);
}
@@ -274,7 +281,7 @@ exports.request = function (options, callback) {
}
}
if (!valid) {
- stderr = 'response does not contain required string(s)';
+ err = 'response does not contain required string(s)';
stdout = null
} else if (!encoding) {
stdout = new Buffer(stdout);
@@ -293,7 +300,7 @@ exports.request = function (options, callback) {
}
}
if (!valid) {
- stderr = 'response contains bad string(s)';
+ err = 'response contains bad string(s)';
stdout = null
} else if (!encoding) {
stdout = new Buffer(stdout);
2  package.json
View
@@ -1,6 +1,6 @@
{ "name" : "curlrequest",
"description" : "A curl wrapper for node",
- "version" : "0.2.9",
+ "version" : "0.3.0",
"homepage" : "https://github.com/chriso/curlrequest",
"author" : "Chris O'Hara <cohara87@gmail.com>",
"main" : "index",
Please sign in to comment.
Something went wrong with that request. Please try again.