Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: npm/npm
...
head fork: npm/npm
Checking mergeability… Don't worry, you can still create the pull request.
  • 9 commits
  • 41 files changed
  • 1 commit comment
  • 1 contributor
Showing with 626 additions and 364 deletions.
  1. +1 −22 lib/npm.js
  2. +6 −9 lib/publish.js
  3. +6 −0 lib/utils/error-handler.js
  4. +3 −0  node_modules/node-gyp/addon.gypi
  5. +5 −1 node_modules/node-gyp/lib/build.js
  6. +2 −2 node_modules/node-gyp/package.json
  7. +23 −9 node_modules/npm-registry-client/README.md
  8. +26 −56 node_modules/npm-registry-client/index.js
  9. +18 −18 node_modules/npm-registry-client/lib/adduser.js
  10. +12 −12 node_modules/npm-registry-client/lib/get.js
  11. +12 −6 node_modules/npm-registry-client/lib/publish.js
  12. +29 −23 node_modules/npm-registry-client/lib/request.js
  13. +4 −4 node_modules/npm-registry-client/package.json
  14. +3 −3 node_modules/npm-registry-client/test/retries.js
  15. +15 −0 node_modules/read/README.md
  16. +14 −1 node_modules/read/lib/read.js
  17. +15 −0 node_modules/read/node_modules/mute-stream/mute.js
  18. +2 −5 node_modules/read/node_modules/mute-stream/package.json
  19. +12 −0 node_modules/read/node_modules/mute-stream/test/basic.js
  20. +4 −4 node_modules/read/package.json
  21. +6 −1 node_modules/read/test/basic.js
  22. +6 −1 node_modules/read/test/defaults.js
  23. +6 −1 node_modules/read/test/many.js
  24. +1 −1  node_modules/request/README.md
  25. +0 −128 node_modules/request/aws2.js
  26. +129 −19 node_modules/request/main.js
  27. +3 −3 node_modules/request/package.json
  28. +9 −5 node_modules/request/tests/server.js
  29. +38 −1 node_modules/request/tests/test-body.js
  30. +33 −2 node_modules/request/tests/test-defaults.js
  31. +30 −0 node_modules/request/tests/test-follow-all-303.js
  32. +35 −0 node_modules/request/tests/test-follow-all.js
  33. +3 −3 node_modules/request/tests/test-https-strict.js
  34. +3 −3 node_modules/request/tests/test-https.js
  35. +3 −3 node_modules/request/tests/test-params.js
  36. +60 −0 node_modules/request/tests/test-protocol-changing-redirect.js
  37. +0 −13 node_modules/request/tests/test-s3.js
  38. +4 −2 node_modules/request/tests/test-tunnel.js
  39. +1 −0  node_modules/request/tunnel.js
  40. +3 −3 package.json
  41. +41 −0 test/tap/publish-config.js
View
23 lib/npm.js
@@ -308,28 +308,7 @@ function load (npm, cli, cb) {
} catch (e) { token = null }
}
- npm.registry = new RegClient(
- { registry: npm.config.get("registry")
- , cache: npm.config.get("cache")
- , auth: npm.config.get("_auth")
- , token: token
- , alwaysAuth: npm.config.get("always-auth")
- , email: npm.config.get("email")
- , proxy: npm.config.get("proxy")
- , tag: npm.config.get("tag")
- , ca: npm.config.get("ca")
- , strictSSL: npm.config.get("strict-ssl")
- , userAgent: npm.config.get("user-agent")
- , E404: npm.E404
- , EPUBLISHCONFLICT: npm.EPUBLISHCONFLICT
- , log: log
- , retries: npm.config.get("fetch-retries")
- , retryFactor: npm.config.get("fetch-retry-factor")
- , retryMinTimeout: npm.config.get("fetch-retry-mintimeout")
- , retryMaxTimeout: npm.config.get("fetch-retry-maxtimeout")
- , cacheMin: npm.config.get("cache-min")
- , cacheMax: npm.config.get("cache-max")
- })
+ npm.registry = new RegClient(npm.config)
// save the token cookie in the config file
if (npm.registry.couchLogin) {
View
15 lib/publish.js
@@ -2,7 +2,6 @@
module.exports = publish
var npm = require("./npm.js")
- , registry = npm.registry
, log = require("npmlog")
, tar = require("./utils/tar.js")
, path = require("path")
@@ -10,6 +9,8 @@ var npm = require("./npm.js")
, fs = require("graceful-fs")
, lifecycle = require("./utils/lifecycle.js")
, chain = require("slide").chain
+ , Conf = require("npmconf").Conf
+ , RegClient = require("npm-registry-client")
publish.usage = "npm publish <tarball>"
+ "\nnpm publish <folder>"
@@ -61,11 +62,11 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
if (!data) return cb(new Error("no package.json file found"))
// check for publishConfig hash
+ var registry = npm.registry
if (data.publishConfig) {
- Object.keys(data.publishConfig).forEach(function (k) {
- log.info("publishConfig", k + "=" + data.publishConfig[k])
- npm.config.set(k, data.publishConfig[k])
- })
+ var pubConf = new Conf(npm.config)
+ pubConf.unshift(data.publishConfig)
+ registry = new RegClient(pubConf)
}
data._npmVersion = npm.version
@@ -77,10 +78,6 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
("This package has been marked as private\n"
+"Remove the 'private' field from the package.json to publish it."))
- regPublish(data, isRetry, arg, cachedir, cb)
-}
-
-function regPublish (data, isRetry, arg, cachedir, cb) {
var tarball = cachedir + ".tgz"
registry.publish(data, tarball, function (er) {
if (er && er.code === "EPUBLISHCONFLICT"
View
6 lib/utils/error-handler.js
@@ -197,6 +197,12 @@ function errorHandler (er) {
,"Move it away, and try again."].join("\n"))
break
+ case "ENEEDAUTH":
+ log.error("need auth", [er.message
+ ,"You need to authorize this machine using `npm adduser`"
+ ].join("\n"))
+ break
+
case "ENOTSUP":
if (er.required) {
log.error("notsup", [er.message
View
3  node_modules/node-gyp/addon.gypi
@@ -15,6 +15,9 @@
}],
[ 'OS=="win"', {
'libraries': [ '-l<(node_root_dir)/$(Configuration)/node.lib' ],
+ # warning C4251: 'node::ObjectWrap::handle_' : class 'v8::Persistent<T>'
+ # needs to have dll-interface to be used by clients of class 'node::ObjectWrap'
+ 'msvs_disabled_warnings': [ 4251 ],
}],
[ 'OS=="freebsd" or OS=="openbsd" or OS=="solaris" or (OS=="linux" and target_arch!="ia32")', {
'cflags': [ '-fPIC' ],
View
6 node_modules/node-gyp/lib/build.js
@@ -176,9 +176,13 @@ function build (gyp, argv, callback) {
argv.push('/clp:Verbosity=minimal')
}
- // Turn off the Microsoft logo on Windows
if (win) {
+ // Turn off the Microsoft logo on Windows
argv.push('/nologo')
+
+ // Fix "warning MSB8012: TargetExt(.dll) does not match
+ // the Linker's OutputFile property value (.node)"
+ argv.push('/property:TargetExt=.node')
}
// Specify the build type, Release by default
View
4 node_modules/node-gyp/package.json
@@ -10,7 +10,7 @@
"bindings",
"gyp"
],
- "version": "0.6.5",
+ "version": "0.6.6",
"installVersion": 9,
"author": {
"name": "Nathan Rajlich",
@@ -45,6 +45,6 @@
"node": ">= 0.6.0"
},
"readme": "node-gyp\n=========\n### Node.js native addon build tool\n\n`node-gyp` is a cross-platform command-line tool written in Node.js for compiling\nnative addon modules for Node.js, which takes away the pain of dealing with the\nvarious differences in build platforms. It is the replacement to the `node-waf`\nprogram which is removed for node `v0.8`. If you have a native addon for node that\nstill has a `wscript` file, then you should definitely add a `binding.gyp` file\nto support the latest versions of node.\n\nMultiple target versions of node are supported (i.e. `0.6`, `0.7`,..., `1.0`,\netc.), regardless of what version of node is actually installed on your system\n(`node-gyp` downloads the necessary development files for the target version).\n\n#### Features:\n\n * Easy to use, consistent interface\n * Same commands to build your module on every platform\n * Supports multiple target versions of Node\n\n\nInstallation\n------------\n\nYou can install with `npm`:\n\n``` bash\n$ npm install -g node-gyp\n```\n\nYou will also need to install:\n\n * On Unix:\n * `python`\n * `make`\n * A proper C/C++ compiler toolchain, like GCC\n * On Windows:\n * [Python][windows-python] ([`v2.7.2`][windows-python-v2.7.2] recommended, `v3.x.x` not yet supported)\n * Microsoft Visual C++ ([Express][msvc] version works well)\n * For 64-bit builds of node and native modules you will _also_ need the [Windows 7 64-bit SDK][win7sdk]\n\nHow to Use\n----------\n\nTo compile your native addon, first go to its root directory:\n\n``` bash\n$ cd my_node_addon\n```\n\nThe next step is to generate the appropriate project build files for the current\nplatform. Use `configure` for that:\n\n``` bash\n$ node-gyp configure\n```\n\n__Note__: The `configure` step looks for the `binding.gyp` file in the current\ndirectory to processs. See below for instructions on creating the `binding.gyp` file.\n\nNow you will have either a `Makefile` (on Unix platforms) or a `vcxproj` file\n(on Windows) in the `build/` directory. Next invoke the `build` command:\n\n``` bash\n$ node-gyp build\n```\n\nNow you have your compiled `.node` bindings file! The compiled bindings end up\nin `build/Debug/` or `build/Release/`, depending on the build mode. At this point\nyou can require the `.node` file with Node and run your tests!\n\n__Note:__ To create a _Debug_ build of the bindings file, pass the `--debug` (or\n`-d`) switch when running the either `configure` or `build` command.\n\n\nThe \"binding.gyp\" file\n----------------------\n\nPreviously when node had `node-waf` you had to write a `wscript` file. The\nreplacement for that is the `binding.gyp` file, which describes the configuration\nto build your module in a JSON-like format. This file gets placed in the root of\nyour package, alongside the `package.json` file.\n\nA barebones `gyp` file appropriate for building a node addon looks like:\n\n``` json\n{\n \"targets\": [\n {\n \"target_name\": \"binding\",\n \"sources\": [ \"src/binding.cc\" ]\n }\n ]\n}\n```\n\nSome additional resources for writing `gyp` files:\n\n * [\"Hello World\" node addon example](https://github.com/joyent/node/tree/master/test/addons/hello-world)\n * [gyp user documentation](http://code.google.com/p/gyp/wiki/GypUserDocumentation)\n * [gyp input format reference](http://code.google.com/p/gyp/wiki/InputFormatReference)\n * [*\"binding.gyp\" files out in the wild* wiki page](https://github.com/TooTallNate/node-gyp/wiki/%22binding.gyp%22-files-out-in-the-wild)\n\n\nCommands\n--------\n\n`node-gyp` responds to the following commands:\n\n| **Command** | **Description**\n|:--------------|:---------------------------------------------------------------\n| `build` | Invokes `make`/`msbuild.exe` and builds the native addon\n| `clean` | Removes any the `build` dir if it exists\n| `configure` | Generates project build files for the current platform\n| `rebuild` | Runs \"clean\", \"configure\" and \"build\" all in a row\n| `install` | Installs node development header files for the given version\n| `list` | Lists the currently installed node development file versions\n| `remove` | Removes the node development header files for the given version\n\n\nLicense\n-------\n\n(The MIT License)\n\nCopyright (c) 2012 Nathan Rajlich &lt;nathan@tootallnate.net&gt;\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n[windows-python]: http://www.python.org/getit/windows\n[windows-python-v2.7.2]: http://www.python.org/download/releases/2.7.2#download\n[msvc]: http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express\n[win7sdk]: http://www.microsoft.com/download/en/details.aspx?displayLang=en&id=8279\n",
- "_id": "node-gyp@0.6.5",
+ "_id": "node-gyp@0.6.6",
"_from": "node-gyp@~0.6.4"
}
View
32 node_modules/npm-registry-client/README.md
@@ -8,7 +8,7 @@ It handles all the caching and HTTP calls.
```javascript
var RegClient = require('npm-registry-client')
-var client = new RegClient(options)
+var client = new RegClient(config)
client.get("npm", "latest", 1000, function (er, data, raw, res) {
// error is an error if there was a problem.
@@ -18,29 +18,43 @@ client.get("npm", "latest", 1000, function (er, data, raw, res) {
})
```
-# Options
+# Configuration
+
+This program is designed to work with
+[npmconf](https://npmjs.org/package/npmconf), but you can also pass in
+a plain-jane object with the appropriate configs, and it'll shim it
+for you. Any configuration thingie that has get/set/del methods will
+also be accepted.
* `registry` **Required** {String} URL to the registry
* `cache` **Required** {String} Path to the cache folder
-* `alwaysAuth` {Boolean} Auth even for GET requests.
+* `always-auth` {Boolean} Auth even for GET requests.
* `auth` {String} A base64-encoded `username:password`
* `email` {String} User's email address
* `tag` {String} The default tag to use when publishing new packages.
Default = `"latest"`
* `ca` {String} Cerficate signing authority certificates to trust.
-* `strictSSL` {Boolean} Whether or not to be strict with SSL
+* `strict-ssl` {Boolean} Whether or not to be strict with SSL
certificates. Default = `true`
-* `userAgent` {String} User agent header to send. Default =
+* `user-agent` {String} User agent header to send. Default =
`"node/{process.version}"`
* `log` {Object} The logger to use. Defaults to `require("npmlog")` if
that works, otherwise logs are disabled.
-* `retries` {Number} Number of times to retry on GET failures.
+* `fetch-retries` {Number} Number of times to retry on GET failures.
Default=2
-* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10
-* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.
+* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10
+* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.
Default=10000 (10 seconds)
-* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.
+* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.
Default=60000 (60 seconds)
+* `proxy` {URL} The url to proxy requests through.
+* `https-proxy` {URL} The url to proxy https requests through.
+ Defaults to be the same as `proxy` if unset.
+* `_auth` {String} The base64-encoded authorization header.
+* `username` `_password` {String} Username/password to use to generate
+ `_auth` if not supplied.
+* `_token` {Object} A token for use with
+ [couch-login](https://npmjs.org/package/couch-login)
# client.request(method, where, [what], [etag], [nofollow], cb)
View
82 node_modules/npm-registry-client/index.js
@@ -19,78 +19,48 @@ try {
function noop () {}
-function RegClient (options) {
+function RegClient (conf) {
+ // accept either a plain-jane object, or a npmconf object
+ // with a "get" method.
+ if (typeof conf.get !== 'function') {
+ var data = conf
+ conf = { get: function (k) { return data[k] }
+ , set: function (k, v) { data[k] = v }
+ , del: function (k) { delete data[k] } }
+ }
+
+ this.conf = conf
+
// if provided, then the registry needs to be a url.
// if it's not provided, then we're just using the cache only.
- var registry = options.registry
+ var registry = conf.get('registry')
if (registry) {
registry = url.parse(registry)
if (!registry.protocol) throw new Error(
'Invalid registry: ' + registry.url)
- this.registry = registry.href
- if (this.registry.slice(-1) !== '/') {
- this.registry += '/'
+ registry = registry.href
+ if (registry.slice(-1) !== '/') {
+ registry += '/'
}
+ this.conf.set('registry', registry)
} else {
- this.registry = null
+ registry = null
}
- this.retries = options.retries || 2
- this.retryFactor = options.retryFactor || 10
- this.retryMinTimeout = options.retryMinTimeout || 10000
- this.retryMaxTimeout = options.retryMaxTimeout || 60000
-
- this.cache = options.cache
- if (!this.cache) throw new Error("Cache dir is required")
-
- this.alwaysAuth = options.alwaysAuth || false
+ if (!conf.get('cache')) throw new Error("Cache dir is required")
- this.auth = options.auth || null
- if (this.auth) {
- var a = new Buffer(this.auth, "base64").toString()
- a = a.split(":")
- this.username = a.shift()
- this.password = a.join(":")
- } else {
- this.username = options.username
- this.password = options.password
-
- // if username and password are set, but auth isn't, use them.
- if (this.username && this.password) {
- var a = this.username + ":" + this.password
- this.auth = new Buffer(a, "utf8").toString("base64")
- }
- }
-
- if (this.auth && !this.alwaysAuth && this.registry) {
+ var auth = this.conf.get('_auth')
+ var alwaysAuth = this.conf.get('always-auth')
+ if (auth && !alwaysAuth && registry) {
// if we're always authing, then we just send the
// user/pass on every thing. otherwise, create a
// session, and use that.
- this.token = options.token
- this.couchLogin = new CouchLogin(this.registry, this.token)
- this.couchLogin.proxy = this.proxy
- }
-
- this.email = options.email || null
- this.defaultTag = options.tag || "latest"
-
- this.ca = options.ca || null
-
- this.strictSSL = options.strictSSL
- if (this.strictSSL === undefined) this.strictSSL = true
-
- this.userAgent = options.userAgent
- if (this.userAgent === undefined) {
- this.userAgent = 'node/' + process.version
+ var token = this.conf.get('_token')
+ this.couchLogin = new CouchLogin(registry, token)
+ this.couchLogin.proxy = this.conf.get('proxy')
}
- this.cacheMin = options.cacheMin || 0
- this.cacheMax = options.cacheMax || Infinity
-
- this.proxy = options.proxy
- this.httpsProxy = options.httpsProxy || options.proxy
-
- this.log = options.log || npmlog
+ this.log = conf.log || conf.get('log') || npmlog
}
require('fs').readdirSync(__dirname + "/lib").forEach(function (f) {
View
36 node_modules/npm-registry-client/lib/adduser.js
@@ -41,18 +41,18 @@ function adduser (username, password, email, cb) {
// pluck off any other username/password/token. it needs to be the
// same as the user we're becoming now. replace them on error.
- var pre = { username: this.username
- , password: this.password
- , auth: this.auth
- , token: this.token }
-
- this.token = null
+ var pre = { username: this.conf.get('username')
+ , password: this.conf.get('_password')
+ , auth: this.conf.get('_auth')
+ , token: this.conf.get('_token') }
+
+ this.conf.del('_token')
+ this.conf.del('username')
+ this.conf.del('_auth')
+ this.conf.del('_password')
if (this.couchLogin) {
this.couchLogin.token = null
}
- this.username = null
- this.password = null
- this.auth = null
cb = done.call(this, cb, pre)
@@ -72,13 +72,13 @@ function adduser (username, password, email, cb) {
, function (error, data, json, response) {
// if it worked, then we just created a new user, and all is well.
// but if we're updating a current record, then it'll 409 first
- if (error && !this.auth) {
+ if (error && !this.conf.get('_auth')) {
// must be trying to re-auth on a new machine.
// use this info as auth
var b = new Buffer(username + ":" + password)
- this.auth = b.toString("base64")
- this.username = username
- this.password = password
+ this.conf.set('_auth', b.toString("base64"))
+ this.conf.set('username', username)
+ this.conf.set('_password', password)
}
if (!error || !response || response.statusCode !== 409) {
@@ -114,16 +114,16 @@ function done (cb, pre) {
}
// there was some kind of error, re-instate previous auth/token/etc.
- this.token = pre.token
+ this.conf.set('_token', pre.token)
if (this.couchLogin) {
- this.couchLogin.token = this.token
+ this.couchLogin.token = pre.token
if (this.couchLogin.tokenSet) {
this.couchLogin.tokenSet(pre.token)
}
}
- this.username = pre.username
- this.password = pre.password
- this.auth = pre.auth
+ this.conf.set('username', pre.username)
+ this.conf.set('_password', pre.password)
+ this.conf.set('_auth', pre.auth)
this.log.verbose("adduser", "back", [error, data, json])
if (!error) {
View
24 node_modules/npm-registry-client/lib/get.js
@@ -12,10 +12,10 @@ function get (uri, timeout, nofollow, staleOk, cb) {
if (typeof cb !== "function") cb = timeout, timeout = -1
if (typeof cb !== "function") cb = version, version = null
- timeout = Math.min(timeout, this.cacheMax)
- timeout = Math.max(timeout, this.cacheMin)
+ timeout = Math.min(timeout, this.conf.get('cache-max') || 0)
+ timeout = Math.max(timeout, this.conf.get('cache-min') || Infinity)
- if (!this.registry) timeout = Infinity
+ if (!this.conf.get('registry')) timeout = Infinity
if ( process.env.COMP_CWORD !== undefined
&& process.env.COMP_LINE !== undefined
@@ -29,7 +29,7 @@ function get (uri, timeout, nofollow, staleOk, cb) {
return requestAll.call(this, cb)
}
- var cache = path.join(this.cache, uri, ".cache.json")
+ var cache = path.join(this.conf.get('cache'), uri, ".cache.json")
fs.stat(cache, function (er, stat) {
if (!er) fs.readFile(cache, function (er, data) {
try { data = JSON.parse(data) }
@@ -41,9 +41,9 @@ function get (uri, timeout, nofollow, staleOk, cb) {
}
function requestAll (cb) {
- var cache = path.join(this.cache, "/-/all", ".cache.json")
+ var cache = path.join(this.conf.get('cache'), "/-/all", ".cache.json")
- mkdir(path.join(this.cache, "-", "all"), function (er) {
+ mkdir(path.join(this.conf.get('cache'), "-", "all"), function (er) {
fs.readFile(cache, function (er, data) {
if (er) return requestAll_.call(this, 0, {}, cb)
try {
@@ -74,7 +74,7 @@ function requestAll_ (c, data, cb) {
uri = "/-/all"
}
- var cache = path.join(this.cache, "-/all", ".cache.json")
+ var cache = path.join(this.conf.get('cache'), "-/all", ".cache.json")
this.request('GET', uri, function (er, updates, _, res) {
if (er) return cb(er, data)
var headers = res.headers
@@ -143,20 +143,20 @@ function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) {
}
function saveToCache (cache, data, saved) {
- if (this.cacheStat) {
- var cs = this.cacheStat
+ if (this._cacheStat) {
+ var cs = this._cacheStat
return saveToCache_.call(this, cache, data, cs.uid, cs.gid, saved)
}
- fs.stat(this.cache, function (er, st) {
+ fs.stat(this.conf.get('cache'), function (er, st) {
if (er) {
return fs.stat(process.env.HOME || "", function (er, st) {
// if this fails, oh well.
if (er) return saved()
- this.cacheStat = st
+ this._cacheStat = st
return saveToCache.call(this, cache, data, saved)
}.bind(this))
}
- this.cacheStat = st || { uid: null, gid: null }
+ this._cacheStat = st || { uid: null, gid: null }
return saveToCache.call(this, cache, data, saved)
}.bind(this))
}
View
18 node_modules/npm-registry-client/lib/publish.js
@@ -6,8 +6,14 @@ var path = require("path")
function publish (data, tarball, cb) {
- if (!this.email || !this.auth || !this.username) {
- return cb(new Error("auth and email required for publishing"))
+ var email = this.conf.get('email')
+ var auth = this.conf.get('_auth')
+ var username = this.conf.get('username')
+
+ if (!email || !auth || !username) {
+ var er = new Error("auth and email required for publishing")
+ er.code = 'ENEEDAUTH'
+ return cb(er)
}
// add the dist-url to the data, pointing at the tarball.
@@ -15,7 +21,7 @@ function publish (data, tarball, cb) {
// if the {version} is already there, then fail.
// then:
// PUT the data to {config.registry}/{data.name}/{data.version}
- var registry = this.registry
+ var registry = this.conf.get('registry')
var fullData =
{ _id : data.name
@@ -25,8 +31,8 @@ function publish (data, tarball, cb) {
, versions : {}
, readme: data.readme || ""
, maintainers :
- [ { name : this.username
- , email : this.email
+ [ { name : username
+ , email : email
}
]
}
@@ -58,7 +64,7 @@ function publish (data, tarball, cb) {
var dataURI = encodeURIComponent(data.name)
+ "/" + encodeURIComponent(data.version)
- var tag = data.tag || this.defaultTag || "latest"
+ var tag = data.tag || this.conf.get('tag') || "latest"
dataURI += "/-tag/" + tag
// let's see what versions are already published.
View
52 node_modules/npm-registry-client/lib/request.js
@@ -13,7 +13,8 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
if (typeof cb_ !== "function") cb_ = etag, etag = null
if (typeof cb_ !== "function") cb_ = what, what = null
- if (!this.registry) return cb(new Error(
+ var registry = this.conf.get('registry')
+ if (!registry) return cb(new Error(
"No registry url provided: " + method + " " + where))
// Since there are multiple places where an error could occur,
@@ -29,13 +30,11 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
return cb(new Error("favicon.ico isn't a package, it's a picture."))
}
- var registry = this.registry
-
var adduserChange = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)\/-rev/
, adduserNew = /^\/?-\/user\/org\.couchdb\.user:([^\/]+)/
, nu = where.match(adduserNew)
, uc = where.match(adduserChange)
- , isUpload = what || this.alwaysAuth
+ , isUpload = what || this.conf.get('always-auth')
, isDel = method === "DELETE"
, authRequired = isUpload && !nu || uc || isDel
@@ -62,15 +61,15 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
}
var remote = url.parse(where)
- , auth = this.auth
+ , auth = this.conf.get('_auth')
- if (authRequired && !this.alwaysAuth) {
+ if (authRequired && !this.conf.get('always-auth')) {
var couch = this.couchLogin
- , token = couch && (this.token || couch.token)
+ , token = couch && (this.conf.get('_token') || couch.token)
, validToken = token && couch.valid(token)
if (!validToken) token = null
- else this.token = token
+ else this.conf.set('_token', token)
if (couch && !token) {
// login to get a valid token
@@ -81,8 +80,10 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
er = er || new Error('login error')
return cb(er, cr, data)
}
- this.token = this.couchLogin.token
- return regRequest.call(this, method, where, what, etag, nofollow, cb_)
+ this.conf.set('_token', this.couchLogin.token)
+ return regRequest.call(this,
+ method, where, what,
+ etag, nofollow, cb_)
}.bind(this))
}
}
@@ -101,11 +102,12 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
// Tuned to spread 3 attempts over about a minute.
// See formula at <https://github.com/tim-kos/node-retry>.
var operation = retry.operation({
- retries: this.retries,
- factor: this.retryFactor,
- minTimeout: this.retryMinTimeout,
- maxTimeout: this.retryMaxTimeout
+ retries: this.conf.get('fetch-retries') || 2,
+ factor: this.conf.get('fetch-retry-factor'),
+ minTimeout: this.conf.get('fetch-retry-mintimeout') || 10000,
+ maxTimeout: this.conf.get('fetch-retry-maxtimeout') || 60000
})
+
var self = this
operation.attempt(function (currentAttempt) {
self.log.info("retry", "registry request attempt " + currentAttempt
@@ -118,8 +120,8 @@ function regRequest (method, where, what, etag, nofollow, cb_) {
var timeout = statusCode === 408
var serverError = statusCode >= 500
var statusRetry = !statusCode || timeout || serverError
- if (reauth && this.auth && this.token) {
- this.token = null
+ if (reauth && this.conf.get('_auth') && this.conf.get('_token')) {
+ this.conf.del('_token')
this.couchLogin.token = null
return regRequest.call(this, method, where, what, etag, nofollow, cb_)
}
@@ -140,10 +142,12 @@ function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
cb_.apply(null, arguments)
}
+ var strict = this.conf.get('strict-ssl')
+ if (strict === undefined) strict = true
var opts = { url: remote
, method: method
- , ca: this.ca
- , strictSSL: this.strictSSL }
+ , ca: this.conf.get('ca')
+ , strictSSL: strict }
, headers = opts.headers = {}
if (etag) {
this.log.verbose("etag", etag)
@@ -156,10 +160,12 @@ function makeRequest (method, remote, where, what, etag, nofollow, tok, cb_) {
headers.accept = "application/json"
- headers["user-agent"] = this.userAgent
+ headers["user-agent"] = this.conf.get('user-agent') ||
+ 'node/' + process.version
- opts.proxy = remote.protocol === "https:"
- ? this.httpsProxy : this.proxy
+ var p = this.conf.get('proxy')
+ var sp = this.conf.get('https-proxy') || p
+ opts.proxy = remote.protocol === "https:" ? sp : p
// figure out wth 'what' is
if (what) {
@@ -259,7 +265,7 @@ function requestDone (method, where, cb) {
, caches = p.map(function (part) {
return _ = path.join(_, part)
}).map(function (cache) {
- return path.join(this.cache, cache, ".cache.json")
+ return path.join(this.conf.get('cache'), cache, ".cache.json")
}, this)
// if the method is DELETE, then also remove the thing itself.
@@ -267,7 +273,7 @@ function requestDone (method, where, cb) {
// That's what you get for deleting stuff. Don't do that.
if (method === "DELETE") {
p = p.slice(0, p.indexOf("-rev"))
- caches.push(path.join(this.cache, p.join("/")))
+ caches.push(path.join(this.conf.get('cache'), p.join("/")))
}
asyncMap(caches, rm, function () {})
View
8 node_modules/npm-registry-client/package.json
@@ -6,7 +6,7 @@
},
"name": "npm-registry-client",
"description": "Client for the npm registry",
- "version": "0.1.4",
+ "version": "0.2.2",
"repository": {
"url": "git://github.com/isaacs/npm-registry-client"
},
@@ -34,7 +34,7 @@
"npmlog": ""
},
"license": "BSD",
- "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(options)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Options\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `alwaysAuth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strictSSL` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `userAgent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `retries` {Number} Number of times to retry on GET failures.\n Default=2\n* `retryFactor` {Number} `factor` setting for `node-retry`. Default=10\n* `retryMinTimeout` {Number} `minTimeout` setting for `node-retry`.\n Default=10000 (10 seconds)\n* `retryMaxTimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default=60000 (60 seconds)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n",
- "_id": "npm-registry-client@0.1.4",
- "_from": "npm-registry-client@latest"
+ "readme": "# npm-registry-client\n\nThe code that npm uses to talk to the registry.\n\nIt handles all the caching and HTTP calls.\n\n## Usage\n\n```javascript\nvar RegClient = require('npm-registry-client')\nvar client = new RegClient(config)\n\nclient.get(\"npm\", \"latest\", 1000, function (er, data, raw, res) {\n // error is an error if there was a problem.\n // data is the parsed data object\n // raw is the json string\n // res is the response from couch\n})\n```\n\n# Configuration\n\nThis program is designed to work with\n[npmconf](https://npmjs.org/package/npmconf), but you can also pass in\na plain-jane object with the appropriate configs, and it'll shim it\nfor you. Any configuration thingie that has get/set/del methods will\nalso be accepted.\n\n* `registry` **Required** {String} URL to the registry\n* `cache` **Required** {String} Path to the cache folder\n* `always-auth` {Boolean} Auth even for GET requests.\n* `auth` {String} A base64-encoded `username:password`\n* `email` {String} User's email address\n* `tag` {String} The default tag to use when publishing new packages.\n Default = `\"latest\"`\n* `ca` {String} Cerficate signing authority certificates to trust.\n* `strict-ssl` {Boolean} Whether or not to be strict with SSL\n certificates. Default = `true`\n* `user-agent` {String} User agent header to send. Default =\n `\"node/{process.version}\"`\n* `log` {Object} The logger to use. Defaults to `require(\"npmlog\")` if\n that works, otherwise logs are disabled.\n* `fetch-retries` {Number} Number of times to retry on GET failures.\n Default=2\n* `fetch-retry-factor` {Number} `factor` setting for `node-retry`. Default=10\n* `fetch-retry-mintimeout` {Number} `minTimeout` setting for `node-retry`.\n Default=10000 (10 seconds)\n* `fetch-retry-maxtimeout` {Number} `maxTimeout` setting for `node-retry`.\n Default=60000 (60 seconds)\n* `proxy` {URL} The url to proxy requests through.\n* `https-proxy` {URL} The url to proxy https requests through.\n Defaults to be the same as `proxy` if unset.\n* `_auth` {String} The base64-encoded authorization header.\n* `username` `_password` {String} Username/password to use to generate\n `_auth` if not supplied.\n* `_token` {Object} A token for use with\n [couch-login](https://npmjs.org/package/couch-login)\n\n# client.request(method, where, [what], [etag], [nofollow], cb)\n\n* `method` {String} HTTP method\n* `where` {String} Path to request on the server\n* `what` {Stream | Buffer | String | Object} The request body. Objects\n that are not Buffers or Streams are encoded as JSON.\n* `etag` {String} The cached ETag\n* `nofollow` {Boolean} Prevent following 302/301 responses\n* `cb` {Function}\n * `error` {Error | null}\n * `data` {Object} the parsed data object\n * `raw` {String} the json\n * `res` {Response Object} response from couch\n\nMake a request to the registry. All the other methods are wrappers\naround this. one.\n\n# client.adduser(username, password, email, cb)\n\n* `username` {String}\n* `password` {String}\n* `email` {String}\n* `cb` {Function}\n\nAdd a user account to the registry, or verify the credentials.\n\n# client.get(url, [timeout], [nofollow], [staleOk], cb)\n\n* `url` {String} The url path to fetch\n* `timeout` {Number} Number of seconds old that a cached copy must be\n before a new request will be made.\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `staleOk` {Boolean} If there's cached data available, then return that\n to the callback quickly, and update the cache the background.\n\nFetches data from the registry via a GET request, saving it in\nthe cache folder with the ETag.\n\n# client.publish(data, tarball, [readme], cb)\n\n* `data` {Object} Package data\n* `tarball` {String | Stream} Filename or stream of the package tarball\n* `readme` {String} Contents of the README markdown file\n* `cb` {Function}\n\nPublish a package to the registry.\n\nNote that this does not create the tarball from a folder. However, it\ncan accept a gzipped tar stream or a filename to a tarball.\n\n# client.star(package, starred, cb)\n\n* `package` {String} Name of the package to star\n* `starred` {Boolean} True to star the package, false to unstar it.\n* `cb` {Function}\n\nStar or unstar a package.\n\nNote that the user does not have to be the package owner to star or\nunstar a package, though other writes do require that the user be the\npackage owner.\n\n# client.tag(project, version, tag, cb)\n\n* `project` {String} Project name\n* `version` {String} Version to tag\n* `tag` {String} Tag name to apply\n* `cb` {Function}\n\nMark a version in the `dist-tags` hash, so that `pkg@tag`\nwill fetch the specified version.\n\n# client.unpublish(name, [ver], cb)\n\n* `name` {String} package name\n* `ver` {String} version to unpublish. Leave blank to unpublish all\n versions.\n* `cb` {Function}\n\nRemove a version of a package (or all versions) from the registry. When\nthe last version us unpublished, the entire document is removed from the\ndatabase.\n\n# client.upload(where, file, [etag], [nofollow], cb)\n\n* `where` {String} URL path to upload to\n* `file` {String | Stream} Either the filename or a readable stream\n* `etag` {String} Cache ETag\n* `nofollow` {Boolean} Do not follow 301/302 responses\n* `cb` {Function}\n\nUpload an attachment. Mostly used by `client.publish()`.\n",
+ "_id": "npm-registry-client@0.2.2",
+ "_from": "npm-registry-client@~0.2.1"
}
View
6 node_modules/npm-registry-client/test/retries.js
@@ -5,9 +5,9 @@ var pkg = { _id: 'some-package@1.2.3',
name: 'some-package',
version: '1.2.3' }
var client = new RC({
- retries: 6
- , retryMinTimeout: 10
- , retryMaxTimeout: 100
+ 'fetch-retries': 6
+ , 'fetch-retry-mintimeout': 10
+ , 'fetch-retry-maxtimeout': 100
, cache: __dirname + '/fixtures/cache'
, registry: 'http://localhost:' + server.port })
View
15 node_modules/read/README.md
@@ -33,6 +33,21 @@ Every option is optional.
If silent is true, and the input is a TTY, then read will set raw
mode, and read character by character.
+## COMPATIBILITY
+
+This module works sort of with node 0.6. It does not work with node
+versions less than 0.6. It is best on node 0.8.
+
+On node version 0.6, it will remove all listeners on the input
+stream's `data` and `keypress` events, because the readline module did
+not fully clean up after itself in that version of node, and did not
+make it possible to clean up after it in a way that has no potential
+for side effects.
+
+Additionally, some of the readline options (like `terminal`) will not
+function in versions of node before 0.8, because they were not
+implemented in the builtin readline module.
+
## CONTRIBUTING
Patches welcome.
View
15 node_modules/read/lib/read.js
@@ -23,7 +23,13 @@ function read (opts, cb) {
var def = opts.default || ''
var terminal = !!(opts.terminal || output.isTTY)
var rlOpts = { input: input, output: output, terminal: terminal }
- var rl = readline.createInterface(rlOpts)
+
+ if (process.version.match(/^v0\.6/)) {
+ var rl = readline.createInterface(rlOpts.input, rlOpts.output)
+ } else {
+ var rl = readline.createInterface(rlOpts)
+ }
+
var prompt = (opts.prompt || '').trim() + ' '
var silent = opts.silent
var editDef = false
@@ -69,6 +75,13 @@ function read (opts, cb) {
function done () {
called = true
rl.close()
+
+ if (process.version.match(/^v0\.6/)) {
+ rl.input.removeAllListeners('data')
+ rl.input.removeAllListeners('keypress')
+ rl.input.pause()
+ }
+
clearTimeout(timer)
output.mute()
output.end()
View
15 node_modules/read/node_modules/mute-stream/mute.js
@@ -63,6 +63,21 @@ function setIsTTY (isTTY) {
})
}
+Object.defineProperty(MuteStream.prototype, 'rows', {
+ get: function () {
+ return( this._dest ? this._dest.rows
+ : this._src ? this._src.rows
+ : undefined )
+ }, enumerable: true, configurable: true })
+
+Object.defineProperty(MuteStream.prototype, 'columns', {
+ get: function () {
+ return( this._dest ? this._dest.columns
+ : this._src ? this._src.columns
+ : undefined )
+ }, enumerable: true, configurable: true })
+
+
MuteStream.prototype.pipe = function (dest) {
this._dest = dest
return Stream.prototype.pipe.call(this, dest)
View
7 node_modules/read/node_modules/mute-stream/package.json
@@ -1,6 +1,6 @@
{
"name": "mute-stream",
- "version": "0.0.2",
+ "version": "0.0.3",
"main": "mute.js",
"directories": {
"test": "test"
@@ -28,9 +28,6 @@
"license": "BSD",
"description": "Bytes go in, but they don't come out (when muted).",
"readme": "# mute-stream\n\nBytes go in, but they don't come out (when muted).\n\nThis is a basic pass-through stream, but when muted, the bytes are\nsilently dropped, rather than being passed through.\n\n## Usage\n\n```javascript\nvar MuteStream = require('mute-stream')\n\nvar ms = new MuteStream(options)\n\nms.pipe(process.stdout)\nms.write('foo') // writes 'foo' to stdout\nms.mute()\nms.write('bar') // does not write 'bar'\nms.unmute()\nms.write('baz') // writes 'baz' to stdout\n\n// can also be used to mute incoming data\nvar ms = new MuteStream\ninput.pipe(ms)\n\nms.on('data', function (c) {\n console.log('data: ' + c)\n})\n\ninput.emit('data', 'foo') // logs 'foo'\nms.mute()\ninput.emit('data', 'bar') // does not log 'bar'\nms.unmute()\ninput.emit('data', 'baz') // logs 'baz'\n```\n\n## Options\n\nAll options are optional.\n\n* `replace` Set to a string to replace each character with the\n specified string when muted. (So you can show `****` instead of the\n password, for example.)\n\n## ms.mute()\n\nSet `muted` to `true`. Turns `.write()` into a no-op.\n\n## ms.unmute()\n\nSet `muted` to `false`\n\n## ms.isTTY\n\nTrue if the pipe destination is a TTY, or if the incoming pipe source is\na TTY.\n\n## Other stream methods...\n\nThe other standard readable and writable stream methods are all\navailable. The MuteStream object acts as a facade to its pipe source\nand destination.\n",
- "_id": "mute-stream@0.0.2",
- "dist": {
- "shasum": "75d4466df24a57e80fec806bda88561cd0560d2d"
- },
+ "_id": "mute-stream@0.0.3",
"_from": "mute-stream@~0.0.2"
}
View
12 node_modules/read/node_modules/mute-stream/test/basic.js
@@ -89,17 +89,29 @@ tap.test('outgoing', function (t) {
tap.test('isTTY', function (t) {
var str = new PassThrough
str.isTTY = true
+ str.columns=80
+ str.rows=24
var ms = new MS
t.equal(ms.isTTY, false)
+ t.equal(ms.columns, undefined)
+ t.equal(ms.rows, undefined)
ms.pipe(str)
t.equal(ms.isTTY, true)
+ t.equal(ms.columns, 80)
+ t.equal(ms.rows, 24)
str.isTTY = false
t.equal(ms.isTTY, false)
+ t.equal(ms.columns, 80)
+ t.equal(ms.rows, 24)
str.isTTY = true
t.equal(ms.isTTY, true)
+ t.equal(ms.columns, 80)
+ t.equal(ms.rows, 24)
ms.isTTY = false
t.equal(ms.isTTY, false)
+ t.equal(ms.columns, 80)
+ t.equal(ms.rows, 24)
ms = new MS
t.equal(ms.isTTY, false)
View
8 node_modules/read/package.json
@@ -1,6 +1,6 @@
{
"name": "read",
- "version": "1.0.3",
+ "version": "1.0.4",
"main": "lib/read.js",
"dependencies": {
"mute-stream": "~0.0.2"
@@ -25,7 +25,7 @@
"scripts": {
"test": "tap test/*.js"
},
- "readme": "## read\n\nFor reading user input from stdin.\n\nSimilar to the `readline` builtin's `question()` method, but with a\nfew more features.\n\n## USAGE\n\n```javascript\nvar read = require(\"read\")\nread(options, callback)\n```\n\nThe callback gets called with either the user input, or the default\nspecified, or an error, as `callback(error, result, isDefault)`\nnode style.\n\n## OPTIONS\n\nEvery option is optional.\n\n* `prompt` What to write to stdout before reading input.\n* `silent` Don't echo the output as the user types it.\n* `replace` Replace silenced characters with the supplied character value.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n* `edit` Allow the user to edit the default value.\n* `terminal` Treat the output as a TTY, whether it is or not.\n* `stdin` Readable stream to get input data from. (default `process.stdin`)\n* `stdout` Writeable stream to write prompts to. (default: `process.stdout`)\n\nIf silent is true, and the input is a TTY, then read will set raw\nmode, and read character by character.\n\n## CONTRIBUTING\n\nPatches welcome.\n",
- "_id": "read@1.0.3",
- "_from": "read@~1"
+ "readme": "## read\n\nFor reading user input from stdin.\n\nSimilar to the `readline` builtin's `question()` method, but with a\nfew more features.\n\n## USAGE\n\n```javascript\nvar read = require(\"read\")\nread(options, callback)\n```\n\nThe callback gets called with either the user input, or the default\nspecified, or an error, as `callback(error, result, isDefault)`\nnode style.\n\n## OPTIONS\n\nEvery option is optional.\n\n* `prompt` What to write to stdout before reading input.\n* `silent` Don't echo the output as the user types it.\n* `replace` Replace silenced characters with the supplied character value.\n* `timeout` Number of ms to wait for user input before giving up.\n* `default` The default value if the user enters nothing.\n* `edit` Allow the user to edit the default value.\n* `terminal` Treat the output as a TTY, whether it is or not.\n* `stdin` Readable stream to get input data from. (default `process.stdin`)\n* `stdout` Writeable stream to write prompts to. (default: `process.stdout`)\n\nIf silent is true, and the input is a TTY, then read will set raw\nmode, and read character by character.\n\n## COMPATIBILITY\n\nThis module works sort of with node 0.6. It does not work with node\nversions less than 0.6. It is best on node 0.8.\n\nOn node version 0.6, it will remove all listeners on the input\nstream's `data` and `keypress` events, because the readline module did\nnot fully clean up after itself in that version of node, and did not\nmake it possible to clean up after it in a way that has no potential\nfor side effects.\n\nAdditionally, some of the readline options (like `terminal`) will not\nfunction in versions of node before 0.8, because they were not\nimplemented in the builtin readline module.\n\n## CONTRIBUTING\n\nPatches welcome.\n",
+ "_id": "read@1.0.4",
+ "_from": "read@~1.0.3"
}
View
7 node_modules/read/test/basic.js
@@ -5,6 +5,11 @@ if (process.argv[2] === 'child') {
return child()
}
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+ CLOSE = 'exit'
+}
+
var spawn = require('child_process').spawn
tap.test('basic', function (t) {
@@ -31,7 +36,7 @@ tap.test('basic', function (t) {
console.error('result %j', c.toString())
})
- child.on('close', function () {
+ child.on(CLOSE, function () {
result = JSON.parse(result)
t.same(result, {"user":"a user","pass":"a password","verify":"a password","passMatch":true})
t.equal(output, 'Username: (test-user) Password: (<default hidden>) Password again: (<default hidden>) ')
View
7 node_modules/read/test/defaults.js
@@ -5,6 +5,11 @@ if (process.argv[2] === 'child') {
return child()
}
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+ CLOSE = 'exit'
+}
+
var spawn = require('child_process').spawn
tap.test('defaults', function (t) {
@@ -31,7 +36,7 @@ tap.test('defaults', function (t) {
console.error('result %j', c.toString())
})
- child.on('close', function () {
+ child.on(CLOSE, function () {
result = JSON.parse(result)
t.same(result, {"user":"test-user","pass":"test-pass","verify":"test-pass","passMatch":true})
t.equal(output, 'Username: (test-user) Password: (<default hidden>) Password again: (<default hidden>) ')
View
7 node_modules/read/test/many.js
@@ -1,6 +1,11 @@
var tap = require('tap')
var read = require('../lib/read.js')
+var CLOSE = 'close'
+if (process.version.match(/^v0\.6/)) {
+ CLOSE = 'exit'
+}
+
if (process.argv[2] === 'child') {
return child()
}
@@ -68,7 +73,7 @@ tap.test('many reads', function (t) {
output += c
console.error('' + c)
})
- child.on('close', function (c) {
+ child.on(CLOSE, function (c) {
t.equal(output, expect)
t.equal(n, 19)
t.end()
View
2  node_modules/request/README.md
@@ -151,7 +151,7 @@ The first argument can be either a url or an options object. The only required o
* `headers` - http headers, defaults to {}
* `body` - entity body for POST and PUT requests. Must be buffer or string.
* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.
-* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.
+* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.
* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.
* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.
* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.
View
128 node_modules/request/aws2.js
@@ -1,128 +0,0 @@
-var crypto = require('crypto')
-
-// The Authentication Header
-//
-// The Amazon S3 REST API uses the standard HTTPAuthorization header to pass authentication information. (The name of the standard header is unfortunate because it carries authentication information, not authorization).Under the Amazon S3 authentication scheme, the Authorization header has the following form.
-//
-// Authorization: AWS AWSAccessKeyId:Signature
-//
-// Developers are issued an AWS Access Key ID and AWS SecretAccess Key when they register. For request authentication, theAWSAccessKeyId element identifies the secret key that was used to compute the signature, and (indirectly) the developer making the request.
-//
-// The Signature element is the RFC 2104HMAC-SHA1 of selected elements from the request, and so theSignature part of the Authorization header will vary from request to request. If the request signature calculated by the system matches theSignature included with the request, then the requester will have demonstrated possession to the AWSSecret Access Key. The request will then be processed under the identity, and with the authority, of the developer to whom the key was issued.
-//
-// Following is pseudo-grammar that illustrates the construction of the Authorization request header (\nmeans the Unicode code point U+000A commonly called newline).
-
-function authorizationHeader (accessKey) {
- // Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
-
- var authorization = 'AWS' + " " + accessKey + ":" + signature()
-
- return authorization
-}
-
-//
-
-function signature (secret, verb, md5, contenttype, date, amzheaders, bucket, path) {
- // Signature = Base64( HMAC-SHA1( UTF-8-Encoding-Of( YourSecretAccessKeyID, StringToSign ) ) );
-
- function encodeSignature (stringToSign) {
- return crypto.createHash('sha1').update(stringToSign).digest('base64')
- }
-
- //
- // StringToSign = HTTP-Verb + "\n" +
- // Content-MD5 + "\n" +
- // Content-Type + "\n" +
- // Date + "\n" +
- // CanonicalizedAmzHeaders +
- // CanonicalizedResource;
-
- function compileStringToSign () {
- var s =
- verb + '\n'
- (md5 || '') + '\n'
- (contenttype || '') + '\n'
- date.toUTCString() + '\n'
- canonicalizeAmzHeaders(amzheaders) +
- canonicalizeResource()
- return s
- }
-
- //
- // CanonicalizedResource = [ "/" + Bucket ] +
- // <HTTP-Request-URI, from the protocol name up to the query string> +
- // [ sub-resource, if present. For example "?acl", "?location", "?logging", or "?torrent"];
-
- function canonicalizeResource () {
- return '/' + bucket + path
- }
-
- //
- // CanonicalizedAmzHeaders = <described below>
- //
- // HMAC-SHA1 is an algorithm defined by RFC 2104 (go to RFC 2104 - Keyed-Hashing for Message Authentication ). The algorithm takes as input two byte-strings: a key and a message. For Amazon S3 Request authentication, use your AWS Secret Access Key (YourSecretAccessKeyID) as the key, and the UTF-8 encoding of the StringToSign as the message. The output of HMAC-SHA1 is also a byte string, called the digest. The Signature request parameter is constructed by Base64 encoding this digest.
- // Request Canonicalization for Signing
- //
- // Recall that when the system receives an authenticated request, it compares the computed request signature with the signature provided in the request in StringToSign. For that reason, you must compute the signature using the same method used by Amazon S3. We call the process of putting a request in an agreed-upon form for signing "canonicalization".
-
-}
-
-
-
-// Constructing the CanonicalizedResource Element
-//
-// CanonicalizedResource represents the Amazon S3 resource targeted by the request. Construct it for a REST request as follows:
-//
-// Launch Process
-//
-// 1
-//
-//
-// Start with the empty string ("").
-//
-// 2
-//
-//
-// If the request specifies a bucket using the HTTP Host header (virtual hosted-style), append the bucket name preceded by a "/" (e.g., "/bucketname"). For path-style requests and requests that don't address a bucket, do nothing. For more information on virtual hosted-style requests, see Virtual Hosting of Buckets.
-//
-// 3
-//
-//
-// Append the path part of the un-decoded HTTP Request-URI, up-to but not including the query string.
-//
-// 4
-//
-//
-// If the request addresses a sub-resource, like ?versioning, ?location, ?acl, ?torrent, ?lifecycle, or ?versionid append the sub-resource, its value if it has one, and the question mark. Note that in case of multiple sub-resources, sub-resources must be lexicographically sorted by sub-resource name and separated by '&'. e.g. ?acl&versionId=value.
-//
-// The list of sub-resources that must be included when constructing the CanonicalizedResource Element are: acl, lifecycle, location, logging, notification, partNumber, policy, requestPayment, torrent, uploadId, uploads, versionId, versioning, versions and website.
-//
-// If the request specifies query string parameters overriding the response header values (see Get Object), append the query string parameters, and its values. When signing you do not encode these values. However, when making the request, you must encode these parameter values. The query string parameters in a GET request include response-content-type, response-content-language, response-expires, response-cache-control, response-content-disposition, response-content-encoding.
-//
-// The delete query string parameter must be including when creating the CanonicalizedResource for a Multi-Object Delete request.
-//
-// Elements of the CanonicalizedResource that come from the HTTP Request-URI should be signed literally as they appear in the HTTP request, including URL-Encoding meta characters.
-//
-// The CanonicalizedResource might be different than the HTTP Request-URI. In particular, if your request uses the HTTP Host header to specify a bucket, the bucket does appear in the HTTP Request-URI. However, the CanonicalizedResource continues to include the bucket. Query string parameters might also appear in the Request-URI but are not included in CanonicalizedResource. For more information, see Virtual Hosting of Buckets.
-// Constructing the CanonicalizedAmzHeaders Element
-//
-// To construct the CanonicalizedAmzHeaders part of StringToSign, select all HTTP request headers that start with 'x-amz-' (using a case-insensitive comparison) and use the following process.
-//
-// CanonicalizedAmzHeaders Process
-// 1 Convert each HTTP header name to lower-case. For example, 'X-Amz-Date' becomes 'x-amz-date'.
-// 2 Sort the collection of headers lexicographically by header name.
-// 3 Combine header fields with the same name into one "header-name:comma-separated-value-list" pair as prescribed by RFC 2616, section 4.2, without any white-space between values. For example, the two metadata headers 'x-amz-meta-username: fred' and 'x-amz-meta-username: barney' would be combined into the single header 'x-amz-meta-username: fred,barney'.
-// 4 "Unfold" long headers that span multiple lines (as allowed by RFC 2616, section 4.2) by replacing the folding white-space (including new-line) by a single space.
-// 5 Trim any white-space around the colon in the header. For example, the header 'x-amz-meta-username: fred,barney' would become 'x-amz-meta-username:fred,barney'
-// 6 Finally, append a new-line (U+000A) to each canonicalized header in the resulting list. Construct the CanonicalizedResource element by concatenating all headers in this list into a single string.
-//
-// Positional versus Named HTTP Header StringToSign Elements
-//
-// The first few header elements of StringToSign (Content-Type, Date, and Content-MD5) are positional in nature. StringToSign does not include the names of these headers, only their values from the request. In contrast, the 'x-amz-' elements are named; Both the header names and the header values appear in StringToSign.
-//
-// If a positional header called for in the definition of StringToSign is not present in your request, (Content-Type or Content-MD5, for example, are optional for PUT requests, and meaningless for GET requests), substitute the empty string ("") in for that position.
-// Time Stamp Requirement
-//
-// A valid time stamp (using either the HTTP Date header or an x-amz-date alternative) is mandatory for authenticated requests. Furthermore, the client time-stamp included with an authenticated request must be within 15 minutes of the Amazon S3 system time when the request is received. If not, the request will fail with the RequestTimeTooSkewed error status code. The intention of these restrictions is to limit the possibility that intercepted requests could be replayed by an adversary. For stronger protection against eavesdropping, use the HTTPS transport for authenticated requests.
-//
-// Some HTTP client libraries do not expose the ability to set the Date header for a request. If you have trouble including the value of the 'Date' header in the canonicalized headers, you can set the time-stamp for the request using an 'x-amz-date' header instead. The value of the x-amz-date header must be in one of the RFC 2616 formats (http://www.ietf.org/rfc/rfc2616.txt). When an x-amz-date header is present in a request, the system will ignore any Date header when computing the request signature. Therefore, if you include the x-amz-date header, use the empty string for the Date when constructing the StringToSign. See the next section for an example.
View
148 node_modules/request/main.js
@@ -107,7 +107,7 @@ Request.prototype.init = function (options) {
var self = this
if (!options) options = {}
-
+ if (process.env.NODE_DEBUG && /request/.test(process.env.NODE_DEBUG)) console.error('REQUEST', options)
if (!self.pool && self.pool !== false) self.pool = globalPool
self.dests = []
self.__isRequestRequest = true
@@ -140,12 +140,11 @@ Request.prototype.init = function (options) {
// do the HTTP CONNECT dance using koichik/node-tunnel
if (http.globalAgent && self.uri.protocol === "https:") {
- self.tunnel = true
var tunnelFn = self.proxy.protocol === "http:"
? tunnel.httpsOverHttp : tunnel.httpsOverHttps
var tunnelOptions = { proxy: { host: self.proxy.hostname
- , port: +self.proxy.port
+ , port: +self.proxy.port
, proxyAuth: self.proxy.auth }
, ca: this.ca }
@@ -223,6 +222,18 @@ Request.prototype.init = function (options) {
self.emit('error', error)
}
+ self._parserErrorHandler = function (error) {
+ if (this.res) {
+ if (this.res.request) {
+ this.res.request.emit('error', error)
+ } else {
+ this.res.emit('error', error)
+ }
+ } else {
+ this._httpMessage.emit('error', error)
+ }
+ }
+
if (options.form) {
self.form(options.form)
}
@@ -319,7 +330,7 @@ Request.prototype.init = function (options) {
}
self.once('pipe', function (src) {
- if (self.ntick) throw new Error("You cannot pipe to this stream after the first nextTick() after creation of the request stream.")
+ if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.")
self.src = src
if (isReadStream(src)) {
if (!self.headers['content-type'] && !self.headers['Content-Type'])
@@ -367,6 +378,70 @@ Request.prototype.init = function (options) {
})
}
+// Must call this when following a redirect from https to http or vice versa
+// Attempts to keep everything as identical as possible, but update the
+// httpModule, Tunneling agent, and/or Forever Agent in use.
+Request.prototype._updateProtocol = function () {
+ var self = this
+ var protocol = self.uri.protocol
+
+ if (protocol === 'https:') {
+ // previously was doing http, now doing https
+ // if it's https, then we might need to tunnel now.
+ if (self.proxy) {
+ self.tunnel = true
+ var tunnelFn = self.proxy.protocol === 'http:'
+ ? tunnel.httpsOverHttp : tunnel.httpsOverHttps
+ var tunnelOptions = { proxy: { host: self.proxy.hostname
+ , post: +self.proxy.port
+ , proxyAuth: self.proxy.auth }
+ , ca: self.ca }
+ self.agent = tunnelFn(tunnelOptions)
+ return
+ }
+
+ self.httpModule = https
+ switch (self.agentClass) {
+ case ForeverAgent:
+ self.agentClass = ForeverAgent.SSL
+ break
+ case http.Agent:
+ self.agentClass = https.Agent
+ break
+ default:
+ // nothing we can do. Just hope for the best.
+ return
+ }
+
+ // if there's an agent, we need to get a new one.
+ if (self.agent) self.agent = self.getAgent()
+
+ } else {
+ if (log) log('previously https, now http')
+ // previously was doing https, now doing http
+ // stop any tunneling.
+ if (self.tunnel) self.tunnel = false
+ self.httpModule = http
+ switch (self.agentClass) {
+ case ForeverAgent.SSL:
+ self.agentClass = ForeverAgent
+ break
+ case https.Agent:
+ self.agentClass = http.Agent
+ break
+ default:
+ // nothing we can do. just hope for the best
+ return
+ }
+
+ // if there's an agent, then get a new one.
+ if (self.agent) {
+ self.agent = null
+ self.agent = self.getAgent()
+ }
+ }
+}
+
Request.prototype.getAgent = function () {
var Agent = this.agentClass
var options = {}
@@ -392,7 +467,11 @@ Request.prototype.getAgent = function () {
poolKey += this.host + ':' + this.port
}
- if (options.ca) {
+ // ca option is only relevant if proxy or destination are https
+ var proxy = this.proxy
+ if (typeof proxy === 'string') proxy = url.parse(proxy)
+ var caRelevant = (proxy && proxy.protocol === 'https:') || this.uri.protocol === 'https:'
+ if (options.ca && caRelevant) {
if (poolKey) poolKey += ':'
poolKey += options.ca
}
@@ -402,6 +481,9 @@ Request.prototype.getAgent = function () {
return this.httpModule.globalAgent
}
+ // we're using a stored agent. Make sure it's protocol-specific
+ poolKey = this.uri.protocol + poolKey
+
// already generated an agent for this setting
if (this.pool[poolKey]) return this.pool[poolKey]
@@ -410,25 +492,28 @@ Request.prototype.getAgent = function () {
Request.prototype.start = function () {
var self = this
-
+
if (self._aborted) return
-
+
self._started = true
self.method = self.method || 'GET'
self.href = self.uri.href
if (log) log('%method %href', self)
-
+
if (self.src && self.src.stat && self.src.stat.size) {
self.headers['content-length'] = self.src.stat.size
}
if (self._aws) {
self.aws(self._aws, true)
}
-
+
self.req = self.httpModule.request(self, function (response) {
+ if (response.connection.listeners('error').indexOf(self._parserErrorHandler) === -1) {
+ response.connection.once('error', self._parserErrorHandler)
+ }
if (self._aborted) return
if (self._paused) response.pause()
-
+
self.response = response
response.request = self
response.toJSON = toJSON
@@ -446,7 +531,7 @@ Request.prototype.start = function () {
clearTimeout(self.timeoutTimer)
self.timeoutTimer = null
}
-
+
var addCookie = function (cookie) {
if (self._jar) self._jar.add(new Cookie(cookie))
else cookieJar.add(new Cookie(cookie))
@@ -470,7 +555,15 @@ Request.prototype.start = function () {
if (!isUrl.test(response.headers.location)) {
response.headers.location = url.resolve(self.uri.href, response.headers.location)
}
- self.uri = response.headers.location
+
+ var uriPrev = self.uri
+ self.uri = url.parse(response.headers.location)
+
+ // handle the case where we change protocol from https to http or vice versa
+ if (self.uri.protocol !== uriPrev.protocol) {
+ self._updateProtocol()
+ }
+
self.redirects.push(
{ statusCode : response.statusCode
, redirectUri: response.headers.location
@@ -540,7 +633,7 @@ Request.prototype.start = function () {
if (self.encoding === null) {
response.body = body
} else {
- response.body = body.toString()
+ response.body = body.toString(self.encoding)
}
} else if (buffer.length) {
response.body = buffer.join('')
@@ -584,7 +677,9 @@ Request.prototype.start = function () {
self.req.on('drain', function() {
self.emit('drain')
})
-
+ self.on('end', function() {
+ self.req.connection.removeListener('error', self._parserErrorHandler)
+ })
self.emit('request', self.req)
}
@@ -659,10 +754,12 @@ Request.prototype.multipart = function (multipart) {
self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary;
}
- console.log('boundary >> ' + self.boundary)
-
if (!multipart.forEach) throw new Error('Argument error, options.multipart.')
+ if (self.preambleCRLF) {
+ self.body.push(new Buffer('\r\n'))
+ }
+
multipart.forEach(function (part) {
var body = part.body
if(body == null) throw Error('Body attribute missing in multipart.')
@@ -747,6 +844,7 @@ Request.prototype.oauth = function (_oauth) {
// skip
} else {
delete oa['oauth_'+i]
+ delete oa[i]
}
}
this.headers.Authorization =
@@ -861,16 +959,25 @@ function request (uri, options, callback) {
module.exports = request
-request.defaults = function (options) {
+request.initParams = initParams;
+
+request.defaults = function (options, requester) {
var def = function (method) {
var d = function (uri, opts, callback) {
var params = initParams(uri, opts, callback);
for (var i in options) {
if (params.options[i] === undefined) params.options[i] = options[i]
}
- return method(params.options, params.callback)
+ if(typeof requester === 'function') {
+ if(method === request) {
+ method = requester;
+ } else {
+ params.options._requester = requester;
+ }
+ }
+ return method(params.options, params.callback);
}
- return d
+ return d;
}
var de = def(request)
de.get = def(request.get)
@@ -920,6 +1027,9 @@ request.head = function (uri, options, callback) {
request.del = function (uri, options, callback) {
var params = initParams(uri, options, callback);
params.options.method = 'DELETE'
+ if(typeof params.options._requester === 'function') {
+ request = params.options._requester;
+ }
return request(params.uri || null, params.options, params.callback)
}
request.jar = function () {
View
6 node_modules/request/package.json
@@ -26,10 +26,10 @@
"scripts": {
"test": "node tests/run.js"
},
- "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n npm install request\n</pre>\n\nOr from source:\n\n<pre>\n git clone git://github.com/mikeal/request.git \n cd request\n npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Assume by some stretch of magic you aquired the verifier\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: VERIFIER\n , token_secret: access_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n",
+ "readme": "# Request -- Simplified HTTP request method\n\n## Install\n\n<pre>\n npm install request\n</pre>\n\nOr from source:\n\n<pre>\n git clone git://github.com/mikeal/request.git \n cd request\n npm link\n</pre>\n\n## Super simple to use\n\nRequest is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.\n\n```javascript\nvar request = require('request');\nrequest('http://www.google.com', function (error, response, body) {\n if (!error && response.statusCode == 200) {\n console.log(body) // Print the google web page.\n }\n})\n```\n\n## Streaming\n\nYou can stream any response to a file stream.\n\n```javascript\nrequest('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))\n```\n\nYou can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.\n\n```javascript\nfs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))\n```\n\nRequest can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.\n\n```javascript\nrequest.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))\n```\n\nNow let's get fancy.\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n if (req.method === 'PUT') {\n req.pipe(request.put('http://mysite.com/doodle.png'))\n } else if (req.method === 'GET' || req.method === 'HEAD') {\n request.get('http://mysite.com/doodle.png').pipe(resp)\n } \n }\n})\n```\n\nYou can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:\n\n```javascript\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n var x = request('http://mysite.com/doodle.png')\n req.pipe(x)\n x.pipe(resp)\n }\n})\n```\n\nAnd since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)\n\n```javascript\nreq.pipe(request('http://mysite.com/doodle.png')).pipe(resp)\n```\n\nAlso, none of this new functionality conflicts with requests previous features, it just expands them.\n\n```javascript\nvar r = request.defaults({'proxy':'http://localproxy.com'})\n\nhttp.createServer(function (req, resp) {\n if (req.url === '/doodle.png') {\n r.get('http://google.com/doodle.png').pipe(resp)\n }\n})\n```\n\nYou can still use intermediate proxies, the requests will still follow HTTP forwards, etc.\n\n## OAuth Signing\n\n```javascript\n// Twitter OAuth\nvar qs = require('querystring')\n , oauth =\n { callback: 'http://mysite.com/callback/'\n , consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n }\n , url = 'https://api.twitter.com/oauth/request_token'\n ;\nrequest.post({url:url, oauth:oauth}, function (e, r, body) {\n // Assume by some stretch of magic you aquired the verifier\n var access_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: access_token.oauth_token\n , verifier: VERIFIER\n , token_secret: access_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/oauth/access_token'\n ;\n request.post({url:url, oauth:oauth}, function (e, r, body) {\n var perm_token = qs.parse(body)\n , oauth = \n { consumer_key: CONSUMER_KEY\n , consumer_secret: CONSUMER_SECRET\n , token: perm_token.oauth_token\n , token_secret: perm_token.oauth_token_secret\n }\n , url = 'https://api.twitter.com/1/users/show.json?'\n , params = \n { screen_name: perm_token.screen_name\n , user_id: perm_token.user_id\n }\n ;\n url += qs.stringify(params)\n request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {\n console.log(user)\n })\n })\n})\n```\n\n\n\n### request(options, callback)\n\nThe first argument can be either a url or an options object. The only required option is uri, all others are optional.\n\n* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()\n* `qs` - object containing querystring values to be appended to the uri\n* `method` - http method, defaults to GET\n* `headers` - http headers, defaults to {}\n* `body` - entity body for POST and PUT requests. Must be buffer or string.\n* `form` - sets `body` but to querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header.\n* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.\n* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.\n* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.\n* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.\n* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.\n* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.\n* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.\n* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.\n* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request\t\n* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.\n* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.\n* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.\n* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)\n\n\nThe callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.\n\n## Convenience methods\n\nThere are also shorthand methods for different HTTP METHODs and some other conveniences.\n\n### request.defaults(options) \n \nThis method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.\n\n### request.put\n\nSame as request() but defaults to `method: \"PUT\"`.\n\n```javascript\nrequest.put(url)\n```\n\n### request.post\n\nSame as request() but defaults to `method: \"POST\"`.\n\n```javascript\nrequest.post(url)\n```\n\n### request.head\n\nSame as request() but defaults to `method: \"HEAD\"`.\n\n```javascript\nrequest.head(url)\n```\n\n### request.del\n\nSame as request() but defaults to `method: \"DELETE\"`.\n\n```javascript\nrequest.del(url)\n```\n\n### request.get\n\nAlias to normal request method for uniformity.\n\n```javascript\nrequest.get(url)\n```\n### request.cookie\n\nFunction that creates a new cookie.\n\n```javascript\nrequest.cookie('cookie_string_here')\n```\n### request.jar\n\nFunction that creates a new cookie jar.\n\n```javascript\nrequest.jar()\n```\n\n\n## Examples:\n\n```javascript\n var request = require('request')\n , rand = Math.floor(Math.random()*100000000).toString()\n ;\n request(\n { method: 'PUT'\n , uri: 'http://mikeal.iriscouch.com/testjs/' + rand\n , multipart: \n [ { 'content-type': 'application/json'\n , body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})\n }\n , { body: 'I am an attachment' }\n ] \n }\n , function (error, response, body) {\n if(response.statusCode == 201){\n console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)\n } else {\n console.log('error: '+ response.statusCode)\n console.log(body)\n }\n }\n )\n```\nCookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).\n\n```javascript\nvar request = request.defaults({jar: false})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\n\nIf you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:\n\n```javascript\nvar j = request.jar()\nvar request = request.defaults({jar:j})\nrequest('http://www.google.com', function () {\n request('http://images.google.com')\n})\n```\nOR\n\n```javascript\nvar j = request.jar()\nvar cookie = request.cookie('your_cookie_here')\nj.add(cookie)\nrequest({url: 'http://www.google.com', jar: j}, function () {\n request('http://images.google.com')\n})\n```\n",
"_id": "request@2.9.203",
"dist": {
- "shasum": "f4c8f35b61b4d6621cb287bb1a1be6002b0bbe4a"
+ "shasum": "baf55a9b2ccfcca405cfcc0b104edf8b2681eeef"
},
- "_from": "request@~2.9"
+ "_from": "git://github.com/isaacs/request"
}
View
14 node_modules/request/tests/server.js
@@ -51,11 +51,15 @@ exports.createPostValidator = function (text) {
var r = '';
req.on('data', function (chunk) {r += chunk})
req.on('end', function () {
- if (r !== text) console.log(r, text);
- assert.equal(r, text)
- resp.writeHead(200, {'content-type':'text/plain'})
- resp.write('OK')
- resp.end()
+ if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) {
+ var boundary = req.headers['content-type'].split('boundary=')[1];
+ text = text.replace(/__BOUNDARY__/g, boundary);
+ }
+ if (r !== text) console.log(r, text);
+ assert.equal(r, text)
+ resp.writeHead(200, {'content-type':'text/plain'})
+ resp.write('OK')
+ resp.end()
})
}
return l;
View
39 node_modules/request/tests/test-body.js
@@ -30,6 +30,11 @@ var tests =
, encoding: null
, expectBody: new Buffer("TESTING!")
}
+ , testGetEncoding :
+ { resp : server.createGetResponse(new Buffer('efa3bfcea9e29883', 'hex'))
+ , encoding: 'hex'
+ , expectBody: "efa3bfcea9e29883"
+ }
, testGetJSON :
{ resp : server.createGetResponse('{"test":true}', 'application/json')
, json : true
@@ -50,7 +55,39 @@ var tests =
, method: "PUT"
, json: {foo: 'bar'}
}
-
+ , testPutMultipart :
+ { resp: server.createPostValidator(
+ '--__BOUNDARY__\r\n' +
+ 'content-type: text/html\r\n' +
+ '\r\n' +
+ '<html><body>Oh hi.</body></html>' +
+ '\r\n--__BOUNDARY__\r\n\r\n' +
+ 'Oh hi.' +
+ '\r\n--__BOUNDARY__--'
+ )
+ , method: "PUT"
+ , multipart:
+ [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+ , {'body': 'Oh hi.'}
+ ]
+ }
+ , testPutMultipartPreambleCRLF :
+ { resp: server.createPostValidator(
+ '\r\n--__BOUNDARY__\r\n' +
+ 'content-type: text/html\r\n' +
+ '\r\n' +
+ '<html><body>Oh hi.</body></html>' +
+ '\r\n--__BOUNDARY__\r\n\r\n' +
+ 'Oh hi.' +
+ '\r\n--__BOUNDARY__--'
+ )
+ , method: "PUT"
+ , preambleCRLF: true
+ , multipart:
+ [ {'content-type': 'text/html', 'body': '<html><body>Oh hi.</body></html>'}
+ , {'body': 'Oh hi.'}
+ ]
+ }
}
s.listen(s.port, function () {
View
35 node_modules/request/tests/test-defaults.js