08-27-周三_17-09-29

This commit is contained in:
2025-08-27 17:10:05 +08:00
commit 86df397d8f
12735 changed files with 1145479 additions and 0 deletions

21
node_modules/phantomjs/.eslintrc generated vendored Normal file
View File

@@ -0,0 +1,21 @@
{
"rules": {
"no-console": 0,
"quotes": [
2,
"single"
],
"linebreak-style": [
2,
"unix"
],
"semi": [
2,
"never"
]
},
"env": {
"node": true
},
"extends": "eslint:recommended"
}

4
node_modules/phantomjs/.jshintrc generated vendored Normal file
View File

@@ -0,0 +1,4 @@
{
"asi": true,
"node": true
}

5
node_modules/phantomjs/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,5 @@
/node_modules
/lib/phantom
/lib/location.js
/tmp
npm-debug.log

7
node_modules/phantomjs/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,7 @@
language: node_js
sudo: false
node_js:
- "5"
- "4"
- "0.12"
- "0.10"

194
node_modules/phantomjs/LICENSE.txt generated vendored Normal file
View File

@@ -0,0 +1,194 @@
Copyright 2012 The Obvious Corporation.
http://obvious.com/
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-------------------------------------------------------------------------
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

238
node_modules/phantomjs/README.md generated vendored Normal file
View File

@@ -0,0 +1,238 @@
phantomjs
==================
An NPM installer for [PhantomJS](http://phantomjs.org/), headless webkit with JS API.
[![Build Status](https://travis-ci.org/Medium/phantomjs.svg?branch=master)](https://travis-ci.org/Medium/phantomjs)
Building and Installing
-----------------------
```shell
npm install phantomjs
```
Or grab the source and
```shell
node ./install.js
```
What this installer is really doing is just grabbing a particular "blessed" (by
this module) version of Phantom. As new versions of Phantom are released
and vetted, this module will be updated accordingly.
Running
-------
```shell
bin/phantomjs [phantom arguments]
```
And npm will install a link to the binary in `node_modules/.bin` as
it is wont to do.
Running via node
----------------
The package exports a `path` string that contains the path to the
phantomjs binary/executable.
Below is an example of using this package via node.
```javascript
var path = require('path')
var childProcess = require('child_process')
var phantomjs = require('phantomjs')
var binPath = phantomjs.path
var childArgs = [
path.join(__dirname, 'phantomjs-script.js'),
'some other argument (passed to phantomjs script)'
]
childProcess.execFile(binPath, childArgs, function(err, stdout, stderr) {
// handle results
})
```
Versioning
----------
The major and minor number tracks the version of PhantomJS that will be
installed. The patch number is incremented when there is either an installer
update or a patch build of the phantom binary.
Pre-2.0, this package was published to NPM as [phantomjs](https://www.npmjs.com/package/phantomjs).
We changed the name to [phantomjs](https://www.npmjs.com/package/phantomjs) at
the request of PhantomJS team.
Deciding Where To Get PhantomJS
-------------------------------
By default, this package will download phantomjs from our [releases](https://github.com/Medium/phantomjs/releases/).
This should work fine for most people.
##### Downloading from a custom URL
If github is down, or the Great Firewall is blocking github, you may need to use
a different download mirror. To set a mirror, set npm config property `phantomjs_cdnurl`.
Alternatives include `https://bitbucket.org/ariya/phantomjs/downloads` (the official download site)
and `http://cnpmjs.org/downloads`.
```Shell
npm install phantomjs --phantomjs_cdnurl=https://bitbucket.org/ariya/phantomjs/downloads
```
Or add property into your `.npmrc` file (https://www.npmjs.org/doc/files/npmrc.html)
```
phantomjs_cdnurl=https://bitbucket.org/ariya/phantomjs/downloads
```
Another option is to use PATH variable `PHANTOMJS_CDNURL`.
```shell
PHANTOMJS_CDNURL=https://bitbucket.org/ariya/phantomjs/downloads npm install phantomjs
```
##### Using PhantomJS from disk
If you plan to install phantomjs many times on a single machine, you can
install the `phantomjs` binary on PATH. The installer will automatically detect
and use that for non-global installs.
Cross-Platform Repositories
---------------------------
PhantomJS needs to be compiled separately for each platform. This installer
finds a prebuilt binary for your operating system, and downloads it.
If you check your dependencies into git, and work on a cross-platform
team, then you need to tell NPM to rebuild any platform-specific dependencies. Run
```shell
npm rebuild
```
as part of your build process. This problem is not specific to PhantomJS, and this
solution will work for any NodeJS package with native or platform-specific code.
If you know in advance that you want to install PhantomJS for a specific architecture,
you can set the environment variables: `PHANTOMJS_PLATFORM`
(to set target platform) and `PHANTOMJS_ARCH` (to set target
arch), where `platform` and `arch` are valid values for
[process.platform and process.arch](https://nodejs.org/api/process.html).
A Note on PhantomJS
-------------------
PhantomJS is not a library for NodeJS. It's a separate environment and code
written for node is unlikely to be compatible. In particular PhantomJS does
not expose a Common JS package loader.
This is an _NPM wrapper_ and can be used to conveniently make Phantom available
It is not a Node JS wrapper.
I have had reasonable experiences writing standalone Phantom scripts which I
then drive from within a node program by spawning phantom in a child process.
Read the PhantomJS FAQ for more details: http://phantomjs.org/faq.html
### Linux Note
An extra note on Linux usage, from the PhantomJS download page:
> There is no requirement to install Qt, WebKit, or any other libraries. It
> however still relies on Fontconfig (the package fontconfig or libfontconfig,
> depending on the distribution).
Troubleshooting
---------------
##### Installation fails with `spawn ENOENT`
This is NPM's way of telling you that it was not able to start a process. It usually means:
- `node` is not on your PATH, or otherwise not correctly installed.
- `tar` is not on your PATH. This package expects `tar` on your PATH on Linux-based platforms.
Check your specific error message for more information.
##### Installation fails with `Error: EPERM` or `operation not permitted` or `permission denied`
This error means that NPM was not able to install phantomjs to the file system. There are three
major reasons why this could happen:
- You don't have write access to the installation directory.
- The permissions in the NPM cache got messed up, and you need to run `npm cache clean` to fix them.
- You have over-zealous anti-virus software installed, and it's blocking file system writes.
##### Installation fails with `Error: read ECONNRESET` or `Error: connect ETIMEDOUT`
This error means that something went wrong with your internet connection, and the installer
was not able to download the PhantomJS binary for your platform. Please try again.
##### I tried again, but I get `ECONNRESET` or `ETIMEDOUT` consistently.
Do you live in China, or a country with an authoritarian government? We've seen problems where
the GFW or local ISP blocks github, preventing the installer from downloading the binary.
Try visiting [the download page](https://bitbucket.org/ariya/phantomjs/downloads) manually.
If that page is blocked, you can try using a different CDN with the `PHANTOMJS_CDNURL`
env variable described above.
##### I am behind a corporate proxy that uses self-signed SSL certificates to intercept encrypted traffic.
You can tell NPM and the PhantomJS installer to skip validation of ssl keys with NPM's
[strict-ssl](https://www.npmjs.org/doc/misc/npm-config.html#strict-ssl) setting:
```
npm set strict-ssl false
```
WARNING: Turning off `strict-ssl` leaves you vulnerable to attackers reading
your encrypted traffic, so run this at your own risk!
##### I tried everything, but my network is b0rked. What do I do?
If you install PhantomJS manually, and put it on PATH, the installer will try to
use the manually-installed binaries.
##### I'm on Debian or Ubuntu, and the installer failed because it couldn't find `node`
Some Linux distros tried to rename `node` to `nodejs` due to a package
conflict. This is a non-portable change, and we do not try to support this. The
[official documentation](https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager#ubuntu-mint-elementary-os)
recommends that you run `apt-get install nodejs-legacy` to symlink `node` to `nodejs`
on those platforms, or many NodeJS programs won't work properly.
Contributing
------------
Questions, comments, bug reports, and pull requests are all welcome. Submit them at
[the project on GitHub](https://github.com/Medium/phantomjs/). If you haven't contributed to an
[Medium](http://github.com/Medium/) project before please head over to the
[Open Source Project](https://github.com/Medium/open-source#note-to-external-contributors) and fill
out an OCLA (it should be pretty painless).
Bug reports that include steps-to-reproduce (including code) are the
best. Even better, make them in the form of pull requests.
Author
------
[Dan Pupius](https://github.com/dpup)
([personal website](http://pupius.co.uk)) and
[Nick Santos](https://github.com/nicks), supported by
[A Medium Corporation](http://medium.com/).
License
-------
Copyright 2012 [A Medium Corporation](http://medium.com/).
Licensed under the Apache License, Version 2.0.
See the top-level file `LICENSE.txt` and
(http://www.apache.org/licenses/LICENSE-2.0).

42
node_modules/phantomjs/bin/phantomjs generated vendored Normal file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/env node
/**
* Script that will execute the downloaded phantomjs binary. stdio are
* forwarded to and from the child process.
*
* The following is for an ugly hack to avoid a problem where the installer
* finds the bin script npm creates during global installation.
*
* {NPM_INSTALL_MARKER}
*/
var path = require('path')
var spawn = require('child_process').spawn
var binPath = require(path.join(__dirname, '..', 'lib', 'phantomjs')).path
var args = process.argv.slice(2)
// For Node 0.6 compatibility, pipe the streams manually, instead of using
// `{ stdio: 'inherit' }`.
var cp = spawn(binPath, args)
cp.stdout.pipe(process.stdout)
cp.stderr.pipe(process.stderr)
process.stdin.pipe(cp.stdin)
cp.on('error', function (err) {
console.error('Error executing phantom at', binPath)
console.error(err.stack)
})
cp.on('exit', function(code){
// Wait few ms for error to be printed.
setTimeout(function(){
process.exit(code)
}, 20)
});
process.on('SIGTERM', function() {
cp.kill('SIGTERM')
process.exit(1)
})

550
node_modules/phantomjs/install.js generated vendored Normal file
View File

@@ -0,0 +1,550 @@
// Copyright 2012 The Obvious Corporation.
/*
* This simply fetches the right version of phantom for the current platform.
*/
'use strict'
var requestProgress = require('request-progress')
var progress = require('progress')
var extractZip = require('extract-zip')
var cp = require('child_process')
var fs = require('fs-extra')
var hasha = require('hasha')
var helper = require('./lib/phantomjs')
var kew = require('kew')
var path = require('path')
var request = require('request')
var url = require('url')
var which = require('which')
var originalPath = process.env.PATH
var DEFAULT_CDN = 'https://github.com/Medium/phantomjs/releases/download/v1.9.19'
// If the process exits without going through exit(), then we did not complete.
var validExit = false
process.on('exit', function () {
if (!validExit) {
console.log('Install exited unexpectedly')
exit(1)
}
})
// NPM adds bin directories to the path, which will cause `which` to find the
// bin for this package not the actual phantomjs bin. Also help out people who
// put ./bin on their path
process.env.PATH = helper.cleanPath(originalPath)
var libPath = path.join(__dirname, 'lib')
var pkgPath = path.join(libPath, 'phantom')
var phantomPath = null
// If the user manually installed PhantomJS, we want
// to use the existing version.
//
// Do not re-use a manually-installed PhantomJS with
// a different version.
//
// Do not re-use an npm-installed PhantomJS, because
// that can lead to weird circular dependencies between
// local versions and global versions.
// https://github.com/Obvious/phantomjs/issues/85
// https://github.com/Medium/phantomjs/pull/184
kew.resolve(true)
.then(tryPhantomjsInLib)
.then(tryPhantomjsOnPath)
.then(downloadPhantomjs)
.then(extractDownload)
.then(function (extractedPath) {
return copyIntoPlace(extractedPath, pkgPath)
})
.then(function () {
var location = getTargetPlatform() === 'win32' ?
path.join(pkgPath, 'phantomjs.exe') :
path.join(pkgPath, 'bin' ,'phantomjs')
try {
// Ensure executable is executable by all users
fs.chmodSync(location, '755')
} catch (err) {
if (err.code == 'ENOENT') {
console.error('chmod failed: phantomjs was not successfully copied to', location)
exit(1)
}
throw err
}
var relativeLocation = path.relative(libPath, location)
writeLocationFile(relativeLocation)
console.log('Done. Phantomjs binary available at', location)
exit(0)
})
.fail(function (err) {
console.error('Phantom installation failed', err, err.stack)
exit(1)
})
function writeLocationFile(location) {
console.log('Writing location.js file')
if (getTargetPlatform() === 'win32') {
location = location.replace(/\\/g, '\\\\')
}
var platform = getTargetPlatform()
var arch = getTargetArch()
var contents = 'module.exports.location = "' + location + '"\n'
if (/^[a-zA-Z0-9]*$/.test(platform) && /^[a-zA-Z0-9]*$/.test(arch)) {
contents +=
'module.exports.platform = "' + getTargetPlatform() + '"\n' +
'module.exports.arch = "' + getTargetArch() + '"\n'
}
fs.writeFileSync(path.join(libPath, 'location.js'), contents)
}
function exit(code) {
validExit = true
process.env.PATH = originalPath
process.exit(code || 0)
}
function findSuitableTempDirectory() {
var now = Date.now()
var candidateTmpDirs = [
process.env.TMPDIR || process.env.TEMP || process.env.npm_config_tmp,
'/tmp',
path.join(process.cwd(), 'tmp')
]
for (var i = 0; i < candidateTmpDirs.length; i++) {
var candidatePath = path.join(candidateTmpDirs[i], 'phantomjs')
try {
fs.mkdirsSync(candidatePath, '0777')
// Make double sure we have 0777 permissions; some operating systems
// default umask does not allow write by default.
fs.chmodSync(candidatePath, '0777')
var testFile = path.join(candidatePath, now + '.tmp')
fs.writeFileSync(testFile, 'test')
fs.unlinkSync(testFile)
return candidatePath
} catch (e) {
console.log(candidatePath, 'is not writable:', e.message)
}
}
console.error('Can not find a writable tmp directory, please report issue ' +
'on https://github.com/Obvious/phantomjs/issues/59 with as much ' +
'information as possible.')
exit(1)
}
function getRequestOptions() {
var strictSSL = !!process.env.npm_config_strict_ssl
if (process.version == 'v0.10.34') {
console.log('Node v0.10.34 detected, turning off strict ssl due to https://github.com/joyent/node/issues/8894')
strictSSL = false
}
var options = {
uri: getDownloadUrl(),
encoding: null, // Get response as a buffer
followRedirect: true, // The default download path redirects to a CDN URL.
headers: {},
strictSSL: strictSSL
}
var proxyUrl = process.env.npm_config_https_proxy ||
process.env.npm_config_http_proxy ||
process.env.npm_config_proxy
if (proxyUrl) {
// Print using proxy
var proxy = url.parse(proxyUrl)
if (proxy.auth) {
// Mask password
proxy.auth = proxy.auth.replace(/:.*$/, ':******')
}
console.log('Using proxy ' + url.format(proxy))
// Enable proxy
options.proxy = proxyUrl
}
// Use the user-agent string from the npm config
options.headers['User-Agent'] = process.env.npm_config_user_agent
// Use certificate authority settings from npm
var ca = process.env.npm_config_ca
if (!ca && process.env.npm_config_cafile) {
try {
ca = fs.readFileSync(process.env.npm_config_cafile, {encoding: 'utf8'})
.split(/\n(?=-----BEGIN CERTIFICATE-----)/g)
// Comments at the beginning of the file result in the first
// item not containing a certificate - in this case the
// download will fail
if (ca.length > 0 && !/-----BEGIN CERTIFICATE-----/.test(ca[0])) {
ca.shift()
}
} catch (e) {
console.error('Could not read cafile', process.env.npm_config_cafile, e)
}
}
if (ca) {
console.log('Using npmconf ca')
options.agentOptions = {
ca: ca
}
options.ca = ca
}
return options
}
function handleRequestError(error) {
if (error && error.stack && error.stack.indexOf('SELF_SIGNED_CERT_IN_CHAIN') != -1) {
console.error('Error making request, SELF_SIGNED_CERT_IN_CHAIN. ' +
'Please read https://github.com/Medium/phantomjs#i-am-behind-a-corporate-proxy-that-uses-self-signed-ssl-certificates-to-intercept-encrypted-traffic')
exit(1)
} else if (error) {
console.error('Error making request.\n' + error.stack + '\n\n' +
'Please report this full log at https://github.com/Medium/phantomjs')
exit(1)
} else {
console.error('Something unexpected happened, please report this full ' +
'log at https://github.com/Medium/phantomjs')
exit(1)
}
}
function requestBinary(requestOptions, filePath) {
var deferred = kew.defer()
var writePath = filePath + '-download-' + Date.now()
console.log('Receiving...')
var bar = null
requestProgress(request(requestOptions, function (error, response, body) {
console.log('')
if (!error && response.statusCode === 200) {
fs.writeFileSync(writePath, body)
console.log('Received ' + Math.floor(body.length / 1024) + 'K total.')
fs.renameSync(writePath, filePath)
deferred.resolve(filePath)
} else if (response) {
console.error('Error requesting archive.\n' +
'Status: ' + response.statusCode + '\n' +
'Request options: ' + JSON.stringify(requestOptions, null, 2) + '\n' +
'Response headers: ' + JSON.stringify(response.headers, null, 2) + '\n' +
'Make sure your network and proxy settings are correct.\n\n' +
'If you continue to have issues, please report this full log at ' +
'https://github.com/Medium/phantomjs')
exit(1)
} else {
handleRequestError(error)
}
})).on('progress', function (state) {
try {
if (!bar) {
bar = new progress(' [:bar] :percent', {total: state.size.total, width: 40})
}
bar.curr = state.size.transferred
bar.tick()
} catch (e) {
// It doesn't really matter if the progress bar doesn't update.
}
})
.on('error', handleRequestError)
return deferred.promise
}
function extractDownload(filePath) {
var deferred = kew.defer()
// extract to a unique directory in case multiple processes are
// installing and extracting at once
var extractedPath = filePath + '-extract-' + Date.now()
var options = {cwd: extractedPath}
fs.mkdirsSync(extractedPath, '0777')
// Make double sure we have 0777 permissions; some operating systems
// default umask does not allow write by default.
fs.chmodSync(extractedPath, '0777')
if (filePath.substr(-4) === '.zip') {
console.log('Extracting zip contents')
extractZip(path.resolve(filePath), {dir: extractedPath}, function(err) {
if (err) {
console.error('Error extracting zip')
deferred.reject(err)
} else {
deferred.resolve(extractedPath)
}
})
} else {
console.log('Extracting tar contents (via spawned process)')
cp.execFile('tar', ['jxf', path.resolve(filePath)], options, function (err) {
if (err) {
console.error('Error extracting archive')
deferred.reject(err)
} else {
deferred.resolve(extractedPath)
}
})
}
return deferred.promise
}
function copyIntoPlace(extractedPath, targetPath) {
console.log('Removing', targetPath)
return kew.nfcall(fs.remove, targetPath).then(function () {
// Look for the extracted directory, so we can rename it.
var files = fs.readdirSync(extractedPath)
for (var i = 0; i < files.length; i++) {
var file = path.join(extractedPath, files[i])
if (fs.statSync(file).isDirectory() && file.indexOf(helper.version) != -1) {
console.log('Copying extracted folder', file, '->', targetPath)
return kew.nfcall(fs.move, file, targetPath)
}
}
console.log('Could not find extracted file', files)
throw new Error('Could not find extracted file')
})
}
function getLocationInLibModuleIfMatching(libPath) {
var libModule = require(libPath)
if (libModule.location &&
getTargetPlatform() == libModule.platform &&
getTargetArch() == libModule.arch) {
try {
var resolvedLocation = path.resolve(path.dirname(libPath), libModule.location)
if (fs.statSync(resolvedLocation)) {
return resolvedLocation
}
} catch (e) {
// fall through
}
}
return false
}
/**
* Check to see if the binary in lib is OK to use. If successful, exit the process.
*/
function tryPhantomjsInLib() {
return kew.fcall(function () {
var location = getLocationInLibModuleIfMatching('./lib/location.js')
if (location) {
console.log('PhantomJS is previously installed at', location)
exit(0)
}
}).fail(function () {
// silently swallow any errors
})
}
/**
* Check to see if the binary on PATH is OK to use. If successful, exit the process.
*/
function tryPhantomjsOnPath() {
if (getTargetPlatform() != process.platform || getTargetArch() != process.arch) {
console.log('Building for target platform ' + getTargetPlatform() + '/' + getTargetArch() +
'. Skipping PATH search')
return kew.resolve(false)
}
return kew.nfcall(which, 'phantomjs')
.then(function (result) {
phantomPath = result
console.log('Considering PhantomJS found at', phantomPath)
// Horrible hack to avoid problems during global install. We check to see if
// the file `which` found is our own bin script.
if (phantomPath.indexOf(path.join('npm', 'phantomjs')) !== -1) {
console.log('Looks like an `npm install -g` on windows; skipping installed version.')
return
}
var contents = fs.readFileSync(phantomPath, 'utf8')
if (/NPM_INSTALL_MARKER/.test(contents)) {
console.log('Looks like an `npm install -g`')
var globalLocation = getLocationInLibModuleIfMatching(
path.resolve(fs.realpathSync(phantomPath), '../../lib/location'))
if (globalLocation) {
console.log('Linking to global install at', globalLocation)
writeLocationFile(globalLocation)
exit(0)
}
console.log('Could not link global install, skipping...')
} else {
return checkPhantomjsVersion(phantomPath).then(function (matches) {
if (matches) {
writeLocationFile(phantomPath)
console.log('PhantomJS is already installed on PATH at', phantomPath)
exit(0)
}
})
}
}, function () {
console.log('PhantomJS not found on PATH')
})
.fail(function (err) {
console.error('Error checking path, continuing', err)
return false
})
}
/**
* @return {?string} Get the download URL for phantomjs.
* May return null if no download url exists.
*/
function getDownloadUrl() {
var spec = getDownloadSpec()
return spec && spec.url
}
/**
* @return {?{url: string, checksum: string}} Get the download URL and expected
* SHA-256 checksum for phantomjs. May return null if no download url exists.
*/
function getDownloadSpec() {
var cdnUrl = process.env.npm_config_phantomjs_cdnurl ||
process.env.PHANTOMJS_CDNURL ||
DEFAULT_CDN
var downloadUrl = cdnUrl + '/phantomjs-' + helper.version + '-'
var checksum = ''
var platform = getTargetPlatform()
var arch = getTargetArch()
if (platform === 'linux' && arch === 'x64') {
downloadUrl += 'linux-x86_64.tar.bz2'
checksum = 'a1d9628118e270f26c4ddd1d7f3502a93b48ede334b8585d11c1c3ae7bc7163a'
} else if (platform === 'linux' && arch == 'ia32') {
downloadUrl += 'linux-i686.tar.bz2'
checksum = '4102450bb658157e9aef3e229828fade0aaa0de0663802b31a0edff4b5aedf85'
} else if (platform === 'darwin' || platform === 'openbsd' || platform === 'freebsd') {
downloadUrl += 'macosx.zip'
checksum = '8f15043ae3031815dc5f884ea6ffa053d365491b1bc0dc3a0862d5ff1ac20a48'
} else if (platform === 'win32') {
downloadUrl += 'windows.zip'
checksum = 'da36853ece7d58b6f50813d3e598d8a16bb191b467ac32e1624a239a49de9104'
} else {
return null
}
return {url: downloadUrl, checksum: checksum}
}
/**
* Download phantomjs, reusing the existing copy on disk if available.
* Exits immediately if there is no binary to download.
* @return {Promise.<string>} The path to the downloaded file.
*/
function downloadPhantomjs() {
var downloadSpec = getDownloadSpec()
if (!downloadSpec) {
console.error(
'Unexpected platform or architecture: ' + getTargetPlatform() + '/' + getTargetArch() + '\n' +
'It seems there is no binary available for your platform/architecture\n' +
'Try to install PhantomJS globally')
exit(1)
}
var downloadUrl = downloadSpec.url
var downloadedFile
return kew.fcall(function () {
// Can't use a global version so start a download.
var tmpPath = findSuitableTempDirectory()
var fileName = downloadUrl.split('/').pop()
downloadedFile = path.join(tmpPath, fileName)
if (fs.existsSync(downloadedFile)) {
console.log('Download already available at', downloadedFile)
return verifyChecksum(downloadedFile, downloadSpec.checksum)
}
return false
}).then(function (verified) {
if (verified) {
return downloadedFile
}
// Start the install.
console.log('Downloading', downloadUrl)
console.log('Saving to', downloadedFile)
return requestBinary(getRequestOptions(), downloadedFile)
})
}
/**
* Check to make sure that the file matches the checksum.
* @param {string} fileName
* @param {string} checksum
* @return {Promise.<boolean>}
*/
function verifyChecksum(fileName, checksum) {
return kew.resolve(hasha.fromFile(fileName, {algorithm: 'sha256'})).then(function (hash) {
var result = checksum == hash
if (result) {
console.log('Verified checksum of previously downloaded file')
} else {
console.log('Checksum did not match')
}
return result
}).fail(function (err) {
console.error('Failed to verify checksum: ', err)
return false
})
}
/**
* Check to make sure a given binary is the right version.
* @return {kew.Promise.<boolean>}
*/
function checkPhantomjsVersion(phantomPath) {
console.log('Found PhantomJS at', phantomPath, '...verifying')
return kew.nfcall(cp.execFile, phantomPath, ['--version']).then(function (stdout) {
var version = stdout.trim()
if (helper.version == version) {
return true
} else {
console.log('PhantomJS detected, but wrong version', stdout.trim(), '@', phantomPath + '.')
return false
}
}).fail(function (err) {
console.error('Error verifying phantomjs, continuing', err)
return false
})
}
/**
* @return {string}
*/
function getTargetPlatform() {
return process.env.PHANTOMJS_PLATFORM || process.platform
}
/**
* @return {string}
*/
function getTargetArch() {
return process.env.PHANTOMJS_ARCH || process.arch
}

63
node_modules/phantomjs/lib/phantomjs.js generated vendored Normal file
View File

@@ -0,0 +1,63 @@
// Copyright 2013 The Obvious Corporation.
/**
* @fileoverview Helpers made available via require('phantomjs') once package is
* installed.
*/
var fs = require('fs')
var path = require('path')
/**
* Where the phantom binary can be found.
* @type {string}
*/
try {
var location = require('./location')
exports.path = path.resolve(__dirname, location.location)
exports.platform = location.platform
exports.arch = location.arch
} catch(e) {
// Must be running inside install script.
exports.path = null
}
/**
* The version of phantomjs installed by this package.
* @type {number}
*/
exports.version = '1.9.8'
/**
* Returns a clean path that helps avoid `which` finding bin files installed
* by NPM for this repo.
* @param {string} path
* @return {string}
*/
exports.cleanPath = function (path) {
return path
.replace(/:[^:]*node_modules[^:]*/g, '')
.replace(/(^|:)\.\/bin(\:|$)/g, ':')
.replace(/^:+/, '')
.replace(/:+$/, '')
}
// Make sure the binary is executable. For some reason doing this inside
// install does not work correctly, likely due to some NPM step.
if (exports.path) {
try {
// avoid touching the binary if it's already got the correct permissions
var st = fs.statSync(exports.path);
var mode = st.mode | parseInt("0555", 8);
if (mode !== st.mode) {
fs.chmodSync(exports.path, mode);
}
} catch (e) {
// Just ignore error if we don't have permission.
// We did our best. Likely because phantomjs was already installed.
}
}

View File

@@ -0,0 +1 @@
../har-validator/bin/har-validator

1
node_modules/phantomjs/node_modules/.bin/uuid generated vendored Normal file
View File

@@ -0,0 +1 @@
../node-uuid/bin/uuid

View File

@@ -0,0 +1,6 @@
Dave Eddy <dave@daveeddy.com>
Fred Kuo <fred.kuo@joyent.com>
Lars-Magnus Skog <ralphtheninja@riseup.net>
Mark Cavage <mcavage@gmail.com>
Patrick Mooney <pmooney@pfmooney.com>
Rob Gulewich <robert.gulewich@joyent.com>

View File

@@ -0,0 +1,8 @@
# assert-plus Changelog
## 0.2.0
- Fix `assert.object(null)` so it throws
- Fix optional/arrayOf exports for non-type-of asserts
- Add optiona/arrayOf exports for Stream/Date/Regex/uuid
- Add basic unit test coverage

View File

@@ -0,0 +1,155 @@
# assert-plus
This library is a super small wrapper over node's assert module that has two
things: (1) the ability to disable assertions with the environment variable
NODE\_NDEBUG, and (2) some API wrappers for argument testing. Like
`assert.string(myArg, 'myArg')`. As a simple example, most of my code looks
like this:
```javascript
var assert = require('assert-plus');
function fooAccount(options, callback) {
assert.object(options, 'options');
assert.number(options.id, 'options.id');
assert.bool(options.isManager, 'options.isManager');
assert.string(options.name, 'options.name');
assert.arrayOfString(options.email, 'options.email');
assert.func(callback, 'callback');
// Do stuff
callback(null, {});
}
```
# API
All methods that *aren't* part of node's core assert API are simply assumed to
take an argument, and then a string 'name' that's not a message; `AssertionError`
will be thrown if the assertion fails with a message like:
AssertionError: foo (string) is required
at test (/home/mark/work/foo/foo.js:3:9)
at Object.<anonymous> (/home/mark/work/foo/foo.js:15:1)
at Module._compile (module.js:446:26)
at Object..js (module.js:464:10)
at Module.load (module.js:353:31)
at Function._load (module.js:311:12)
at Array.0 (module.js:484:10)
at EventEmitter._tickCallback (node.js:190:38)
from:
```javascript
function test(foo) {
assert.string(foo, 'foo');
}
```
There you go. You can check that arrays are of a homogeneous type with `Arrayof$Type`:
```javascript
function test(foo) {
assert.arrayOfString(foo, 'foo');
}
```
You can assert IFF an argument is not `undefined` (i.e., an optional arg):
```javascript
assert.optionalString(foo, 'foo');
```
Lastly, you can opt-out of assertion checking altogether by setting the
environment variable `NODE_NDEBUG=1`. This is pseudo-useful if you have
lots of assertions, and don't want to pay `typeof ()` taxes to v8 in
production. Be advised: The standard functions re-exported from `assert` are
also disabled in assert-plus if NDEBUG is specified. Using them directly from
the `assert` module avoids this behavior.
The complete list of APIs is:
* assert.array
* assert.bool
* assert.buffer
* assert.func
* assert.number
* assert.object
* assert.string
* assert.stream
* assert.date
* assert.regex
* assert.uuid
* assert.arrayOfArray
* assert.arrayOfBool
* assert.arrayOfBuffer
* assert.arrayOfFunc
* assert.arrayOfNumber
* assert.arrayOfObject
* assert.arrayOfString
* assert.arrayOfStream
* assert.arrayOfDate
* assert.arrayOfUuid
* assert.optionalArray
* assert.optionalBool
* assert.optionalBuffer
* assert.optionalFunc
* assert.optionalNumber
* assert.optionalObject
* assert.optionalString
* assert.optionalStream
* assert.optionalDate
* assert.optionalUuid
* assert.optionalArrayOfArray
* assert.optionalArrayOfBool
* assert.optionalArrayOfBuffer
* assert.optionalArrayOfFunc
* assert.optionalArrayOfNumber
* assert.optionalArrayOfObject
* assert.optionalArrayOfString
* assert.optionalArrayOfStream
* assert.optionalArrayOfDate
* assert.optionalArrayOfUuid
* assert.AssertionError
* assert.fail
* assert.ok
* assert.equal
* assert.notEqual
* assert.deepEqual
* assert.notDeepEqual
* assert.strictEqual
* assert.notStrictEqual
* assert.throws
* assert.doesNotThrow
* assert.ifError
# Installation
npm install assert-plus
## License
The MIT License (MIT)
Copyright (c) 2012 Mark Cavage
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
## Bugs
See <https://github.com/mcavage/node-assert-plus/issues>.

View File

@@ -0,0 +1,206 @@
// Copyright (c) 2012, Mark Cavage. All rights reserved.
// Copyright 2015 Joyent, Inc.
var assert = require('assert');
var Stream = require('stream').Stream;
var util = require('util');
///--- Globals
/* JSSTYLED */
var UUID_REGEXP = /^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$/;
///--- Internal
function _capitalize(str) {
return (str.charAt(0).toUpperCase() + str.slice(1));
}
function _toss(name, expected, oper, arg, actual) {
throw new assert.AssertionError({
message: util.format('%s (%s) is required', name, expected),
actual: (actual === undefined) ? typeof (arg) : actual(arg),
expected: expected,
operator: oper || '===',
stackStartFunction: _toss.caller
});
}
function _getClass(arg) {
return (Object.prototype.toString.call(arg).slice(8, -1));
}
function noop() {
// Why even bother with asserts?
}
///--- Exports
var types = {
bool: {
check: function (arg) { return typeof (arg) === 'boolean'; }
},
func: {
check: function (arg) { return typeof (arg) === 'function'; }
},
string: {
check: function (arg) { return typeof (arg) === 'string'; }
},
object: {
check: function (arg) {
return typeof (arg) === 'object' && arg !== null;
}
},
number: {
check: function (arg) {
return typeof (arg) === 'number' && !isNaN(arg) && isFinite(arg);
}
},
buffer: {
check: function (arg) { return Buffer.isBuffer(arg); },
operator: 'Buffer.isBuffer'
},
array: {
check: function (arg) { return Array.isArray(arg); },
operator: 'Array.isArray'
},
stream: {
check: function (arg) { return arg instanceof Stream; },
operator: 'instanceof',
actual: _getClass
},
date: {
check: function (arg) { return arg instanceof Date; },
operator: 'instanceof',
actual: _getClass
},
regexp: {
check: function (arg) { return arg instanceof RegExp; },
operator: 'instanceof',
actual: _getClass
},
uuid: {
check: function (arg) {
return typeof (arg) === 'string' && UUID_REGEXP.test(arg);
},
operator: 'isUUID'
}
};
function _setExports(ndebug) {
var keys = Object.keys(types);
var out;
/* re-export standard assert */
if (process.env.NODE_NDEBUG) {
out = noop;
} else {
out = function (arg, msg) {
if (!arg) {
_toss(msg, 'true', arg);
}
};
}
/* standard checks */
keys.forEach(function (k) {
if (ndebug) {
out[k] = noop;
return;
}
var type = types[k];
out[k] = function (arg, msg) {
if (!type.check(arg)) {
_toss(msg, k, type.operator, arg, type.actual);
}
};
});
/* optional checks */
keys.forEach(function (k) {
var name = 'optional' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
out[name] = function (arg, msg) {
if (arg === undefined || arg === null) {
return;
}
if (!type.check(arg)) {
_toss(msg, k, type.operator, arg, type.actual);
}
};
});
/* arrayOf checks */
keys.forEach(function (k) {
var name = 'arrayOf' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
var expected = '[' + k + ']';
out[name] = function (arg, msg) {
if (!Array.isArray(arg)) {
_toss(msg, expected, type.operator, arg, type.actual);
}
var i;
for (i = 0; i < arg.length; i++) {
if (!type.check(arg[i])) {
_toss(msg, expected, type.operator, arg, type.actual);
}
}
};
});
/* optionalArrayOf checks */
keys.forEach(function (k) {
var name = 'optionalArrayOf' + _capitalize(k);
if (ndebug) {
out[name] = noop;
return;
}
var type = types[k];
var expected = '[' + k + ']';
out[name] = function (arg, msg) {
if (arg === undefined || arg === null) {
return;
}
if (!Array.isArray(arg)) {
_toss(msg, expected, type.operator, arg, type.actual);
}
var i;
for (i = 0; i < arg.length; i++) {
if (!type.check(arg[i])) {
_toss(msg, expected, type.operator, arg, type.actual);
}
}
};
});
/* re-export built-in assertions */
Object.keys(assert).forEach(function (k) {
if (k === 'AssertionError') {
out[k] = assert[k];
return;
}
if (ndebug) {
out[k] = noop;
return;
}
out[k] = assert[k];
});
/* export ourselves (for unit tests _only_) */
out._setExports = _setExports;
return out;
}
module.exports = _setExports(process.env.NODE_NDEBUG);

View File

@@ -0,0 +1,121 @@
{
"_args": [
[
{
"name": "assert-plus",
"raw": "assert-plus@^0.2.0",
"rawSpec": "^0.2.0",
"scope": null,
"spec": ">=0.2.0 <0.3.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/http-signature"
]
],
"_from": "assert-plus@>=0.2.0 <0.3.0",
"_id": "assert-plus@0.2.0",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/assert-plus",
"_nodeVersion": "0.10.36",
"_npmUser": {
"email": "patrick.f.mooney@gmail.com",
"name": "pfmooney"
},
"_npmVersion": "3.3.8",
"_phantomChildren": {},
"_requested": {
"name": "assert-plus",
"raw": "assert-plus@^0.2.0",
"rawSpec": "^0.2.0",
"scope": null,
"spec": ">=0.2.0 <0.3.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/http-signature"
],
"_resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
"_shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
"_shrinkwrap": null,
"_spec": "assert-plus@^0.2.0",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/http-signature",
"author": {
"email": "mcavage@gmail.com",
"name": "Mark Cavage"
},
"bugs": {
"url": "https://github.com/mcavage/node-assert-plus/issues"
},
"contributors": [
{
"email": "dave@daveeddy.com",
"name": "Dave Eddy"
},
{
"email": "fred.kuo@joyent.com",
"name": "Fred Kuo"
},
{
"email": "ralphtheninja@riseup.net",
"name": "Lars-Magnus Skog"
},
{
"email": "mcavage@gmail.com",
"name": "Mark Cavage"
},
{
"email": "pmooney@pfmooney.com",
"name": "Patrick Mooney"
},
{
"email": "robert.gulewich@joyent.com",
"name": "Rob Gulewich"
}
],
"dependencies": {},
"description": "Extra assertions on top of node's assert module",
"devDependencies": {
"faucet": "0.0.1",
"tape": "4.2.2"
},
"directories": {},
"dist": {
"integrity": "sha512-u1L0ZLywRziOVjUhRxI0Qg9G+4RnFB9H/Rq40YWn0dieDgO7vAYeJz6jKAO6t/aruzlDFLAPkQTT87e+f8Imaw==",
"shasum": "d74e1b87e7affc0db8aadb7021f3fe48101ab234",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQCwKUBmv9LO9YbpD6fgIGg0s3pZscqI6Ak3Be6o1NMOsQIhAL8oLWRmoCCEp1Yd9MF3Ws+j1JAeWMOrQVdfeffnv9rf"
}
],
"tarball": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz"
},
"engines": {
"node": ">=0.8"
},
"homepage": "https://github.com/mcavage/node-assert-plus#readme",
"license": "MIT",
"main": "./assert.js",
"maintainers": [
{
"email": "mcavage@gmail.com",
"name": "mcavage"
},
{
"email": "patrick.f.mooney@gmail.com",
"name": "pfmooney"
}
],
"name": "assert-plus",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/mcavage/node-assert-plus.git"
},
"scripts": {
"test": "tape tests/*.js | ./node_modules/.bin/faucet"
},
"version": "0.2.0"
}

55
node_modules/phantomjs/node_modules/aws-sign2/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,55 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,4 @@
aws-sign
========
AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.

212
node_modules/phantomjs/node_modules/aws-sign2/index.js generated vendored Normal file
View File

@@ -0,0 +1,212 @@
/*!
* Copyright 2010 LearnBoost <dev@learnboost.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Module dependencies.
*/
var crypto = require('crypto')
, parse = require('url').parse
;
/**
* Valid keys.
*/
var keys =
[ 'acl'
, 'location'
, 'logging'
, 'notification'
, 'partNumber'
, 'policy'
, 'requestPayment'
, 'torrent'
, 'uploadId'
, 'uploads'
, 'versionId'
, 'versioning'
, 'versions'
, 'website'
]
/**
* Return an "Authorization" header value with the given `options`
* in the form of "AWS <key>:<signature>"
*
* @param {Object} options
* @return {String}
* @api private
*/
function authorization (options) {
return 'AWS ' + options.key + ':' + sign(options)
}
module.exports = authorization
module.exports.authorization = authorization
/**
* Simple HMAC-SHA1 Wrapper
*
* @param {Object} options
* @return {String}
* @api private
*/
function hmacSha1 (options) {
return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
}
module.exports.hmacSha1 = hmacSha1
/**
* Create a base64 sha1 HMAC for `options`.
*
* @param {Object} options
* @return {String}
* @api private
*/
function sign (options) {
options.message = stringToSign(options)
return hmacSha1(options)
}
module.exports.sign = sign
/**
* Create a base64 sha1 HMAC for `options`.
*
* Specifically to be used with S3 presigned URLs
*
* @param {Object} options
* @return {String}
* @api private
*/
function signQuery (options) {
options.message = queryStringToSign(options)
return hmacSha1(options)
}
module.exports.signQuery= signQuery
/**
* Return a string for sign() with the given `options`.
*
* Spec:
*
* <verb>\n
* <md5>\n
* <content-type>\n
* <date>\n
* [headers\n]
* <resource>
*
* @param {Object} options
* @return {String}
* @api private
*/
function stringToSign (options) {
var headers = options.amazonHeaders || ''
if (headers) headers += '\n'
var r =
[ options.verb
, options.md5
, options.contentType
, options.date ? options.date.toUTCString() : ''
, headers + options.resource
]
return r.join('\n')
}
module.exports.queryStringToSign = stringToSign
/**
* Return a string for sign() with the given `options`, but is meant exclusively
* for S3 presigned URLs
*
* Spec:
*
* <date>\n
* <resource>
*
* @param {Object} options
* @return {String}
* @api private
*/
function queryStringToSign (options){
return 'GET\n\n\n' + options.date + '\n' + options.resource
}
module.exports.queryStringToSign = queryStringToSign
/**
* Perform the following:
*
* - ignore non-amazon headers
* - lowercase fields
* - sort lexicographically
* - trim whitespace between ":"
* - join with newline
*
* @param {Object} headers
* @return {String}
* @api private
*/
function canonicalizeHeaders (headers) {
var buf = []
, fields = Object.keys(headers)
;
for (var i = 0, len = fields.length; i < len; ++i) {
var field = fields[i]
, val = headers[field]
, field = field.toLowerCase()
;
if (0 !== field.indexOf('x-amz')) continue
buf.push(field + ':' + val)
}
return buf.sort().join('\n')
}
module.exports.canonicalizeHeaders = canonicalizeHeaders
/**
* Perform the following:
*
* - ignore non sub-resources
* - sort lexicographically
*
* @param {String} resource
* @return {String}
* @api private
*/
function canonicalizeResource (resource) {
var url = parse(resource, true)
, path = url.pathname
, buf = []
;
Object.keys(url.query).forEach(function(key){
if (!~keys.indexOf(key)) return
var val = '' == url.query[key] ? '' : '=' + encodeURIComponent(url.query[key])
buf.push(key + val)
})
return path + (buf.length ? '?' + buf.sort().join('&') : '')
}
module.exports.canonicalizeResource = canonicalizeResource

View File

@@ -0,0 +1,86 @@
{
"_args": [
[
{
"name": "aws-sign2",
"raw": "aws-sign2@~0.6.0",
"rawSpec": "~0.6.0",
"scope": null,
"spec": ">=0.6.0 <0.7.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "aws-sign2@>=0.6.0 <0.7.0",
"_id": "aws-sign2@0.6.0",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/aws-sign2",
"_nodeVersion": "4.1.2",
"_npmUser": {
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
},
"_npmVersion": "2.14.4",
"_phantomChildren": {},
"_requested": {
"name": "aws-sign2",
"raw": "aws-sign2@~0.6.0",
"rawSpec": "~0.6.0",
"scope": null,
"spec": ">=0.6.0 <0.7.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
"_shasum": "14342dd38dbcc94d0e5b87d763cd63612c0e794f",
"_shrinkwrap": null,
"_spec": "aws-sign2@~0.6.0",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "mikeal.rogers@gmail.com",
"name": "Mikeal Rogers",
"url": "http://www.futurealoof.com"
},
"bugs": {
"url": "https://github.com/mikeal/aws-sign/issues"
},
"dependencies": {},
"description": "AWS signing. Originally pulled from LearnBoost/knox, maintained as vendor in request, now a standalone module.",
"devDependencies": {},
"dist": {
"integrity": "sha512-JnJpAS0p9RmixkOvW2XwDxxzs1bd4/VAGIl6Q0EC5YOo+p+hqIhtDhn/nmFnB/xUNXbLkpE2mOjgVIBRKD4xYw==",
"shasum": "14342dd38dbcc94d0e5b87d763cd63612c0e794f",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIQCP59EXIRNLeMyKGCO0bZGuWbNLQTlip1qtGeqEvRyTHAIgNwGZIH1REbo8LOnJSG2K2zTuvD3JPoFEsNxGVR2TJDk="
}
],
"tarball": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz"
},
"engines": {
"node": "*"
},
"gitHead": "8554bdb41268fa295eb1ee300f4adaa9f7f07fec",
"homepage": "https://github.com/mikeal/aws-sign#readme",
"license": "Apache-2.0",
"main": "index.js",
"maintainers": [
{
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
}
],
"name": "aws-sign2",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"url": "git+https://github.com/mikeal/aws-sign.git"
},
"scripts": {},
"version": "0.6.0"
}

28
node_modules/phantomjs/node_modules/caseless/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,28 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

45
node_modules/phantomjs/node_modules/caseless/README.md generated vendored Normal file
View File

@@ -0,0 +1,45 @@
## Caseless -- wrap an object to set and get property with caseless semantics but also preserve caseing.
This library is incredibly useful when working with HTTP headers. It allows you to get/set/check for headers in a caseless manner while also preserving the caseing of headers the first time they are set.
## Usage
```javascript
var headers = {}
, c = caseless(headers)
;
c.set('a-Header', 'asdf')
c.get('a-header') === 'asdf'
```
## has(key)
Has takes a name and if it finds a matching header will return that header name with the preserved caseing it was set with.
```javascript
c.has('a-header') === 'a-Header'
```
## set(key, value[, clobber=true])
Set is fairly straight forward except that if the header exists and clobber is disabled it will add `','+value` to the existing header.
```javascript
c.set('a-Header', 'fdas')
c.set('a-HEADER', 'more', false)
c.get('a-header') === 'fdsa,more'
```
## swap(key)
Swaps the casing of a header with the new one that is passed in.
```javascript
var headers = {}
, c = caseless(headers)
;
c.set('a-Header', 'fdas')
c.swap('a-HEADER')
c.has('a-header') === 'a-HEADER'
headers === {'a-HEADER': 'fdas'}
```

66
node_modules/phantomjs/node_modules/caseless/index.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
function Caseless (dict) {
this.dict = dict || {}
}
Caseless.prototype.set = function (name, value, clobber) {
if (typeof name === 'object') {
for (var i in name) {
this.set(i, name[i], value)
}
} else {
if (typeof clobber === 'undefined') clobber = true
var has = this.has(name)
if (!clobber && has) this.dict[has] = this.dict[has] + ',' + value
else this.dict[has || name] = value
return has
}
}
Caseless.prototype.has = function (name) {
var keys = Object.keys(this.dict)
, name = name.toLowerCase()
;
for (var i=0;i<keys.length;i++) {
if (keys[i].toLowerCase() === name) return keys[i]
}
return false
}
Caseless.prototype.get = function (name) {
name = name.toLowerCase()
var result, _key
var headers = this.dict
Object.keys(headers).forEach(function (key) {
_key = key.toLowerCase()
if (name === _key) result = headers[key]
})
return result
}
Caseless.prototype.swap = function (name) {
var has = this.has(name)
if (!has) throw new Error('There is no header than matches "'+name+'"')
this.dict[name] = this.dict[has]
delete this.dict[has]
}
Caseless.prototype.del = function (name) {
var has = this.has(name)
return delete this.dict[has || name]
}
module.exports = function (dict) {return new Caseless(dict)}
module.exports.httpify = function (resp, headers) {
var c = new Caseless(headers)
resp.setHeader = function (key, value, clobber) {
if (typeof value === 'undefined') return
return c.set(key, value, clobber)
}
resp.hasHeader = function (key) {
return c.has(key)
}
resp.getHeader = function (key) {
return c.get(key)
}
resp.removeHeader = function (key) {
return c.del(key)
}
resp.headers = c.dict
return c
}

View File

@@ -0,0 +1,101 @@
{
"_args": [
[
{
"name": "caseless",
"raw": "caseless@~0.11.0",
"rawSpec": "~0.11.0",
"scope": null,
"spec": ">=0.11.0 <0.12.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "caseless@>=0.11.0 <0.12.0",
"_id": "caseless@0.11.0",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/caseless",
"_nodeVersion": "1.8.1",
"_npmUser": {
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
},
"_npmVersion": "2.8.3",
"_phantomChildren": {},
"_requested": {
"name": "caseless",
"raw": "caseless@~0.11.0",
"rawSpec": "~0.11.0",
"scope": null,
"spec": ">=0.11.0 <0.12.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz",
"_shasum": "715b96ea9841593cc33067923f5ec60ebda4f7d7",
"_shrinkwrap": null,
"_spec": "caseless@~0.11.0",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "mikeal.rogers@gmail.com",
"name": "Mikeal Rogers"
},
"bugs": {
"url": "https://github.com/mikeal/caseless/issues"
},
"dependencies": {},
"description": "Caseless object set/get/has, very useful when working with HTTP headers.",
"devDependencies": {
"tape": "^2.10.2"
},
"dist": {
"integrity": "sha512-ODLXH644w9C2fMPAm7bMDQ3GRvipZWZfKc+8As6hIadRIelE0n0xZuN38NS6kiK3KPEVrpymmQD8bvncAHWQkQ==",
"shasum": "715b96ea9841593cc33067923f5ec60ebda4f7d7",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEQCICfzl5F7m+qsN4BTHw4c2ZQ5n+YFWSMFJD65BkxJEQZvAiB/JtczBYO2QoJcX+G7uzLLmvDdj8UMod0pvcTO9b1oBw=="
}
],
"tarball": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz"
},
"gitHead": "c578232a02cc2b46b6da8851caf57fdbfac89ff5",
"homepage": "https://github.com/mikeal/caseless#readme",
"keywords": [
"headers",
"http",
"caseless"
],
"license": "Apache-2.0",
"main": "index.js",
"maintainers": [
{
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
},
{
"email": "jnylen@gmail.com",
"name": "nylen"
},
{
"email": "simeonvelichkov@gmail.com",
"name": "simov"
}
],
"name": "caseless",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/mikeal/caseless.git"
},
"scripts": {
"test": "node test.js"
},
"test": "node test.js",
"version": "0.11.0"
}

40
node_modules/phantomjs/node_modules/caseless/test.js generated vendored Normal file
View File

@@ -0,0 +1,40 @@
var tape = require('tape')
, caseless = require('./')
;
tape('set get has', function (t) {
var headers = {}
, c = caseless(headers)
;
t.plan(17)
c.set('a-Header', 'asdf')
t.equal(c.get('a-header'), 'asdf')
t.equal(c.has('a-header'), 'a-Header')
t.ok(!c.has('nothing'))
// old bug where we used the wrong regex
t.ok(!c.has('a-hea'))
c.set('a-header', 'fdsa')
t.equal(c.get('a-header'), 'fdsa')
t.equal(c.get('a-Header'), 'fdsa')
c.set('a-HEADER', 'more', false)
t.equal(c.get('a-header'), 'fdsa,more')
t.deepEqual(headers, {'a-Header': 'fdsa,more'})
c.swap('a-HEADER')
t.deepEqual(headers, {'a-HEADER': 'fdsa,more'})
c.set('deleteme', 'foobar')
t.ok(c.has('deleteme'))
t.ok(c.del('deleteme'))
t.notOk(c.has('deleteme'))
t.notOk(c.has('idonotexist'))
t.ok(c.del('idonotexist'))
c.set('tva', 'test1')
c.set('tva-header', 'test2')
t.equal(c.has('tva'), 'tva')
t.notOk(c.has('header'))
t.equal(c.get('tva'), 'test1')
})

19
node_modules/phantomjs/node_modules/form-data/License generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2012 Felix Geisendörfer (felix@debuggable.com) and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

217
node_modules/phantomjs/node_modules/form-data/README.md generated vendored Normal file
View File

@@ -0,0 +1,217 @@
# Form-Data [![NPM Module](https://img.shields.io/npm/v/form-data.svg)](https://www.npmjs.com/package/form-data) [![Join the chat at https://gitter.im/form-data/form-data](http://form-data.github.io/images/gitterbadge.svg)](https://gitter.im/form-data/form-data)
A library to create readable ```"multipart/form-data"``` streams. Can be used to submit forms and file uploads to other web applications.
The API of this library is inspired by the [XMLHttpRequest-2 FormData Interface][xhr2-fd].
[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface
[streams2-thing]: http://nodejs.org/api/stream.html#stream_compatibility_with_older_node_versions
[![Linux Build](https://img.shields.io/travis/form-data/form-data/v1.0.1.svg?label=linux:0.10-6.x)](https://travis-ci.org/form-data/form-data)
[![Windows Build](https://img.shields.io/appveyor/ci/alexindigo/form-data/v1.0.1.svg?label=windows:0.10-6.x)](https://ci.appveyor.com/project/alexindigo/form-data)
[![Coverage Status](https://img.shields.io/coveralls/form-data/form-data/v1.0.1.svg?label=code+coverage)](https://coveralls.io/github/form-data/form-data?branch=master)
[![Dependency Status](https://img.shields.io/david/form-data/form-data.svg)](https://david-dm.org/form-data/form-data)
[![bitHound Overall Score](https://www.bithound.io/github/form-data/form-data/badges/score.svg)](https://www.bithound.io/github/form-data/form-data)
## Install
```
npm install --save form-data
```
## Usage
In this example we are constructing a form with 3 fields that contain a string,
a buffer and a file stream.
``` javascript
var FormData = require('form-data');
var fs = require('fs');
var form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
```
Also you can use http-response stream:
``` javascript
var FormData = require('form-data');
var http = require('http');
var form = new FormData();
http.request('http://nodejs.org/images/logo.png', function(response) {
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_logo', response);
});
```
Or @mikeal's [request](https://github.com/request/request) stream:
``` javascript
var FormData = require('form-data');
var request = require('request');
var form = new FormData();
form.append('my_field', 'my value');
form.append('my_buffer', new Buffer(10));
form.append('my_logo', request('http://nodejs.org/images/logo.png'));
```
In order to submit this form to a web application, call ```submit(url, [callback])``` method:
``` javascript
form.submit('http://example.org/', function(err, res) {
// res response object (http.IncomingMessage) //
res.resume();
});
```
For more advanced request manipulations ```submit()``` method returns ```http.ClientRequest``` object, or you can choose from one of the alternative submission methods.
### Alternative submission methods
You can use node's http client interface:
``` javascript
var http = require('http');
var request = http.request({
method: 'post',
host: 'example.org',
path: '/upload',
headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
console.log(res.statusCode);
});
```
Or if you would prefer the `'Content-Length'` header to be set for you:
``` javascript
form.submit('example.org/upload', function(err, res) {
console.log(res.statusCode);
});
```
To use custom headers and pre-known length in parts:
``` javascript
var CRLF = '\r\n';
var form = new FormData();
var options = {
header: CRLF + '--' + form.getBoundary() + CRLF + 'X-Custom-Header: 123' + CRLF + CRLF,
knownLength: 1
};
form.append('my_buffer', buffer, options);
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
```
Form-Data can recognize and fetch all the required information from common types of streams (```fs.readStream```, ```http.response``` and ```mikeal's request```), for some other types of streams you'd need to provide "file"-related information manually:
``` javascript
someModule.stream(function(err, stdout, stderr) {
if (err) throw err;
var form = new FormData();
form.append('file', stdout, {
filename: 'unicycle.jpg',
contentType: 'image/jpg',
knownLength: 19806
});
form.submit('http://example.com/', function(err, res) {
if (err) throw err;
console.log('Done');
});
});
```
For edge cases, like POST request to URL with query string or to pass HTTP auth credentials, object can be passed to `form.submit()` as first parameter:
``` javascript
form.submit({
host: 'example.com',
path: '/probably.php?extra=params',
auth: 'username:password'
}, function(err, res) {
console.log(res.statusCode);
});
```
In case you need to also send custom HTTP headers with the POST request, you can use the `headers` key in first parameter of `form.submit()`:
``` javascript
form.submit({
host: 'example.com',
path: '/surelynot.php',
headers: {'x-test-header': 'test-header-value'}
}, function(err, res) {
console.log(res.statusCode);
});
```
### Integration with other libraries
#### Request
Form submission using [request](https://github.com/request/request):
```javascript
var formData = {
my_field: 'my_value',
my_file: fs.createReadStream(__dirname + '/unicycle.jpg'),
};
request.post({url:'http://service.com/upload', formData: formData}, function(err, httpResponse, body) {
if (err) {
return console.error('upload failed:', err);
}
console.log('Upload successful! Server responded with:', body);
});
```
For more details see [request readme](https://github.com/request/request#multipartform-data-multipart-form-uploads).
#### node-fetch
You can also submit a form using [node-fetch](https://github.com/bitinn/node-fetch):
```javascript
var form = new FormData();
form.append('a', 1);
fetch('http://example.com', { method: 'POST', body: form })
.then(function(res) {
return res.json();
}).then(function(json) {
console.log(json);
});
```
## Notes
- ```getLengthSync()``` method DOESN'T calculate length for streams, use ```knownLength``` options as workaround.
- If it feels like FormData hangs after submit, please check [Compatibility with Older Node Versions][streams2-thing]
## License
Form-Data is released under the [MIT](License) license.

View File

@@ -0,0 +1,2 @@
/* eslint-env browser */
module.exports = window.FormData;

View File

@@ -0,0 +1,437 @@
var CombinedStream = require('combined-stream');
var util = require('util');
var path = require('path');
var http = require('http');
var https = require('https');
var parseUrl = require('url').parse;
var fs = require('fs');
var mime = require('mime-types');
var async = require('async');
var populate = require('./populate.js');
// Public API
module.exports = FormData;
// make it a Stream
util.inherits(FormData, CombinedStream);
/**
* Create readable "multipart/form-data" streams.
* Can be used to submit forms
* and file uploads to other web applications.
*
* @constructor
*/
function FormData() {
if (!(this instanceof FormData)) {
throw new TypeError('Failed to construct FormData: Please use the _new_ operator, this object constructor cannot be called as a function.');
}
this._overheadLength = 0;
this._valueLength = 0;
this._lengthRetrievers = [];
CombinedStream.call(this);
}
FormData.LINE_BREAK = '\r\n';
FormData.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
FormData.prototype.append = function(field, value, options) {
options = options || {};
// allow filename as single option
if (typeof options == 'string') {
options = {filename: options};
}
var append = CombinedStream.prototype.append.bind(this);
// all that streamy business can't handle numbers
if (typeof value == 'number') {
value = '' + value;
}
// https://github.com/felixge/node-form-data/issues/38
if (util.isArray(value)) {
// Please convert your array into string
// the way web server expects it
this._error(new Error('Arrays are not supported.'));
return;
}
var header = this._multiPartHeader(field, value, options);
var footer = this._multiPartFooter();
append(header);
append(value);
append(footer);
// pass along options.knownLength
this._trackLength(header, value, options);
};
FormData.prototype._trackLength = function(header, value, options) {
var valueLength = 0;
// used w/ getLengthSync(), when length is known.
// e.g. for streaming directly from a remote server,
// w/ a known file a size, and not wanting to wait for
// incoming file to finish to get its size.
if (options.knownLength != null) {
valueLength += +options.knownLength;
} else if (Buffer.isBuffer(value)) {
valueLength = value.length;
} else if (typeof value === 'string') {
valueLength = Buffer.byteLength(value);
}
this._valueLength += valueLength;
// @check why add CRLF? does this account for custom/multiple CRLFs?
this._overheadLength +=
Buffer.byteLength(header) +
FormData.LINE_BREAK.length;
// empty or either doesn't have path or not an http response
if (!value || ( !value.path && !(value.readable && value.hasOwnProperty('httpVersion')) )) {
return;
}
// no need to bother with the length
if (!options.knownLength) {
this._lengthRetrievers.push(function(next) {
if (value.hasOwnProperty('fd')) {
// take read range into a account
// `end` = Infinity > read file till the end
//
// TODO: Looks like there is bug in Node fs.createReadStream
// it doesn't respect `end` options without `start` options
// Fix it when node fixes it.
// https://github.com/joyent/node/issues/7819
if (value.end != undefined && value.end != Infinity && value.start != undefined) {
// when end specified
// no need to calculate range
// inclusive, starts with 0
next(null, value.end + 1 - (value.start ? value.start : 0));
// not that fast snoopy
} else {
// still need to fetch file size from fs
fs.stat(value.path, function(err, stat) {
var fileSize;
if (err) {
next(err);
return;
}
// update final size based on the range options
fileSize = stat.size - (value.start ? value.start : 0);
next(null, fileSize);
});
}
// or http response
} else if (value.hasOwnProperty('httpVersion')) {
next(null, +value.headers['content-length']);
// or request stream http://github.com/mikeal/request
} else if (value.hasOwnProperty('httpModule')) {
// wait till response come back
value.on('response', function(response) {
value.pause();
next(null, +response.headers['content-length']);
});
value.resume();
// something else
} else {
next('Unknown stream');
}
});
}
};
FormData.prototype._multiPartHeader = function(field, value, options) {
// custom header specified (as string)?
// it becomes responsible for boundary
// (e.g. to handle extra CRLFs on .NET servers)
if (typeof options.header == 'string') {
return options.header;
}
var contentDisposition = this._getContentDisposition(value, options);
var contentType = this._getContentType(value, options);
var contents = '';
var headers = {
// add custom disposition as third element or keep it two elements if not
'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
// if no content type. allow it to be empty array
'Content-Type': [].concat(contentType || [])
};
// allow custom headers.
if (typeof options.header == 'object') {
populate(headers, options.header);
}
var header;
for (var prop in headers) {
header = headers[prop];
// skip nullish headers.
if (header == null) {
continue;
}
// convert all headers to arrays.
if (!Array.isArray(header)) {
header = [header];
}
// add non-empty headers.
if (header.length) {
contents += prop + ': ' + header.join('; ') + FormData.LINE_BREAK;
}
}
return '--' + this.getBoundary() + FormData.LINE_BREAK + contents + FormData.LINE_BREAK;
};
FormData.prototype._getContentDisposition = function(value, options) {
var contentDisposition;
// custom filename takes precedence
// fs- and request- streams have path property
// formidable and the browser add a name property.
var filename = options.filename || value.name || value.path;
// or try http response
if (!filename && value.readable && value.hasOwnProperty('httpVersion')) {
filename = value.client._httpMessage.path;
}
if (filename) {
contentDisposition = 'filename="' + path.basename(filename) + '"';
}
return contentDisposition;
};
FormData.prototype._getContentType = function(value, options) {
// use custom content-type above all
var contentType = options.contentType;
// or try `name` from formidable, browser
if (!contentType && value.name) {
contentType = mime.lookup(value.name);
}
// or try `path` from fs-, request- streams
if (!contentType && value.path) {
contentType = mime.lookup(value.path);
}
// or if it's http-reponse
if (!contentType && value.readable && value.hasOwnProperty('httpVersion')) {
contentType = value.headers['content-type'];
}
// or guess it from the filename
if (!contentType && options.filename) {
contentType = mime.lookup(options.filename);
}
// fallback to the default content type if `value` is not simple value
if (!contentType && typeof value == 'object') {
contentType = FormData.DEFAULT_CONTENT_TYPE;
}
return contentType;
};
FormData.prototype._multiPartFooter = function() {
return function(next) {
var footer = FormData.LINE_BREAK;
var lastPart = (this._streams.length === 0);
if (lastPart) {
footer += this._lastBoundary();
}
next(footer);
}.bind(this);
};
FormData.prototype._lastBoundary = function() {
return '--' + this.getBoundary() + '--' + FormData.LINE_BREAK;
};
FormData.prototype.getHeaders = function(userHeaders) {
var header;
var formHeaders = {
'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
};
for (header in userHeaders) {
if (userHeaders.hasOwnProperty(header)) {
formHeaders[header.toLowerCase()] = userHeaders[header];
}
}
return formHeaders;
};
// TODO: Looks like unused function
FormData.prototype.getCustomHeaders = function(contentType) {
contentType = contentType ? contentType : 'multipart/form-data';
var formHeaders = {
'content-type': contentType + '; boundary=' + this.getBoundary(),
'content-length': this.getLengthSync()
};
return formHeaders;
};
FormData.prototype.getBoundary = function() {
if (!this._boundary) {
this._generateBoundary();
}
return this._boundary;
};
FormData.prototype._generateBoundary = function() {
// This generates a 50 character boundary similar to those used by Firefox.
// They are optimized for boyer-moore parsing.
var boundary = '--------------------------';
for (var i = 0; i < 24; i++) {
boundary += Math.floor(Math.random() * 10).toString(16);
}
this._boundary = boundary;
};
// Note: getLengthSync DOESN'T calculate streams length
// As workaround one can calculate file size manually
// and add it as knownLength option
FormData.prototype.getLengthSync = function() {
var knownLength = this._overheadLength + this._valueLength;
// Don't get confused, there are 3 "internal" streams for each keyval pair
// so it basically checks if there is any value added to the form
if (this._streams.length) {
knownLength += this._lastBoundary().length;
}
// https://github.com/form-data/form-data/issues/40
if (this._lengthRetrievers.length) {
// Some async length retrievers are present
// therefore synchronous length calculation is false.
// Please use getLength(callback) to get proper length
this._error(new Error('Cannot calculate proper length in synchronous way.'));
}
return knownLength;
};
FormData.prototype.getLength = function(cb) {
var knownLength = this._overheadLength + this._valueLength;
if (this._streams.length) {
knownLength += this._lastBoundary().length;
}
if (!this._lengthRetrievers.length) {
process.nextTick(cb.bind(this, null, knownLength));
return;
}
async.parallel(this._lengthRetrievers, function(err, values) {
if (err) {
cb(err);
return;
}
values.forEach(function(length) {
knownLength += length;
});
cb(null, knownLength);
});
};
FormData.prototype.submit = function(params, cb) {
var request
, options
, defaults = {method: 'post'}
;
// parse provided url if it's string
// or treat it as options object
if (typeof params == 'string') {
params = parseUrl(params);
options = populate({
port: params.port,
path: params.pathname,
host: params.hostname
}, defaults);
// use custom params
} else {
options = populate(params, defaults);
// if no port provided use default one
if (!options.port) {
options.port = options.protocol == 'https:' ? 443 : 80;
}
}
// put that good code in getHeaders to some use
options.headers = this.getHeaders(params.headers);
// https if specified, fallback to http in any other case
if (options.protocol == 'https:') {
request = https.request(options);
} else {
request = http.request(options);
}
// get content length and fire away
this.getLength(function(err, length) {
if (err) {
this._error(err);
return;
}
// add content length
request.setHeader('Content-Length', length);
this.pipe(request);
if (cb) {
request.on('error', cb);
request.on('response', cb.bind(this, null));
}
}.bind(this));
return request;
};
FormData.prototype._error = function(err) {
if (!this.error) {
this.error = err;
this.pause();
this.emit('error', err);
}
};

View File

@@ -0,0 +1,10 @@
// populates missing values
module.exports = function(dst, src) {
Object.keys(src).forEach(function(prop)
{
dst[prop] = dst[prop] || src[prop];
});
return dst;
};

View File

@@ -0,0 +1,141 @@
{
"_args": [
[
{
"name": "form-data",
"raw": "form-data@~1.0.0-rc3",
"rawSpec": "~1.0.0-rc3",
"scope": null,
"spec": ">=1.0.0-rc3 <1.1.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "form-data@>=1.0.0-rc3 <1.1.0",
"_id": "form-data@1.0.1",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/form-data",
"_nodeVersion": "4.5.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/form-data-1.0.1.tgz_1472204677067_0.1879937476478517"
},
"_npmUser": {
"email": "iam@alexindigo.com",
"name": "alexindigo"
},
"_npmVersion": "2.15.9",
"_phantomChildren": {},
"_requested": {
"name": "form-data",
"raw": "form-data@~1.0.0-rc3",
"rawSpec": "~1.0.0-rc3",
"scope": null,
"spec": ">=1.0.0-rc3 <1.1.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz",
"_shasum": "ae315db9a4907fa065502304a66d7733475ee37c",
"_shrinkwrap": null,
"_spec": "form-data@~1.0.0-rc3",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "felix@debuggable.com",
"name": "Felix Geisendörfer",
"url": "http://debuggable.com/"
},
"browser": "./lib/browser",
"bugs": {
"url": "https://github.com/form-data/form-data/issues"
},
"dependencies": {
"async": "^2.0.1",
"combined-stream": "^1.0.5",
"mime-types": "^2.1.11"
},
"description": "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.",
"devDependencies": {
"coveralls": "^2.11.12",
"cross-spawn": "^4.0.0",
"eslint": "^2.13.1",
"fake": "^0.2.2",
"far": "^0.0.7",
"formidable": "^1.0.17",
"in-publish": "^2.0.0",
"istanbul": "^0.4.5",
"pkgfiles": "^2.3.0",
"pre-commit": "^1.1.3",
"request": "^2.74.0",
"rimraf": "^2.5.4"
},
"directories": {},
"dist": {
"integrity": "sha512-M4Yhq2mLogpCtpUmfopFlTTuIe6mSCTgKvnlMhDj3NcgVhA1uS20jT0n+xunKPzpmL5w2erSVtp+SKiJf1TlWg==",
"shasum": "ae315db9a4907fa065502304a66d7733475ee37c",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIGDMk1tL6IBIJuFSDCnOClhpcCSl38XriiZBX0/IVYNvAiEA/SQz3F5ZLpKR3uQTX40yROMNl4c+G3bYdVjP+fTrnv4="
}
],
"tarball": "https://registry.npmjs.org/form-data/-/form-data-1.0.1.tgz"
},
"engines": {
"node": ">= 0.10"
},
"gitHead": "158443da3b2ce221f0a06ccb3b8ab8c56b68b034",
"homepage": "https://github.com/form-data/form-data#readme",
"license": "MIT",
"main": "./lib/form_data",
"maintainers": [
{
"email": "iam@alexindigo.com",
"name": "alexindigo"
},
{
"email": "pierceydylan@gmail.com",
"name": "dylanpiercey"
},
{
"email": "felix@debuggable.com",
"name": "felixge"
},
{
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
}
],
"name": "form-data",
"optionalDependencies": {},
"pre-commit": [
"lint",
"test",
"check"
],
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/form-data/form-data.git"
},
"scripts": {
"check": "istanbul check-coverage coverage/coverage*.json",
"debug": "verbose=1 ./test/run.js",
"files": "pkgfiles --sort=name",
"get-version": "node -e \"console.log(require('./package.json').version)\"",
"lint": "eslint lib/*.js test/*.js test/**/*.js",
"postpublish": "npm run restore-readme",
"posttest": "istanbul report lcov text",
"predebug": "rimraf coverage test/tmp",
"prepublish": "in-publish && npm run update-readme || not-in-publish",
"pretest": "rimraf coverage test/tmp",
"restore-readme": "mv README.md.bak README.md",
"test": "istanbul cover test/run.js",
"update-readme": "sed -i.bak 's/\\/master\\.svg/\\/v'$(npm --silent run get-version)'.svg/g' README.md"
},
"version": "1.0.1"
}

View File

@@ -0,0 +1,13 @@
Copyright (c) 2015, Ahmad Nassri <ahmad@ahmadnassri.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,309 @@
# HAR Validator [![version][npm-version]][npm-url] [![License][npm-license]][license-url]
Extremely fast HTTP Archive ([HAR](http://www.softwareishard.com/blog/har-12-spec/)) validator using JSON Schema.
[![Build Status][travis-image]][travis-url]
[![Downloads][npm-downloads]][npm-url]
[![Code Climate][codeclimate-quality]][codeclimate-url]
[![Coverage Status][codeclimate-coverage]][codeclimate-url]
[![Dependencies][david-image]][david-url]
## Install
```shell
# to use in cli
npm install --global har-validator
# to use as a module
npm install --save har-validator
```
## Usage
```
Usage: har-validator [options] <files ...>
Options:
-h, --help output usage information
-V, --version output the version number
-s, --schema [name] validate schema name (log, request, response, etc ...)
```
###### Example
```shell
har-validator har.json
har-validator --schema request request.json
```
## API
**Note**: as of [`v2.0.0`](https://github.com/ahmadnassri/har-validator/releases/tag/v2.0.0) this module defaults to Promise based API. *For backward comptability with `v1.x` an [async/callback API](#callback-api) is provided*
### Validate(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a full [HAR](http://www.softwareishard.com/blog/har-12-spec/) object
```js
validate(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.log(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [log](http://www.softwareishard.com/blog/har-12-spec/#log) object
```js
validate.log(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.cache(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [cache](http://www.softwareishard.com/blog/har-12-spec/#cache) object
```js
validate.cache(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.cacheEntry(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a ["beforeRequest" or "afterRequest"](http://www.softwareishard.com/blog/har-12-spec/#cache) objects
```js
validate.cacheEntry(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.content(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [content](http://www.softwareishard.com/blog/har-12-spec/#content) object
```js
validate.content(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.cookie(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [cookie](http://www.softwareishard.com/blog/har-12-spec/#cookies) object
```js
validate.cookie(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.creator(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [creator](http://www.softwareishard.com/blog/har-12-spec/#creator) object
```js
validate.creator(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.entry(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
an [entry](http://www.softwareishard.com/blog/har-12-spec/#entries) object
```js
validate.entry(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.log(data)
alias of [`Validate(data)`](#validate-data-callback-)
### Validate.page(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [page](http://www.softwareishard.com/blog/har-12-spec/#pages) object
```js
validate.page(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.pageTimings(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [pageTimings](http://www.softwareishard.com/blog/har-12-spec/#pageTimings) object
```js
validate.pageTimings(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.postData(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [postData](http://www.softwareishard.com/blog/har-12-spec/#postData) object
```js
validate.postData(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.record(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [record](http://www.softwareishard.com/blog/har-12-spec/#headers) object
```js
validate.record(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.request(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [request](http://www.softwareishard.com/blog/har-12-spec/#request) object
```js
validate.request(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.response(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [response](http://www.softwareishard.com/blog/har-12-spec/#response) object
```js
validate.cacheEntry(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
### Validate.timings(data)
> Returns a promise that resolves to the valid object.
- **data**: `Object` *(Required)*
a [timings](http://www.softwareishard.com/blog/har-12-spec/#timings) object
```js
validate.timings(data)
.then(data => console.log('horray!'))
.catch(console.error)
```
----
## Callback API
### Validate(data [, callback])
> Returns `true` or `false`.
```js
var HAR = require('./har.json');
var validate = require('har-validator/lib/async');
validate(HAR, function (e, valid) {
if (e) console.log(e.errors)
if (valid) console.log('horray!');
});
```
The async API provides exactly the same methods as the [Promise API](#promise-api)
----
## Support
Donations are welcome to help support the continuous development of this project.
[![Gratipay][gratipay-image]][gratipay-url]
[![PayPal][paypal-image]][paypal-url]
[![Flattr][flattr-image]][flattr-url]
[![Bitcoin][bitcoin-image]][bitcoin-url]
## License
[ISC License](LICENSE) &copy; [Ahmad Nassri](https://www.ahmadnassri.com/)
[license-url]: https://github.com/ahmadnassri/har-validator/blob/master/LICENSE
[travis-url]: https://travis-ci.org/ahmadnassri/har-validator
[travis-image]: https://img.shields.io/travis/ahmadnassri/har-validator.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/har-validator
[npm-license]: https://img.shields.io/npm/l/har-validator.svg?style=flat-square
[npm-version]: https://img.shields.io/npm/v/har-validator.svg?style=flat-square
[npm-downloads]: https://img.shields.io/npm/dm/har-validator.svg?style=flat-square
[codeclimate-url]: https://codeclimate.com/github/ahmadnassri/har-validator
[codeclimate-quality]: https://img.shields.io/codeclimate/github/ahmadnassri/har-validator.svg?style=flat-square
[codeclimate-coverage]: https://img.shields.io/codeclimate/coverage/github/ahmadnassri/har-validator.svg?style=flat-square
[david-url]: https://david-dm.org/ahmadnassri/har-validator
[david-image]: https://img.shields.io/david/ahmadnassri/har-validator.svg?style=flat-square
[gratipay-url]: https://www.gratipay.com/ahmadnassri/
[gratipay-image]: https://img.shields.io/gratipay/ahmadnassri.svg?style=flat-square
[paypal-url]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=UJ2B2BTK9VLRS&on0=project&os0=har-validator
[paypal-image]: http://img.shields.io/badge/paypal-donate-green.svg?style=flat-square
[flattr-url]: https://flattr.com/submit/auto?user_id=ahmadnassri&url=https://github.com/ahmadnassri/har-validator&title=har-validator&language=&tags=github&category=software
[flattr-image]: http://img.shields.io/badge/flattr-donate-green.svg?style=flat-square
[bitcoin-image]: http://img.shields.io/badge/bitcoin-1Nb46sZRVG3or7pNaDjthcGJpWhvoPpCxy-green.svg?style=flat-square
[bitcoin-url]: https://www.coinbase.com/checkouts/ae383ae6bb931a2fa5ad11cec115191e?name=har-validator

View File

@@ -0,0 +1,56 @@
#!/usr/bin/env node
'use strict'
var chalk = require('chalk')
var cmd = require('commander')
var fs = require('fs')
var path = require('path')
var pkg = require('../package.json')
var Promise = require('pinkie-promise')
var validate = require('..')
var ValidationError = require('../lib/error')
cmd
.version(pkg.version)
.usage('[options] <files ...>')
.option('-s, --schema [name]', 'validate schema name (log, request, response, etc ...)')
.parse(process.argv)
if (!cmd.args.length) {
cmd.help()
}
cmd.args.map(function (fileName) {
var file = chalk.yellow.italic(path.basename(fileName))
new Promise(function (resolve, reject) {
fs.readFile(fileName, function (err, data) {
return err === null ? resolve(data) : reject(err)
})
})
.then(JSON.parse)
.then(cmd.schema ? validate[cmd.schema] : validate)
.then(function (data) {
console.log('%s [%s] is valid', chalk.green('✓'), file)
})
.catch(function (err) {
if (err instanceof SyntaxError) {
return console.error('%s [%s] failed to read JSON: %s', chalk.red('✖'), file, chalk.red(err.message))
}
if (err instanceof ValidationError) {
err.errors.forEach(function (details) {
console.error('%s [%s] failed validation: (%s: %s) %s', chalk.red('✖'), file, chalk.cyan.italic(details.field), chalk.magenta.italic(details.value), chalk.red(details.message))
})
return
}
console.error('%s [%s] an unknown error has occured: %s', chalk.red('✖'), file, chalk.red(err.message))
})
})

View File

@@ -0,0 +1,14 @@
'use strict'
var runner = require('./runner')
var schemas = require('./schemas')
module.exports = function (data, cb) {
return runner(schemas.har, data, cb)
}
Object.keys(schemas).map(function (name) {
module.exports[name] = function (data, cb) {
return runner(schemas[name], data, cb)
}
})

View File

@@ -0,0 +1,10 @@
'use strict'
function ValidationError (errors) {
this.name = 'ValidationError'
this.errors = errors
}
ValidationError.prototype = Error.prototype
module.exports = ValidationError

View File

@@ -0,0 +1,22 @@
'use strict'
var Promise = require('pinkie-promise')
var runner = require('./runner')
var schemas = require('./schemas')
var promisify = function (schema) {
return function (data) {
return new Promise(function (resolve, reject) {
runner(schema, data, function (err, valid) {
return err === null ? resolve(data) : reject(err)
})
})
}
}
module.exports = promisify(schemas.har)
// utility methods for all parts of the schema
Object.keys(schemas).map(function (name) {
module.exports[name] = promisify(schemas[name])
})

View File

@@ -0,0 +1,29 @@
'use strict'
var schemas = require('./schemas')
var ValidationError = require('./error')
var validator = require('is-my-json-valid')
module.exports = function (schema, data, cb) {
// default value
var valid = false
// validator config
var validate = validator(schema, {
greedy: true,
verbose: true,
schemas: schemas
})
// execute is-my-json-valid
if (data !== undefined) {
valid = validate(data)
}
// callback?
if (typeof cb === 'function') {
return cb(validate.errors ? new ValidationError(validate.errors) : null, valid)
}
return valid
}

View File

@@ -0,0 +1,13 @@
{
"properties": {
"beforeRequest": {
"$ref": "#cacheEntry"
},
"afterRequest": {
"$ref": "#cacheEntry"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,31 @@
{
"oneOf": [{
"type": "object",
"optional": true,
"required": [
"lastAccess",
"eTag",
"hitCount"
],
"properties": {
"expires": {
"type": "string"
},
"lastAccess": {
"type": "string"
},
"eTag": {
"type": "string"
},
"hitCount": {
"type": "integer"
},
"comment": {
"type": "string"
}
}
}, {
"type": null,
"additionalProperties": false
}]
}

View File

@@ -0,0 +1,27 @@
{
"type": "object",
"required": [
"size",
"mimeType"
],
"properties": {
"size": {
"type": "integer"
},
"compression": {
"type": "integer"
},
"mimeType": {
"type": "string"
},
"text": {
"type": "string"
},
"encoding": {
"type": "string"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,34 @@
{
"type": "object",
"required": [
"name",
"value"
],
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"path": {
"type": "string"
},
"domain": {
"type": "string"
},
"expires": {
"type": ["string", "null"],
"format": "date-time"
},
"httpOnly": {
"type": "boolean"
},
"secure": {
"type": "boolean"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,18 @@
{
"type": "object",
"required": [
"name",
"version"
],
"properties": {
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,51 @@
{
"type": "object",
"optional": true,
"required": [
"startedDateTime",
"time",
"request",
"response",
"cache",
"timings"
],
"properties": {
"pageref": {
"type": "string"
},
"startedDateTime": {
"type": "string",
"format": "date-time",
"pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))"
},
"time": {
"type": "number",
"min": 0
},
"request": {
"$ref": "#request"
},
"response": {
"$ref": "#response"
},
"cache": {
"$ref": "#cache"
},
"timings": {
"$ref": "#timings"
},
"serverIPAddress": {
"type": "string",
"oneOf": [
{ "format": "ipv4" },
{ "format": "ipv6" }
]
},
"connection": {
"type": "string"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,11 @@
{
"type": "object",
"required": [
"log"
],
"properties": {
"log": {
"$ref": "#log"
}
}
}

View File

@@ -0,0 +1,49 @@
'use strict'
var schemas = {
cache: require('./cache.json'),
cacheEntry: require('./cacheEntry.json'),
content: require('./content.json'),
cookie: require('./cookie.json'),
creator: require('./creator.json'),
entry: require('./entry.json'),
har: require('./har.json'),
log: require('./log.json'),
page: require('./page.json'),
pageTimings: require('./pageTimings.json'),
postData: require('./postData.json'),
record: require('./record.json'),
request: require('./request.json'),
response: require('./response.json'),
timings: require('./timings.json')
}
// is-my-json-valid does not provide meaningful error messages for external schemas
// this is a workaround
schemas.cache.properties.beforeRequest = schemas.cacheEntry
schemas.cache.properties.afterRequest = schemas.cacheEntry
schemas.page.properties.pageTimings = schemas.pageTimings
schemas.request.properties.cookies.items = schemas.cookie
schemas.request.properties.headers.items = schemas.record
schemas.request.properties.queryString.items = schemas.record
schemas.request.properties.postData = schemas.postData
schemas.response.properties.cookies.items = schemas.cookie
schemas.response.properties.headers.items = schemas.record
schemas.response.properties.content = schemas.content
schemas.entry.properties.request = schemas.request
schemas.entry.properties.response = schemas.response
schemas.entry.properties.cache = schemas.cache
schemas.entry.properties.timings = schemas.timings
schemas.log.properties.creator = schemas.creator
schemas.log.properties.browser = schemas.creator
schemas.log.properties.pages.items = schemas.page
schemas.log.properties.entries.items = schemas.entry
schemas.har.properties.log = schemas.log
module.exports = schemas

View File

@@ -0,0 +1,34 @@
{
"type": "object",
"required": [
"version",
"creator",
"entries"
],
"properties": {
"version": {
"type": "string"
},
"creator": {
"$ref": "#creator"
},
"browser": {
"$ref": "#creator"
},
"pages": {
"type": "array",
"items": {
"$ref": "#page"
}
},
"entries": {
"type": "array",
"items": {
"$ref": "#entry"
}
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,30 @@
{
"type": "object",
"optional": true,
"required": [
"startedDateTime",
"id",
"title",
"pageTimings"
],
"properties": {
"startedDateTime": {
"type": "string",
"format": "date-time",
"pattern": "^(\\d{4})(-)?(\\d\\d)(-)?(\\d\\d)(T)?(\\d\\d)(:)?(\\d\\d)(:)?(\\d\\d)(\\.\\d+)?(Z|([+-])(\\d\\d)(:)?(\\d\\d))"
},
"id": {
"type": "string",
"unique": true
},
"title": {
"type": "string"
},
"pageTimings": {
"$ref": "#pageTimings"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,16 @@
{
"type": "object",
"properties": {
"onContentLoad": {
"type": "number",
"min": -1
},
"onLoad": {
"type": "number",
"min": -1
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,41 @@
{
"type": "object",
"optional": true,
"required": [
"mimeType"
],
"properties": {
"mimeType": {
"type": "string"
},
"text": {
"type": "string"
},
"params": {
"type": "array",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"fileName": {
"type": "string"
},
"contentType": {
"type": "string"
},
"comment": {
"type": "string"
}
}
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,18 @@
{
"type": "object",
"required": [
"name",
"value"
],
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,55 @@
{
"type": "object",
"required": [
"method",
"url",
"httpVersion",
"cookies",
"headers",
"queryString",
"headersSize",
"bodySize"
],
"properties": {
"method": {
"type": "string"
},
"url": {
"type": "string",
"format": "uri"
},
"httpVersion": {
"type": "string"
},
"cookies": {
"type": "array",
"items": {
"$ref": "#cookie"
}
},
"headers": {
"type": "array",
"items": {
"$ref": "#record"
}
},
"queryString": {
"type": "array",
"items": {
"$ref": "#record"
}
},
"postData": {
"$ref": "#postData"
},
"headersSize": {
"type": "integer"
},
"bodySize": {
"type": "integer"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,52 @@
{
"type": "object",
"required": [
"status",
"statusText",
"httpVersion",
"cookies",
"headers",
"content",
"redirectURL",
"headersSize",
"bodySize"
],
"properties": {
"status": {
"type": "integer"
},
"statusText": {
"type": "string"
},
"httpVersion": {
"type": "string"
},
"cookies": {
"type": "array",
"items": {
"$ref": "#cookie"
}
},
"headers": {
"type": "array",
"items": {
"$ref": "#record"
}
},
"content": {
"$ref": "#content"
},
"redirectURL": {
"type": "string"
},
"headersSize": {
"type": "integer"
},
"bodySize": {
"type": "integer"
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,40 @@
{
"required": [
"send",
"wait",
"receive"
],
"properties": {
"dns": {
"type": "number",
"min": -1
},
"connect": {
"type": "number",
"min": -1
},
"blocked": {
"type": "number",
"min": -1
},
"send": {
"type": "number",
"min": -1
},
"wait": {
"type": "number",
"min": -1
},
"receive": {
"type": "number",
"min": -1
},
"ssl": {
"type": "number",
"min": -1
},
"comment": {
"type": "string"
}
}
}

View File

@@ -0,0 +1,127 @@
{
"_args": [
[
{
"name": "har-validator",
"raw": "har-validator@~2.0.2",
"rawSpec": "~2.0.2",
"scope": null,
"spec": ">=2.0.2 <2.1.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "har-validator@>=2.0.2 <2.1.0",
"_id": "har-validator@2.0.6",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/har-validator",
"_nodeVersion": "5.2.0",
"_npmUser": {
"email": "ahmad@ahmadnassri.com",
"name": "ahmadnassri"
},
"_npmVersion": "3.3.12",
"_phantomChildren": {},
"_requested": {
"name": "har-validator",
"raw": "har-validator@~2.0.2",
"rawSpec": "~2.0.2",
"scope": null,
"spec": ">=2.0.2 <2.1.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
"_shasum": "cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d",
"_shrinkwrap": null,
"_spec": "har-validator@~2.0.2",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "ahmad@ahmadnassri.com",
"name": "Ahmad Nassri",
"url": "https://www.ahmadnassri.com/"
},
"bin": {
"har-validator": "bin/har-validator"
},
"bugs": {
"url": "https://github.com/ahmadnassri/har-validator/issues"
},
"dependencies": {
"chalk": "^1.1.1",
"commander": "^2.9.0",
"is-my-json-valid": "^2.12.4",
"pinkie-promise": "^2.0.0"
},
"deprecated": "this library is no longer supported",
"description": "Extremely fast HTTP Archive (HAR) validator using JSON Schema",
"devDependencies": {
"codeclimate-test-reporter": "0.2.1",
"echint": "^1.5.1",
"istanbul": "^0.4.2",
"mocha": "^2.3.4",
"require-directory": "^2.1.1",
"should": "^8.1.1",
"standard": "^5.4.1"
},
"directories": {},
"dist": {
"integrity": "sha512-P6tFV+wCcUL3nbyTDAvveDySfbhy0XkDtAIfZP6HITjM2WUsiPna/Eg1Yy93SFXvahqoX+kt0n+6xlXKDXYowA==",
"shasum": "cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDiZGpYmF2YYLQSRznLCSGxNr+IeEDkcPN120sdTRskWwIhAMKmH9cGxF5OH06yf/bfnP7ZS9KBu1JUKW8OMH6B2Js1"
}
],
"tarball": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz"
},
"echint": {
"ignore": [
"coverage/**"
]
},
"engines": {
"node": ">=0.10"
},
"files": [
"bin",
"lib"
],
"gitHead": "92ccddad2e5d13e6e32c764e06c347d67805b211",
"homepage": "https://github.com/ahmadnassri/har-validator",
"keywords": [
"har",
"http",
"archive",
"validate",
"validator"
],
"license": "ISC",
"main": "lib/index",
"maintainers": [
{
"email": "ahmad@ahmadnassri.com",
"name": "ahmadnassri"
}
],
"name": "har-validator",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/ahmadnassri/har-validator.git"
},
"scripts": {
"codeclimate": "codeclimate < coverage/lcov.info",
"coverage": "istanbul cover --dir coverage _mocha -- -R dot",
"posttest": "npm run coverage",
"pretest": "standard && echint",
"test": "mocha"
},
"version": "2.0.6"
}

View File

@@ -0,0 +1,6 @@
((nil . ((indent-tabs-mode . nil)
(tab-width . 8)
(fill-column . 80)))
(js-mode . ((js-indent-level . 2)
(indent-tabs-mode . nil)
)))

View File

@@ -0,0 +1,7 @@
.gitmodules
deps
docs
Makefile
node_modules
test
tools

View File

@@ -0,0 +1,46 @@
# node-http-signature changelog
## 1.1.1
- Version of dependency `assert-plus` updated: old version was missing
some license information
- Corrected examples in `http_signing.md`, added auto-tests to
automatically validate these examples
## 1.1.0
- Bump version of `sshpk` dependency, remove peerDependency on it since
it now supports exchanging objects between multiple versions of itself
where possible
## 1.0.2
- Bump min version of `jsprim` dependency, to include fixes for using
http-signature with `browserify`
## 1.0.1
- Bump minimum version of `sshpk` dependency, to include fixes for
whitespace tolerance in key parsing.
## 1.0.0
- First semver release.
- #36: Ensure verifySignature does not leak useful timing information
- #42: Bring the library up to the latest version of the spec (including the
request-target changes)
- Support for ECDSA keys and signatures.
- Now uses `sshpk` for key parsing, validation and conversion.
- Fixes for #21, #47, #39 and compatibility with node 0.8
## 0.11.0
- Split up HMAC and Signature verification to avoid vulnerabilities where a
key intended for use with one can be validated against the other method
instead.
## 0.10.2
- Updated versions of most dependencies.
- Utility functions exported for PEM => SSH-RSA conversion.
- Improvements to tests and examples.

View File

@@ -0,0 +1,18 @@
Copyright Joyent, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

View File

@@ -0,0 +1,79 @@
# node-http-signature
node-http-signature is a node.js library that has client and server components
for Joyent's [HTTP Signature Scheme](http_signing.md).
## Usage
Note the example below signs a request with the same key/cert used to start an
HTTP server. This is almost certainly not what you actually want, but is just
used to illustrate the API calls; you will need to provide your own key
management in addition to this library.
### Client
```js
var fs = require('fs');
var https = require('https');
var httpSignature = require('http-signature');
var key = fs.readFileSync('./key.pem', 'ascii');
var options = {
host: 'localhost',
port: 8443,
path: '/',
method: 'GET',
headers: {}
};
// Adds a 'Date' header in, signs it, and adds the
// 'Authorization' header in.
var req = https.request(options, function(res) {
console.log(res.statusCode);
});
httpSignature.sign(req, {
key: key,
keyId: './cert.pem'
});
req.end();
```
### Server
```js
var fs = require('fs');
var https = require('https');
var httpSignature = require('http-signature');
var options = {
key: fs.readFileSync('./key.pem'),
cert: fs.readFileSync('./cert.pem')
};
https.createServer(options, function (req, res) {
var rc = 200;
var parsed = httpSignature.parseRequest(req);
var pub = fs.readFileSync(parsed.keyId, 'ascii');
if (!httpSignature.verifySignature(parsed, pub))
rc = 401;
res.writeHead(rc);
res.end();
}).listen(8443);
```
## Installation
npm install http-signature
## License
MIT.
## Bugs
See <https://github.com/joyent/node-http-signature/issues>.

View File

@@ -0,0 +1,363 @@
# Abstract
This document describes a way to add origin authentication, message integrity,
and replay resistance to HTTP REST requests. It is intended to be used over
the HTTPS protocol.
# Copyright Notice
Copyright (c) 2011 Joyent, Inc. and the persons identified as document authors.
All rights reserved.
Code Components extracted from this document must include MIT License text.
# Introduction
This protocol is intended to provide a standard way for clients to sign HTTP
requests. RFC2617 (HTTP Authentication) defines Basic and Digest authentication
mechanisms, and RFC5246 (TLS 1.2) defines client-auth, both of which are widely
employed on the Internet today. However, it is common place that the burdens of
PKI prevent web service operators from deploying that methodology, and so many
fall back to Basic authentication, which has poor security characteristics.
Additionally, OAuth provides a fully-specified alternative for authorization
of web service requests, but is not (always) ideal for machine to machine
communication, as the key acquisition steps (generally) imply a fixed
infrastructure that may not make sense to a service provider (e.g., symmetric
keys).
Several web service providers have invented their own schemes for signing
HTTP requests, but to date, none have been placed in the public domain as a
standard. This document serves that purpose. There are no techniques in this
proposal that are novel beyond previous art, however, this aims to be a simple
mechanism for signing these requests.
# Signature Authentication Scheme
The "signature" authentication scheme is based on the model that the client must
authenticate itself with a digital signature produced by either a private
asymmetric key (e.g., RSA) or a shared symmetric key (e.g., HMAC). The scheme
is parameterized enough such that it is not bound to any particular key type or
signing algorithm. However, it does explicitly assume that clients can send an
HTTP `Date` header.
## Authorization Header
The client is expected to send an Authorization header (as defined in RFC 2617)
with the following parameterization:
credentials := "Signature" params
params := 1#(keyId | algorithm | [headers] | [ext] | signature)
digitalSignature := plain-string
keyId := "keyId" "=" <"> plain-string <">
algorithm := "algorithm" "=" <"> plain-string <">
headers := "headers" "=" <"> 1#headers-value <">
ext := "ext" "=" <"> plain-string <">
signature := "signature" "=" <"> plain-string <">
headers-value := plain-string
plain-string = 1*( %x20-21 / %x23-5B / %x5D-7E )
### Signature Parameters
#### keyId
REQUIRED. The `keyId` field is an opaque string that the server can use to look
up the component they need to validate the signature. It could be an SSH key
fingerprint, an LDAP DN, etc. Management of keys and assignment of `keyId` is
out of scope for this document.
#### algorithm
REQUIRED. The `algorithm` parameter is used if the client and server agree on a
non-standard digital signature algorithm. The full list of supported signature
mechanisms is listed below.
#### headers
OPTIONAL. The `headers` parameter is used to specify the list of HTTP headers
used to sign the request. If specified, it should be a quoted list of HTTP
header names, separated by a single space character. By default, only one
HTTP header is signed, which is the `Date` header. Note that the list MUST be
specified in the order the values are concatenated together during signing. To
include the HTTP request line in the signature calculation, use the special
`request-line` value. While this is overloading the definition of `headers` in
HTTP linguism, the request-line is defined in RFC 2616, and as the outlier from
headers in useful signature calculation, it is deemed simpler to simply use
`request-line` than to add a separate parameter for it.
#### extensions
OPTIONAL. The `extensions` parameter is used to include additional information
which is covered by the request. The content and format of the string is out of
scope for this document, and expected to be specified by implementors.
#### signature
REQUIRED. The `signature` parameter is a `Base64` encoded digital signature
generated by the client. The client uses the `algorithm` and `headers` request
parameters to form a canonicalized `signing string`. This `signing string` is
then signed with the key associated with `keyId` and the algorithm
corresponding to `algorithm`. The `signature` parameter is then set to the
`Base64` encoding of the signature.
### Signing String Composition
In order to generate the string that is signed with a key, the client MUST take
the values of each HTTP header specified by `headers` in the order they appear.
1. If the header name is not `request-line` then append the lowercased header
name followed with an ASCII colon `:` and an ASCII space ` `.
2. If the header name is `request-line` then append the HTTP request line,
otherwise append the header value.
3. If value is not the last value then append an ASCII newline `\n`. The string
MUST NOT include a trailing ASCII newline.
# Example Requests
All requests refer to the following request (body omitted):
POST /foo HTTP/1.1
Host: example.org
Date: Tue, 07 Jun 2014 20:51:35 GMT
Content-Type: application/json
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
Content-Length: 18
The "rsa-key-1" keyId refers to a private key known to the client and a public
key known to the server. The "hmac-key-1" keyId refers to key known to the
client and server.
## Default parameterization
The authorization header and signature would be generated as:
Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",signature="Base64(RSA-SHA256(signing string))"
The client would compose the signing string as:
date: Tue, 07 Jun 2014 20:51:35 GMT
## Header List
The authorization header and signature would be generated as:
Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",headers="(request-target) date content-type digest",signature="Base64(RSA-SHA256(signing string))"
The client would compose the signing string as (`+ "\n"` inserted for
readability):
(request-target) post /foo + "\n"
date: Tue, 07 Jun 2011 20:51:35 GMT + "\n"
content-type: application/json + "\n"
digest: SHA-256=Base64(SHA256(Body))
## Algorithm
The authorization header and signature would be generated as:
Authorization: Signature keyId="hmac-key-1",algorithm="hmac-sha1",signature="Base64(HMAC-SHA1(signing string))"
The client would compose the signing string as:
date: Tue, 07 Jun 2011 20:51:35 GMT
# Signing Algorithms
Currently supported algorithm names are:
* rsa-sha1
* rsa-sha256
* rsa-sha512
* dsa-sha1
* hmac-sha1
* hmac-sha256
* hmac-sha512
# Security Considerations
## Default Parameters
Note the default parameterization of the `Signature` scheme is only safe if all
requests are carried over a secure transport (i.e., TLS). Sending the default
scheme over a non-secure transport will leave the request vulnerable to
spoofing, tampering, replay/repudiation, and integrity violations (if using the
STRIDE threat-modeling methodology).
## Insecure Transports
If sending the request over plain HTTP, service providers SHOULD require clients
to sign ALL HTTP headers, and the `request-line`. Additionally, service
providers SHOULD require `Content-MD5` calculations to be performed to ensure
against any tampering from clients.
## Nonces
Nonces are out of scope for this document simply because many service providers
fail to implement them correctly, or do not adopt security specifications
because of the infrastructure complexity. Given the `header` parameterization,
a service provider is fully enabled to add nonce semantics into this scheme by
using something like an `x-request-nonce` header, and ensuring it is signed
with the `Date` header.
## Clock Skew
As the default scheme is to sign the `Date` header, service providers SHOULD
protect against logged replay attacks by enforcing a clock skew. The server
SHOULD be synchronized with NTP, and the recommendation in this specification
is to allow 300s of clock skew (in either direction).
## Required Headers to Sign
It is out of scope for this document to dictate what headers a service provider
will want to enforce, but service providers SHOULD at minimum include the
`Date` header.
# References
## Normative References
* [RFC2616] Hypertext Transfer Protocol -- HTTP/1.1
* [RFC2617] HTTP Authentication: Basic and Digest Access Authentication
* [RFC5246] The Transport Layer Security (TLS) Protocol Version 1.2
## Informative References
Name: Mark Cavage (editor)
Company: Joyent, Inc.
Email: mark.cavage@joyent.com
URI: http://www.joyent.com
# Appendix A - Test Values
The following test data uses the RSA (1024b) keys, which we will refer
to as `keyId=Test` in the following samples:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
oYi+1hqp1fIekaxsyQIDAQAB
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
-----END RSA PRIVATE KEY-----
And all examples use this request:
<!-- httpreq -->
POST /foo?param=value&pet=dog HTTP/1.1
Host: example.com
Date: Thu, 05 Jan 2014 21:31:40 GMT
Content-Type: application/json
Digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
Content-Length: 18
{"hello": "world"}
<!-- /httpreq -->
### Default
The string to sign would be:
<!-- sign {"name": "Default", "options": {"keyId":"Test", "algorithm": "rsa-sha256"}} -->
<!-- signstring -->
date: Thu, 05 Jan 2014 21:31:40 GMT
<!-- /signstring -->
The Authorization header would be:
<!-- authz -->
Authorization: Signature keyId="Test",algorithm="rsa-sha256",headers="date",signature="jKyvPcxB4JbmYY4mByyBY7cZfNl4OW9HpFQlG7N4YcJPteKTu4MWCLyk+gIr0wDgqtLWf9NLpMAMimdfsH7FSWGfbMFSrsVTHNTk0rK3usrfFnti1dxsM4jl0kYJCKTGI/UWkqiaxwNiKqGcdlEDrTcUhhsFsOIo8VhddmZTZ8w="
<!-- /authz -->
### All Headers
Parameterized to include all headers, the string to sign would be (`+ "\n"`
inserted for readability):
<!-- sign {"name": "All Headers", "options": {"keyId":"Test", "algorithm": "rsa-sha256", "headers": ["(request-target)", "host", "date", "content-type", "digest", "content-length"]}} -->
<!-- signstring -->
(request-target): post /foo?param=value&pet=dog
host: example.com
date: Thu, 05 Jan 2014 21:31:40 GMT
content-type: application/json
digest: SHA-256=X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=
content-length: 18
<!-- /signstring -->
The Authorization header would be:
<!-- authz -->
Authorization: Signature keyId="Test",algorithm="rsa-sha256",headers="(request-target) host date content-type digest content-length",signature="Ef7MlxLXoBovhil3AlyjtBwAL9g4TN3tibLj7uuNB3CROat/9KaeQ4hW2NiJ+pZ6HQEOx9vYZAyi+7cmIkmJszJCut5kQLAwuX+Ms/mUFvpKlSo9StS2bMXDBNjOh4Auj774GFj4gwjS+3NhFeoqyr/MuN6HsEnkvn6zdgfE2i0="
<!-- /authz -->
## Generating and verifying signatures using `openssl`
The `openssl` commandline tool can be used to generate or verify the signatures listed above.
Compose the signing string as usual, and pipe it into the the `openssl dgst` command, then into `openssl enc -base64`, as follows:
$ printf 'date: Thu, 05 Jan 2014 21:31:40 GMT' | \
openssl dgst -binary -sign /path/to/private.pem -sha256 | \
openssl enc -base64
jKyvPcxB4JbmYY4mByyBY7cZfNl4OW9Hp...
$
The `-sha256` option is necessary to produce an `rsa-sha256` signature. You can select other hash algorithms such as `sha1` by changing this argument.
To verify a signature, first save the signature data, Base64-decoded, into a file, then use `openssl dgst` again with the `-verify` option:
$ echo 'jKyvPcxB4JbmYY4mByy...' | openssl enc -A -d -base64 > signature
$ printf 'date: Thu, 05 Jan 2014 21:31:40 GMT' | \
openssl dgst -sha256 -verify /path/to/public.pem -signature ./signature
Verified OK
$
## Generating and verifying signatures using `sshpk-sign`
You can also generate and check signatures using the `sshpk-sign` tool which is
included with the `sshpk` package in `npm`.
Compose the signing string as above, and pipe it into `sshpk-sign` as follows:
$ printf 'date: Thu, 05 Jan 2014 21:31:40 GMT' | \
sshpk-sign -i /path/to/private.pem
jKyvPcxB4JbmYY4mByyBY7cZfNl4OW9Hp...
$
This will produce an `rsa-sha256` signature by default, as you can see using
the `-v` option:
sshpk-sign: using rsa-sha256 with a 1024 bit key
You can also use `sshpk-verify` in a similar manner:
$ printf 'date: Thu, 05 Jan 2014 21:31:40 GMT' | \
sshpk-verify -i ./public.pem -s 'jKyvPcxB4JbmYY...'
OK
$

View File

@@ -0,0 +1,29 @@
// Copyright 2015 Joyent, Inc.
var parser = require('./parser');
var signer = require('./signer');
var verify = require('./verify');
var utils = require('./utils');
///--- API
module.exports = {
parse: parser.parseRequest,
parseRequest: parser.parseRequest,
sign: signer.signRequest,
signRequest: signer.signRequest,
createSigner: signer.createSigner,
isSigner: signer.isSigner,
sshKeyToPEM: utils.sshKeyToPEM,
sshKeyFingerprint: utils.fingerprint,
pemToRsaSSHKey: utils.pemToRsaSSHKey,
verify: verify.verifySignature,
verifySignature: verify.verifySignature,
verifyHMAC: verify.verifyHMAC
};

View File

@@ -0,0 +1,318 @@
// Copyright 2012 Joyent, Inc. All rights reserved.
var assert = require('assert-plus');
var util = require('util');
var utils = require('./utils');
///--- Globals
var HASH_ALGOS = utils.HASH_ALGOS;
var PK_ALGOS = utils.PK_ALGOS;
var HttpSignatureError = utils.HttpSignatureError;
var InvalidAlgorithmError = utils.InvalidAlgorithmError;
var validateAlgorithm = utils.validateAlgorithm;
var State = {
New: 0,
Params: 1
};
var ParamsState = {
Name: 0,
Quote: 1,
Value: 2,
Comma: 3
};
///--- Specific Errors
function ExpiredRequestError(message) {
HttpSignatureError.call(this, message, ExpiredRequestError);
}
util.inherits(ExpiredRequestError, HttpSignatureError);
function InvalidHeaderError(message) {
HttpSignatureError.call(this, message, InvalidHeaderError);
}
util.inherits(InvalidHeaderError, HttpSignatureError);
function InvalidParamsError(message) {
HttpSignatureError.call(this, message, InvalidParamsError);
}
util.inherits(InvalidParamsError, HttpSignatureError);
function MissingHeaderError(message) {
HttpSignatureError.call(this, message, MissingHeaderError);
}
util.inherits(MissingHeaderError, HttpSignatureError);
function StrictParsingError(message) {
HttpSignatureError.call(this, message, StrictParsingError);
}
util.inherits(StrictParsingError, HttpSignatureError);
///--- Exported API
module.exports = {
/**
* Parses the 'Authorization' header out of an http.ServerRequest object.
*
* Note that this API will fully validate the Authorization header, and throw
* on any error. It will not however check the signature, or the keyId format
* as those are specific to your environment. You can use the options object
* to pass in extra constraints.
*
* As a response object you can expect this:
*
* {
* "scheme": "Signature",
* "params": {
* "keyId": "foo",
* "algorithm": "rsa-sha256",
* "headers": [
* "date" or "x-date",
* "digest"
* ],
* "signature": "base64"
* },
* "signingString": "ready to be passed to crypto.verify()"
* }
*
* @param {Object} request an http.ServerRequest.
* @param {Object} options an optional options object with:
* - clockSkew: allowed clock skew in seconds (default 300).
* - headers: required header names (def: date or x-date)
* - algorithms: algorithms to support (default: all).
* - strict: should enforce latest spec parsing
* (default: false).
* @return {Object} parsed out object (see above).
* @throws {TypeError} on invalid input.
* @throws {InvalidHeaderError} on an invalid Authorization header error.
* @throws {InvalidParamsError} if the params in the scheme are invalid.
* @throws {MissingHeaderError} if the params indicate a header not present,
* either in the request headers from the params,
* or not in the params from a required header
* in options.
* @throws {StrictParsingError} if old attributes are used in strict parsing
* mode.
* @throws {ExpiredRequestError} if the value of date or x-date exceeds skew.
*/
parseRequest: function parseRequest(request, options) {
assert.object(request, 'request');
assert.object(request.headers, 'request.headers');
if (options === undefined) {
options = {};
}
if (options.headers === undefined) {
options.headers = [request.headers['x-date'] ? 'x-date' : 'date'];
}
assert.object(options, 'options');
assert.arrayOfString(options.headers, 'options.headers');
assert.optionalNumber(options.clockSkew, 'options.clockSkew');
if (!request.headers.authorization)
throw new MissingHeaderError('no authorization header present in ' +
'the request');
options.clockSkew = options.clockSkew || 300;
var i = 0;
var state = State.New;
var substate = ParamsState.Name;
var tmpName = '';
var tmpValue = '';
var parsed = {
scheme: '',
params: {},
signingString: '',
get algorithm() {
return this.params.algorithm.toUpperCase();
},
get keyId() {
return this.params.keyId;
}
};
var authz = request.headers.authorization;
for (i = 0; i < authz.length; i++) {
var c = authz.charAt(i);
switch (Number(state)) {
case State.New:
if (c !== ' ') parsed.scheme += c;
else state = State.Params;
break;
case State.Params:
switch (Number(substate)) {
case ParamsState.Name:
var code = c.charCodeAt(0);
// restricted name of A-Z / a-z
if ((code >= 0x41 && code <= 0x5a) || // A-Z
(code >= 0x61 && code <= 0x7a)) { // a-z
tmpName += c;
} else if (c === '=') {
if (tmpName.length === 0)
throw new InvalidHeaderError('bad param format');
substate = ParamsState.Quote;
} else {
throw new InvalidHeaderError('bad param format');
}
break;
case ParamsState.Quote:
if (c === '"') {
tmpValue = '';
substate = ParamsState.Value;
} else {
throw new InvalidHeaderError('bad param format');
}
break;
case ParamsState.Value:
if (c === '"') {
parsed.params[tmpName] = tmpValue;
substate = ParamsState.Comma;
} else {
tmpValue += c;
}
break;
case ParamsState.Comma:
if (c === ',') {
tmpName = '';
substate = ParamsState.Name;
} else {
throw new InvalidHeaderError('bad param format');
}
break;
default:
throw new Error('Invalid substate');
}
break;
default:
throw new Error('Invalid substate');
}
}
if (!parsed.params.headers || parsed.params.headers === '') {
if (request.headers['x-date']) {
parsed.params.headers = ['x-date'];
} else {
parsed.params.headers = ['date'];
}
} else {
parsed.params.headers = parsed.params.headers.split(' ');
}
// Minimally validate the parsed object
if (!parsed.scheme || parsed.scheme !== 'Signature')
throw new InvalidHeaderError('scheme was not "Signature"');
if (!parsed.params.keyId)
throw new InvalidHeaderError('keyId was not specified');
if (!parsed.params.algorithm)
throw new InvalidHeaderError('algorithm was not specified');
if (!parsed.params.signature)
throw new InvalidHeaderError('signature was not specified');
// Check the algorithm against the official list
parsed.params.algorithm = parsed.params.algorithm.toLowerCase();
try {
validateAlgorithm(parsed.params.algorithm);
} catch (e) {
if (e instanceof InvalidAlgorithmError)
throw (new InvalidParamsError(parsed.params.algorithm + ' is not ' +
'supported'));
else
throw (e);
}
// Build the signingString
for (i = 0; i < parsed.params.headers.length; i++) {
var h = parsed.params.headers[i].toLowerCase();
parsed.params.headers[i] = h;
if (h === 'request-line') {
if (!options.strict) {
/*
* We allow headers from the older spec drafts if strict parsing isn't
* specified in options.
*/
parsed.signingString +=
request.method + ' ' + request.url + ' HTTP/' + request.httpVersion;
} else {
/* Strict parsing doesn't allow older draft headers. */
throw (new StrictParsingError('request-line is not a valid header ' +
'with strict parsing enabled.'));
}
} else if (h === '(request-target)') {
parsed.signingString +=
'(request-target): ' + request.method.toLowerCase() + ' ' +
request.url;
} else {
var value = request.headers[h];
if (value === undefined)
throw new MissingHeaderError(h + ' was not in the request');
parsed.signingString += h + ': ' + value;
}
if ((i + 1) < parsed.params.headers.length)
parsed.signingString += '\n';
}
// Check against the constraints
var date;
if (request.headers.date || request.headers['x-date']) {
if (request.headers['x-date']) {
date = new Date(request.headers['x-date']);
} else {
date = new Date(request.headers.date);
}
var now = new Date();
var skew = Math.abs(now.getTime() - date.getTime());
if (skew > options.clockSkew * 1000) {
throw new ExpiredRequestError('clock skew of ' +
(skew / 1000) +
's was greater than ' +
options.clockSkew + 's');
}
}
options.headers.forEach(function (hdr) {
// Remember that we already checked any headers in the params
// were in the request, so if this passes we're good.
if (parsed.params.headers.indexOf(hdr) < 0)
throw new MissingHeaderError(hdr + ' was not a signed header');
});
if (options.algorithms) {
if (options.algorithms.indexOf(parsed.params.algorithm) === -1)
throw new InvalidParamsError(parsed.params.algorithm +
' is not a supported algorithm');
}
return parsed;
}
};

View File

@@ -0,0 +1,399 @@
// Copyright 2012 Joyent, Inc. All rights reserved.
var assert = require('assert-plus');
var crypto = require('crypto');
var http = require('http');
var util = require('util');
var sshpk = require('sshpk');
var jsprim = require('jsprim');
var utils = require('./utils');
var sprintf = require('util').format;
var HASH_ALGOS = utils.HASH_ALGOS;
var PK_ALGOS = utils.PK_ALGOS;
var InvalidAlgorithmError = utils.InvalidAlgorithmError;
var HttpSignatureError = utils.HttpSignatureError;
var validateAlgorithm = utils.validateAlgorithm;
///--- Globals
var AUTHZ_FMT =
'Signature keyId="%s",algorithm="%s",headers="%s",signature="%s"';
///--- Specific Errors
function MissingHeaderError(message) {
HttpSignatureError.call(this, message, MissingHeaderError);
}
util.inherits(MissingHeaderError, HttpSignatureError);
function StrictParsingError(message) {
HttpSignatureError.call(this, message, StrictParsingError);
}
util.inherits(StrictParsingError, HttpSignatureError);
/* See createSigner() */
function RequestSigner(options) {
assert.object(options, 'options');
var alg = [];
if (options.algorithm !== undefined) {
assert.string(options.algorithm, 'options.algorithm');
alg = validateAlgorithm(options.algorithm);
}
this.rs_alg = alg;
/*
* RequestSigners come in two varieties: ones with an rs_signFunc, and ones
* with an rs_signer.
*
* rs_signFunc-based RequestSigners have to build up their entire signing
* string within the rs_lines array and give it to rs_signFunc as a single
* concat'd blob. rs_signer-based RequestSigners can add a line at a time to
* their signing state by using rs_signer.update(), thus only needing to
* buffer the hash function state and one line at a time.
*/
if (options.sign !== undefined) {
assert.func(options.sign, 'options.sign');
this.rs_signFunc = options.sign;
} else if (alg[0] === 'hmac' && options.key !== undefined) {
assert.string(options.keyId, 'options.keyId');
this.rs_keyId = options.keyId;
if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key))
throw (new TypeError('options.key for HMAC must be a string or Buffer'));
/*
* Make an rs_signer for HMACs, not a rs_signFunc -- HMACs digest their
* data in chunks rather than requiring it all to be given in one go
* at the end, so they are more similar to signers than signFuncs.
*/
this.rs_signer = crypto.createHmac(alg[1].toUpperCase(), options.key);
this.rs_signer.sign = function () {
var digest = this.digest('base64');
return ({
hashAlgorithm: alg[1],
toString: function () { return (digest); }
});
};
} else if (options.key !== undefined) {
var key = options.key;
if (typeof (key) === 'string' || Buffer.isBuffer(key))
key = sshpk.parsePrivateKey(key);
assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),
'options.key must be a sshpk.PrivateKey');
this.rs_key = key;
assert.string(options.keyId, 'options.keyId');
this.rs_keyId = options.keyId;
if (!PK_ALGOS[key.type]) {
throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +
'keys are not supported'));
}
if (alg[0] !== undefined && key.type !== alg[0]) {
throw (new InvalidAlgorithmError('options.key must be a ' +
alg[0].toUpperCase() + ' key, was given a ' +
key.type.toUpperCase() + ' key instead'));
}
this.rs_signer = key.createSign(alg[1]);
} else {
throw (new TypeError('options.sign (func) or options.key is required'));
}
this.rs_headers = [];
this.rs_lines = [];
}
/**
* Adds a header to be signed, with its value, into this signer.
*
* @param {String} header
* @param {String} value
* @return {String} value written
*/
RequestSigner.prototype.writeHeader = function (header, value) {
assert.string(header, 'header');
header = header.toLowerCase();
assert.string(value, 'value');
this.rs_headers.push(header);
if (this.rs_signFunc) {
this.rs_lines.push(header + ': ' + value);
} else {
var line = header + ': ' + value;
if (this.rs_headers.length > 0)
line = '\n' + line;
this.rs_signer.update(line);
}
return (value);
};
/**
* Adds a default Date header, returning its value.
*
* @return {String}
*/
RequestSigner.prototype.writeDateHeader = function () {
return (this.writeHeader('date', jsprim.rfc1123(new Date())));
};
/**
* Adds the request target line to be signed.
*
* @param {String} method, HTTP method (e.g. 'get', 'post', 'put')
* @param {String} path
*/
RequestSigner.prototype.writeTarget = function (method, path) {
assert.string(method, 'method');
assert.string(path, 'path');
method = method.toLowerCase();
this.writeHeader('(request-target)', method + ' ' + path);
};
/**
* Calculate the value for the Authorization header on this request
* asynchronously.
*
* @param {Func} callback (err, authz)
*/
RequestSigner.prototype.sign = function (cb) {
assert.func(cb, 'callback');
if (this.rs_headers.length < 1)
throw (new Error('At least one header must be signed'));
var alg, authz;
if (this.rs_signFunc) {
var data = this.rs_lines.join('\n');
var self = this;
this.rs_signFunc(data, function (err, sig) {
if (err) {
cb(err);
return;
}
try {
assert.object(sig, 'signature');
assert.string(sig.keyId, 'signature.keyId');
assert.string(sig.algorithm, 'signature.algorithm');
assert.string(sig.signature, 'signature.signature');
alg = validateAlgorithm(sig.algorithm);
authz = sprintf(AUTHZ_FMT,
sig.keyId,
sig.algorithm,
self.rs_headers.join(' '),
sig.signature);
} catch (e) {
cb(e);
return;
}
cb(null, authz);
});
} else {
try {
var sigObj = this.rs_signer.sign();
} catch (e) {
cb(e);
return;
}
alg = (this.rs_alg[0] || this.rs_key.type) + '-' + sigObj.hashAlgorithm;
var signature = sigObj.toString();
authz = sprintf(AUTHZ_FMT,
this.rs_keyId,
alg,
this.rs_headers.join(' '),
signature);
cb(null, authz);
}
};
///--- Exported API
module.exports = {
/**
* Identifies whether a given object is a request signer or not.
*
* @param {Object} object, the object to identify
* @returns {Boolean}
*/
isSigner: function (obj) {
if (typeof (obj) === 'object' && obj instanceof RequestSigner)
return (true);
return (false);
},
/**
* Creates a request signer, used to asynchronously build a signature
* for a request (does not have to be an http.ClientRequest).
*
* @param {Object} options, either:
* - {String} keyId
* - {String|Buffer} key
* - {String} algorithm (optional, required for HMAC)
* or:
* - {Func} sign (data, cb)
* @return {RequestSigner}
*/
createSigner: function createSigner(options) {
return (new RequestSigner(options));
},
/**
* Adds an 'Authorization' header to an http.ClientRequest object.
*
* Note that this API will add a Date header if it's not already set. Any
* other headers in the options.headers array MUST be present, or this
* will throw.
*
* You shouldn't need to check the return type; it's just there if you want
* to be pedantic.
*
* The optional flag indicates whether parsing should use strict enforcement
* of the version draft-cavage-http-signatures-04 of the spec or beyond.
* The default is to be loose and support
* older versions for compatibility.
*
* @param {Object} request an instance of http.ClientRequest.
* @param {Object} options signing parameters object:
* - {String} keyId required.
* - {String} key required (either a PEM or HMAC key).
* - {Array} headers optional; defaults to ['date'].
* - {String} algorithm optional (unless key is HMAC);
* default is the same as the sshpk default
* signing algorithm for the type of key given
* - {String} httpVersion optional; defaults to '1.1'.
* - {Boolean} strict optional; defaults to 'false'.
* @return {Boolean} true if Authorization (and optionally Date) were added.
* @throws {TypeError} on bad parameter types (input).
* @throws {InvalidAlgorithmError} if algorithm was bad or incompatible with
* the given key.
* @throws {sshpk.KeyParseError} if key was bad.
* @throws {MissingHeaderError} if a header to be signed was specified but
* was not present.
*/
signRequest: function signRequest(request, options) {
assert.object(request, 'request');
assert.object(options, 'options');
assert.optionalString(options.algorithm, 'options.algorithm');
assert.string(options.keyId, 'options.keyId');
assert.optionalArrayOfString(options.headers, 'options.headers');
assert.optionalString(options.httpVersion, 'options.httpVersion');
if (!request.getHeader('Date'))
request.setHeader('Date', jsprim.rfc1123(new Date()));
if (!options.headers)
options.headers = ['date'];
if (!options.httpVersion)
options.httpVersion = '1.1';
var alg = [];
if (options.algorithm) {
options.algorithm = options.algorithm.toLowerCase();
alg = validateAlgorithm(options.algorithm);
}
var i;
var stringToSign = '';
for (i = 0; i < options.headers.length; i++) {
if (typeof (options.headers[i]) !== 'string')
throw new TypeError('options.headers must be an array of Strings');
var h = options.headers[i].toLowerCase();
if (h === 'request-line') {
if (!options.strict) {
/**
* We allow headers from the older spec drafts if strict parsing isn't
* specified in options.
*/
stringToSign +=
request.method + ' ' + request.path + ' HTTP/' +
options.httpVersion;
} else {
/* Strict parsing doesn't allow older draft headers. */
throw (new StrictParsingError('request-line is not a valid header ' +
'with strict parsing enabled.'));
}
} else if (h === '(request-target)') {
stringToSign +=
'(request-target): ' + request.method.toLowerCase() + ' ' +
request.path;
} else {
var value = request.getHeader(h);
if (value === undefined || value === '') {
throw new MissingHeaderError(h + ' was not in the request');
}
stringToSign += h + ': ' + value;
}
if ((i + 1) < options.headers.length)
stringToSign += '\n';
}
/* This is just for unit tests. */
if (request.hasOwnProperty('_stringToSign')) {
request._stringToSign = stringToSign;
}
var signature;
if (alg[0] === 'hmac') {
if (typeof (options.key) !== 'string' && !Buffer.isBuffer(options.key))
throw (new TypeError('options.key must be a string or Buffer'));
var hmac = crypto.createHmac(alg[1].toUpperCase(), options.key);
hmac.update(stringToSign);
signature = hmac.digest('base64');
} else {
var key = options.key;
if (typeof (key) === 'string' || Buffer.isBuffer(key))
key = sshpk.parsePrivateKey(options.key);
assert.ok(sshpk.PrivateKey.isPrivateKey(key, [1, 2]),
'options.key must be a sshpk.PrivateKey');
if (!PK_ALGOS[key.type]) {
throw (new InvalidAlgorithmError(key.type.toUpperCase() + ' type ' +
'keys are not supported'));
}
if (alg[0] !== undefined && key.type !== alg[0]) {
throw (new InvalidAlgorithmError('options.key must be a ' +
alg[0].toUpperCase() + ' key, was given a ' +
key.type.toUpperCase() + ' key instead'));
}
var signer = key.createSign(alg[1]);
signer.update(stringToSign);
var sigObj = signer.sign();
if (!HASH_ALGOS[sigObj.hashAlgorithm]) {
throw (new InvalidAlgorithmError(sigObj.hashAlgorithm.toUpperCase() +
' is not a supported hash algorithm'));
}
options.algorithm = key.type + '-' + sigObj.hashAlgorithm;
signature = sigObj.toString();
assert.notStrictEqual(signature, '', 'empty signature produced');
}
request.setHeader('Authorization', sprintf(AUTHZ_FMT,
options.keyId,
options.algorithm,
options.headers.join(' '),
signature));
return true;
}
};

View File

@@ -0,0 +1,112 @@
// Copyright 2012 Joyent, Inc. All rights reserved.
var assert = require('assert-plus');
var sshpk = require('sshpk');
var util = require('util');
var HASH_ALGOS = {
'sha1': true,
'sha256': true,
'sha512': true
};
var PK_ALGOS = {
'rsa': true,
'dsa': true,
'ecdsa': true
};
function HttpSignatureError(message, caller) {
if (Error.captureStackTrace)
Error.captureStackTrace(this, caller || HttpSignatureError);
this.message = message;
this.name = caller.name;
}
util.inherits(HttpSignatureError, Error);
function InvalidAlgorithmError(message) {
HttpSignatureError.call(this, message, InvalidAlgorithmError);
}
util.inherits(InvalidAlgorithmError, HttpSignatureError);
function validateAlgorithm(algorithm) {
var alg = algorithm.toLowerCase().split('-');
if (alg.length !== 2) {
throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' is not a ' +
'valid algorithm'));
}
if (alg[0] !== 'hmac' && !PK_ALGOS[alg[0]]) {
throw (new InvalidAlgorithmError(alg[0].toUpperCase() + ' type keys ' +
'are not supported'));
}
if (!HASH_ALGOS[alg[1]]) {
throw (new InvalidAlgorithmError(alg[1].toUpperCase() + ' is not a ' +
'supported hash algorithm'));
}
return (alg);
}
///--- API
module.exports = {
HASH_ALGOS: HASH_ALGOS,
PK_ALGOS: PK_ALGOS,
HttpSignatureError: HttpSignatureError,
InvalidAlgorithmError: InvalidAlgorithmError,
validateAlgorithm: validateAlgorithm,
/**
* Converts an OpenSSH public key (rsa only) to a PKCS#8 PEM file.
*
* The intent of this module is to interoperate with OpenSSL only,
* specifically the node crypto module's `verify` method.
*
* @param {String} key an OpenSSH public key.
* @return {String} PEM encoded form of the RSA public key.
* @throws {TypeError} on bad input.
* @throws {Error} on invalid ssh key formatted data.
*/
sshKeyToPEM: function sshKeyToPEM(key) {
assert.string(key, 'ssh_key');
var k = sshpk.parseKey(key, 'ssh');
return (k.toString('pem'));
},
/**
* Generates an OpenSSH fingerprint from an ssh public key.
*
* @param {String} key an OpenSSH public key.
* @return {String} key fingerprint.
* @throws {TypeError} on bad input.
* @throws {Error} if what you passed doesn't look like an ssh public key.
*/
fingerprint: function fingerprint(key) {
assert.string(key, 'ssh_key');
var k = sshpk.parseKey(key, 'ssh');
return (k.fingerprint('md5').toString('hex'));
},
/**
* Converts a PKGCS#8 PEM file to an OpenSSH public key (rsa)
*
* The reverse of the above function.
*/
pemToRsaSSHKey: function pemToRsaSSHKey(pem, comment) {
assert.equal('string', typeof (pem), 'typeof pem');
var k = sshpk.parseKey(pem, 'pem');
k.comment = comment;
return (k.toString('ssh'));
}
};

View File

@@ -0,0 +1,88 @@
// Copyright 2015 Joyent, Inc.
var assert = require('assert-plus');
var crypto = require('crypto');
var sshpk = require('sshpk');
var utils = require('./utils');
var HASH_ALGOS = utils.HASH_ALGOS;
var PK_ALGOS = utils.PK_ALGOS;
var InvalidAlgorithmError = utils.InvalidAlgorithmError;
var HttpSignatureError = utils.HttpSignatureError;
var validateAlgorithm = utils.validateAlgorithm;
///--- Exported API
module.exports = {
/**
* Verify RSA/DSA signature against public key. You are expected to pass in
* an object that was returned from `parse()`.
*
* @param {Object} parsedSignature the object you got from `parse`.
* @param {String} pubkey RSA/DSA private key PEM.
* @return {Boolean} true if valid, false otherwise.
* @throws {TypeError} if you pass in bad arguments.
* @throws {InvalidAlgorithmError}
*/
verifySignature: function verifySignature(parsedSignature, pubkey) {
assert.object(parsedSignature, 'parsedSignature');
if (typeof (pubkey) === 'string' || Buffer.isBuffer(pubkey))
pubkey = sshpk.parseKey(pubkey);
assert.ok(sshpk.Key.isKey(pubkey, [1, 1]), 'pubkey must be a sshpk.Key');
var alg = validateAlgorithm(parsedSignature.algorithm);
if (alg[0] === 'hmac' || alg[0] !== pubkey.type)
return (false);
var v = pubkey.createVerify(alg[1]);
v.update(parsedSignature.signingString);
return (v.verify(parsedSignature.params.signature, 'base64'));
},
/**
* Verify HMAC against shared secret. You are expected to pass in an object
* that was returned from `parse()`.
*
* @param {Object} parsedSignature the object you got from `parse`.
* @param {String} secret HMAC shared secret.
* @return {Boolean} true if valid, false otherwise.
* @throws {TypeError} if you pass in bad arguments.
* @throws {InvalidAlgorithmError}
*/
verifyHMAC: function verifyHMAC(parsedSignature, secret) {
assert.object(parsedSignature, 'parsedHMAC');
assert.string(secret, 'secret');
var alg = validateAlgorithm(parsedSignature.algorithm);
if (alg[0] !== 'hmac')
return (false);
var hashAlg = alg[1].toUpperCase();
var hmac = crypto.createHmac(hashAlg, secret);
hmac.update(parsedSignature.signingString);
/*
* Now double-hash to avoid leaking timing information - there's
* no easy constant-time compare in JS, so we use this approach
* instead. See for more info:
* https://www.isecpartners.com/blog/2011/february/double-hmac-
* verification.aspx
*/
var h1 = crypto.createHmac(hashAlg, secret);
h1.update(hmac.digest());
h1 = h1.digest();
var h2 = crypto.createHmac(hashAlg, secret);
h2.update(new Buffer(parsedSignature.params.signature, 'base64'));
h2 = h2.digest();
/* Node 0.8 returns strings from .digest(). */
if (typeof (h1) === 'string')
return (h1 === h2);
/* And node 0.10 lacks the .equals() method on Buffers. */
if (Buffer.isBuffer(h1) && !h1.equals)
return (h1.toString('binary') === h2.toString('binary'));
return (h1.equals(h2));
}
};

View File

@@ -0,0 +1,122 @@
{
"_args": [
[
{
"name": "http-signature",
"raw": "http-signature@~1.1.0",
"rawSpec": "~1.1.0",
"scope": null,
"spec": ">=1.1.0 <1.2.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "http-signature@>=1.1.0 <1.2.0",
"_id": "http-signature@1.1.1",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/http-signature",
"_nodeVersion": "0.12.9",
"_npmUser": {
"email": "alex@cooperi.net",
"name": "arekinath"
},
"_npmVersion": "2.14.9",
"_phantomChildren": {},
"_requested": {
"name": "http-signature",
"raw": "http-signature@~1.1.0",
"rawSpec": "~1.1.0",
"scope": null,
"spec": ">=1.1.0 <1.2.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"_shasum": "df72e267066cd0ac67fb76adf8e134a8fbcf91bf",
"_shrinkwrap": null,
"_spec": "http-signature@~1.1.0",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"name": "Joyent, Inc"
},
"bugs": {
"url": "https://github.com/joyent/node-http-signature/issues"
},
"contributors": [
{
"email": "mcavage@gmail.com",
"name": "Mark Cavage"
},
{
"email": "dil@lehn.org",
"name": "David I. Lehn"
},
{
"email": "patrick.f.mooney@gmail.com",
"name": "Patrick Mooney"
}
],
"dependencies": {
"assert-plus": "^0.2.0",
"jsprim": "^1.2.2",
"sshpk": "^1.7.0"
},
"description": "Reference implementation of Joyent's HTTP Signature scheme.",
"devDependencies": {
"node-uuid": "^1.4.1",
"tap": "0.4.2"
},
"directories": {},
"dist": {
"integrity": "sha512-iUn0NcRULlDGtqNLN1Jxmzayk8ogm7NToldASyZBpM2qggbphjXzNOiw3piN8tgz+e/DRs6X5gAzFwTI6BCRcg==",
"shasum": "df72e267066cd0ac67fb76adf8e134a8fbcf91bf",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIH75FKkCIl2mNVioRBiIGBx3zu9bVFOYrWwffyK9qK7xAiEAuAh0SAJl7L2LRGqO7Aaql33ezVVeqWkVTudkHQyJJ80="
}
],
"tarball": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz"
},
"engines": {
"node": ">=0.8",
"npm": ">=1.3.7"
},
"gitHead": "74d3f35e3aa436d83723c53b01e266f448e8149a",
"homepage": "https://github.com/joyent/node-http-signature/",
"keywords": [
"https",
"request"
],
"license": "MIT",
"main": "lib/index.js",
"maintainers": [
{
"email": "alex@cooperi.net",
"name": "arekinath"
},
{
"email": "mcavage@gmail.com",
"name": "mcavage"
},
{
"email": "patrick.f.mooney@gmail.com",
"name": "pfmooney"
}
],
"name": "http-signature",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/joyent/node-http-signature.git"
},
"scripts": {
"test": "tap test/*.js"
},
"version": "1.1.1"
}

View File

@@ -0,0 +1,4 @@
node_modules
.DS_Store
.nyc_output
coverage

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2010-2012 Robert Kieffer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,8 @@
# node-uuid
DEPRECATED: Use the `uuid` package instead. See
* On NPM: https://www.npmjs.com/package/uuid
* On Github: https://github.com/kelektiv/node-uuid
(Yes, the github project is still called "node-uuid". We merged the two projects. Sorry for the confusion.)

View File

@@ -0,0 +1,53 @@
# node-uuid Benchmarks
### Results
To see the results of our benchmarks visit https://github.com/broofa/node-uuid/wiki/Benchmark
### Run them yourself
node-uuid comes with some benchmarks to measure performance of generating UUIDs. These can be run using node.js. node-uuid is being benchmarked against some other uuid modules, that are available through npm namely `uuid` and `uuid-js`.
To prepare and run the benchmark issue;
```
npm install uuid uuid-js
node benchmark/benchmark.js
```
You'll see an output like this one:
```
# v4
nodeuuid.v4(): 854700 uuids/second
nodeuuid.v4('binary'): 788643 uuids/second
nodeuuid.v4('binary', buffer): 1336898 uuids/second
uuid(): 479386 uuids/second
uuid('binary'): 582072 uuids/second
uuidjs.create(4): 312304 uuids/second
# v1
nodeuuid.v1(): 938086 uuids/second
nodeuuid.v1('binary'): 683060 uuids/second
nodeuuid.v1('binary', buffer): 1644736 uuids/second
uuidjs.create(1): 190621 uuids/second
```
* The `uuid()` entries are for Nikhil Marathe's [uuid module](https://bitbucket.org/nikhilm/uuidjs) which is a wrapper around the native libuuid library.
* The `uuidjs()` entries are for Patrick Negri's [uuid-js module](https://github.com/pnegri/uuid-js) which is a pure javascript implementation based on [UUID.js](https://github.com/LiosK/UUID.js) by LiosK.
If you want to get more reliable results you can run the benchmark multiple times and write the output into a log file:
```
for i in {0..9}; do node benchmark/benchmark.js >> benchmark/bench_0.4.12.log; done;
```
If you're interested in how performance varies between different node versions, you can issue the above command multiple times.
You can then use the shell script `bench.sh` provided in this directory to calculate the averages over all benchmark runs and draw a nice plot:
```
(cd benchmark/ && ./bench.sh)
```
This assumes you have [gnuplot](http://www.gnuplot.info/) and [ImageMagick](http://www.imagemagick.org/) installed. You'll find a nice `bench.png` graph in the `benchmark/` directory then.

View File

@@ -0,0 +1,174 @@
#!/opt/local/bin/gnuplot -persist
#
#
# G N U P L O T
# Version 4.4 patchlevel 3
# last modified March 2011
# System: Darwin 10.8.0
#
# Copyright (C) 1986-1993, 1998, 2004, 2007-2010
# Thomas Williams, Colin Kelley and many others
#
# gnuplot home: http://www.gnuplot.info
# faq, bugs, etc: type "help seeking-assistance"
# immediate help: type "help"
# plot window: hit 'h'
set terminal postscript eps noenhanced defaultplex \
leveldefault color colortext \
solid linewidth 1.2 butt noclip \
palfuncparam 2000,0.003 \
"Helvetica" 14
set output 'bench.eps'
unset clip points
set clip one
unset clip two
set bar 1.000000 front
set border 31 front linetype -1 linewidth 1.000
set xdata
set ydata
set zdata
set x2data
set y2data
set timefmt x "%d/%m/%y,%H:%M"
set timefmt y "%d/%m/%y,%H:%M"
set timefmt z "%d/%m/%y,%H:%M"
set timefmt x2 "%d/%m/%y,%H:%M"
set timefmt y2 "%d/%m/%y,%H:%M"
set timefmt cb "%d/%m/%y,%H:%M"
set boxwidth
set style fill empty border
set style rectangle back fc lt -3 fillstyle solid 1.00 border lt -1
set style circle radius graph 0.02, first 0, 0
set dummy x,y
set format x "% g"
set format y "% g"
set format x2 "% g"
set format y2 "% g"
set format z "% g"
set format cb "% g"
set angles radians
unset grid
set key title ""
set key outside left top horizontal Right noreverse enhanced autotitles columnhead nobox
set key noinvert samplen 4 spacing 1 width 0 height 0
set key maxcolumns 2 maxrows 0
unset label
unset arrow
set style increment default
unset style line
set style line 1 linetype 1 linewidth 2.000 pointtype 1 pointsize default pointinterval 0
unset style arrow
set style histogram clustered gap 2 title offset character 0, 0, 0
unset logscale
set offsets graph 0.05, 0.15, 0, 0
set pointsize 1.5
set pointintervalbox 1
set encoding default
unset polar
unset parametric
unset decimalsign
set view 60, 30, 1, 1
set samples 100, 100
set isosamples 10, 10
set surface
unset contour
set clabel '%8.3g'
set mapping cartesian
set datafile separator whitespace
unset hidden3d
set cntrparam order 4
set cntrparam linear
set cntrparam levels auto 5
set cntrparam points 5
set size ratio 0 1,1
set origin 0,0
set style data points
set style function lines
set xzeroaxis linetype -2 linewidth 1.000
set yzeroaxis linetype -2 linewidth 1.000
set zzeroaxis linetype -2 linewidth 1.000
set x2zeroaxis linetype -2 linewidth 1.000
set y2zeroaxis linetype -2 linewidth 1.000
set ticslevel 0.5
set mxtics default
set mytics default
set mztics default
set mx2tics default
set my2tics default
set mcbtics default
set xtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set xtics norangelimit
set xtics ()
set ytics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set ytics autofreq norangelimit
set ztics border in scale 1,0.5 nomirror norotate offset character 0, 0, 0
set ztics autofreq norangelimit
set nox2tics
set noy2tics
set cbtics border in scale 1,0.5 mirror norotate offset character 0, 0, 0
set cbtics autofreq norangelimit
set title ""
set title offset character 0, 0, 0 font "" norotate
set timestamp bottom
set timestamp ""
set timestamp offset character 0, 0, 0 font "" norotate
set rrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] )
set autoscale rfixmin
set autoscale rfixmax
set trange [ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000] )
set autoscale tfixmin
set autoscale tfixmax
set urange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale ufixmin
set autoscale ufixmax
set vrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale vfixmin
set autoscale vfixmax
set xlabel ""
set xlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate
set x2label ""
set x2label offset character 0, 0, 0 font "" textcolor lt -1 norotate
set xrange [ * : * ] noreverse nowriteback # (currently [-0.150000:3.15000] )
set autoscale xfixmin
set autoscale xfixmax
set x2range [ * : * ] noreverse nowriteback # (currently [0.00000:3.00000] )
set autoscale x2fixmin
set autoscale x2fixmax
set ylabel ""
set ylabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set y2label ""
set y2label offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set yrange [ 0.00000 : 1.90000e+06 ] noreverse nowriteback # (currently [:] )
set autoscale yfixmin
set autoscale yfixmax
set y2range [ * : * ] noreverse nowriteback # (currently [0.00000:1.90000e+06] )
set autoscale y2fixmin
set autoscale y2fixmax
set zlabel ""
set zlabel offset character 0, 0, 0 font "" textcolor lt -1 norotate
set zrange [ * : * ] noreverse nowriteback # (currently [-10.0000:10.0000] )
set autoscale zfixmin
set autoscale zfixmax
set cblabel ""
set cblabel offset character 0, 0, 0 font "" textcolor lt -1 rotate by -270
set cbrange [ * : * ] noreverse nowriteback # (currently [8.98847e+307:-8.98847e+307] )
set autoscale cbfixmin
set autoscale cbfixmax
set zero 1e-08
set lmargin -1
set bmargin -1
set rmargin -1
set tmargin -1
set pm3d explicit at s
set pm3d scansautomatic
set pm3d interpolate 1,1 flush begin noftriangles nohidden3d corners2color mean
set palette positive nops_allcF maxcolors 0 gamma 1.5 color model RGB
set palette rgbformulae 7, 5, 15
set colorbox default
set colorbox vertical origin screen 0.9, 0.2, 0 size screen 0.05, 0.6, 0 front bdefault
set loadpath
set fontpath
set fit noerrorvariables
GNUTERM = "aqua"
plot 'bench_results.txt' using 2:xticlabel(1) w lp lw 2, '' using 3:xticlabel(1) w lp lw 2, '' using 4:xticlabel(1) w lp lw 2, '' using 5:xticlabel(1) w lp lw 2, '' using 6:xticlabel(1) w lp lw 2, '' using 7:xticlabel(1) w lp lw 2, '' using 8:xticlabel(1) w lp lw 2, '' using 9:xticlabel(1) w lp lw 2
# EOF

View File

@@ -0,0 +1,34 @@
#!/bin/bash
# for a given node version run:
# for i in {0..9}; do node benchmark.js >> bench_0.6.2.log; done;
PATTERNS=('nodeuuid.v1()' "nodeuuid.v1('binary'," 'nodeuuid.v4()' "nodeuuid.v4('binary'," "uuid()" "uuid('binary')" 'uuidjs.create(1)' 'uuidjs.create(4)' '140byte')
FILES=(node_uuid_v1_string node_uuid_v1_buf node_uuid_v4_string node_uuid_v4_buf libuuid_v4_string libuuid_v4_binary uuidjs_v1_string uuidjs_v4_string 140byte_es)
INDICES=(2 3 2 3 2 2 2 2 2)
VERSIONS=$( ls bench_*.log | sed -e 's/^bench_\([0-9\.]*\)\.log/\1/' | tr "\\n" " " )
TMPJOIN="tmp_join"
OUTPUT="bench_results.txt"
for I in ${!FILES[*]}; do
F=${FILES[$I]}
P=${PATTERNS[$I]}
INDEX=${INDICES[$I]}
echo "version $F" > $F
for V in $VERSIONS; do
(VAL=$( grep "$P" bench_$V.log | LC_ALL=en_US awk '{ sum += $'$INDEX' } END { print sum/NR }' ); echo $V $VAL) >> $F
done
if [ $I == 0 ]; then
cat $F > $TMPJOIN
else
join $TMPJOIN $F > $OUTPUT
cp $OUTPUT $TMPJOIN
fi
rm $F
done
rm $TMPJOIN
gnuplot bench.gnu
convert -density 200 -resize 800x560 -flatten bench.eps bench.png
rm bench.eps

View File

@@ -0,0 +1,34 @@
/*
Test performance of native C UUID generation
To Compile: cc -luuid benchmark-native.c -o benchmark-native
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <uuid/uuid.h>
int main() {
uuid_t myid;
char buf[36+1];
int i;
struct timeval t;
double start, finish;
gettimeofday(&t, NULL);
start = t.tv_sec + t.tv_usec/1e6;
int n = 2e5;
for (i = 0; i < n; i++) {
uuid_generate(myid);
uuid_unparse(myid, buf);
}
gettimeofday(&t, NULL);
finish = t.tv_sec + t.tv_usec/1e6;
double dur = finish - start;
printf("%d uuids/sec", (int)(n/dur));
return 0;
}

View File

@@ -0,0 +1,84 @@
try {
var nodeuuid = require('../uuid');
} catch (e) {
console.error('node-uuid require failed - skipping tests');
}
try {
var uuid = require('uuid');
} catch (e) {
console.error('uuid require failed - skipping tests');
}
try {
var uuidjs = require('uuid-js');
} catch (e) {
console.error('uuid-js require failed - skipping tests');
}
var N = 5e5;
function rate(msg, t) {
console.log(msg + ': ' +
(N / (Date.now() - t) * 1e3 | 0) +
' uuids/second');
}
console.log('# v4');
// node-uuid - string form
if (nodeuuid) {
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4();
rate('nodeuuid.v4() - using node.js crypto RNG', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4({rng: nodeuuid.mathRNG});
rate('nodeuuid.v4() - using Math.random() RNG', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary');
rate('nodeuuid.v4(\'binary\')', t);
var buffer = new nodeuuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v4('binary', buffer);
rate('nodeuuid.v4(\'binary\', buffer)', t);
}
// libuuid - string form
if (uuid) {
for (var i = 0, t = Date.now(); i < N; i++) uuid();
rate('uuid()', t);
for (var i = 0, t = Date.now(); i < N; i++) uuid('binary');
rate('uuid(\'binary\')', t);
}
// uuid-js - string form
if (uuidjs) {
for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(4);
rate('uuidjs.create(4)', t);
}
// 140byte.es
for (var i = 0, t = Date.now(); i < N; i++) 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,function(s,r){r=Math.random()*16|0;return (s=='x'?r:r&0x3|0x8).toString(16)});
rate('140byte.es_v4', t);
console.log('');
console.log('# v1');
// node-uuid - v1 string form
if (nodeuuid) {
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1();
rate('nodeuuid.v1()', t);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary');
rate('nodeuuid.v1(\'binary\')', t);
var buffer = new nodeuuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) nodeuuid.v1('binary', buffer);
rate('nodeuuid.v1(\'binary\', buffer)', t);
}
// uuid-js - v1 string form
if (uuidjs) {
for (var i = 0, t = Date.now(); i < N; i++) uuidjs.create(1);
rate('uuidjs.create(1)', t);
}

26
node_modules/phantomjs/node_modules/node-uuid/bin/uuid generated vendored Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env node
var path = require('path');
var uuid = require(path.join(__dirname, '..'));
var arg = process.argv[2];
if ('--help' === arg) {
console.log('\n USAGE: uuid [version] [options]\n\n');
console.log(' options:\n');
console.log(' --help Display this message and exit\n');
process.exit(0);
}
if (null == arg) {
console.log(uuid());
process.exit(0);
}
if ('v1' !== arg && 'v4' !== arg) {
console.error('Version must be RFC4122 version 1 or version 4, denoted as "v1" or "v4"');
process.exit(1);
}
console.log(uuid[arg]());
process.exit(0);

View File

@@ -0,0 +1,23 @@
{
"name": "node-uuid",
"version": "1.4.7",
"homepage": "https://github.com/broofa/node-uuid",
"authors": [
"Robert Kieffer <robert@broofa.com>"
],
"description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
"main": "uuid.js",
"keywords": [
"uuid",
"gid",
"rfc4122"
],
"license": "MIT",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

View File

@@ -0,0 +1,25 @@
{
"name": "node-uuid",
"repo": "broofa/node-uuid",
"description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
"version": "1.4.7",
"author": "Robert Kieffer <robert@broofa.com>",
"contributors": [
{
"name": "Christoph Tavan <dev@tavan.de>",
"github": "https://github.com/ctavan"
}
],
"keywords": [
"uuid",
"guid",
"rfc4122"
],
"dependencies": {},
"development": {},
"main": "uuid.js",
"scripts": [
"uuid.js"
],
"license": "MIT"
}

View File

@@ -0,0 +1,120 @@
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* SHA-1 (FIPS 180-4) implementation in JavaScript (c) Chris Veness 2002-2016 */
/* MIT Licence */
/* www.movable-type.co.uk/scripts/sha1.html */
/* */
/* - see http://csrc.nist.gov/groups/ST/toolkit/secure_hashing.html */
/* http://csrc.nist.gov/groups/ST/toolkit/examples.html */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
'use strict';
function f(s, x, y, z) {
switch (s) {
case 0: return (x & y) ^ (~x & z); // Ch()
case 1: return x ^ y ^ z; // Parity()
case 2: return (x & y) ^ (x & z) ^ (y & z); // Maj()
case 3: return x ^ y ^ z; // Parity()
}
}
function ROTL(x, n) {
return (x<<n) | (x>>>(32-n));
}
var Sha1 = {};
Sha1.hash = function(msg, options) {
var defaults = { msgFormat: 'string', outFormat: 'hex' };
var opt = Object.assign(defaults, options);
switch (opt.msgFormat) {
default: // default is to convert string to UTF-8, as SHA only deals with byte-streams
case 'string': msg = Sha1.utf8Encode(msg); break;
case 'hex-bytes':msg = Sha1.hexBytesToString(msg); break; // mostly for running tests
}
// constants [<5B>4.2.1]
var K = [ 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 ];
// initial hash value [<5B>5.3.1]
var H = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
// PREPROCESSING [<5B>6.1.1]
msg += String.fromCharCode(0x80); // add trailing '1' bit (+ 0's padding) to string [<5B>5.1.1]
// convert string msg into 512-bit/16-integer blocks arrays of ints [<5B>5.2.1]
var l = msg.length/4 + 2; // length (in 32-bit integers) of msg + <20>1<EFBFBD> + appended length
var N = Math.ceil(l/16); // number of 16-integer-blocks required to hold 'l' ints
var M = new Array(N);
for (var i=0; i<N; i++) {
M[i] = new Array(16);
for (var j=0; j<16; j++) { // encode 4 chars per integer, big-endian encoding
M[i][j] = (msg.charCodeAt(i*64+j*4)<<24) | (msg.charCodeAt(i*64+j*4+1)<<16) |
(msg.charCodeAt(i*64+j*4+2)<<8) | (msg.charCodeAt(i*64+j*4+3));
} // note running off the end of msg is ok 'cos bitwise ops on NaN return 0
}
// add length (in bits) into final pair of 32-bit integers (big-endian) [<5B>5.1.1]
// note: most significant word would be (len-1)*8 >>> 32, but since JS converts
// bitwise-op args to 32 bits, we need to simulate this by arithmetic operators
M[N-1][14] = ((msg.length-1)*8) / Math.pow(2, 32); M[N-1][14] = Math.floor(M[N-1][14]);
M[N-1][15] = ((msg.length-1)*8) & 0xffffffff;
// HASH COMPUTATION [<5B>6.1.2]
for (var i=0; i<N; i++) {
var W = new Array(80);
// 1 - prepare message schedule 'W'
for (var t=0; t<16; t++) W[t] = M[i][t];
for (var t=16; t<80; t++) W[t] = ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
// 2 - initialise five working variables a, b, c, d, e with previous hash value
var a = H[0], b = H[1], c = H[2], d = H[3], e = H[4];
// 3 - main loop (use JavaScript '>>> 0' to emulate UInt32 variables)
for (var t=0; t<80; t++) {
var s = Math.floor(t/20); // seq for blocks of 'f' functions and 'K' constants
var T = (ROTL(a,5) + f(s,b,c,d) + e + K[s] + W[t]) >>> 0;
e = d;
d = c;
c = ROTL(b, 30) >>> 0;
b = a;
a = T;
}
// 4 - compute the new intermediate hash value (note 'addition modulo 2^32' <20> JavaScript
// '>>> 0' coerces to unsigned UInt32 which achieves modulo 2^32 addition)
H[0] = (H[0]+a) >>> 0;
H[1] = (H[1]+b) >>> 0;
H[2] = (H[2]+c) >>> 0;
H[3] = (H[3]+d) >>> 0;
H[4] = (H[4]+e) >>> 0;
}
// convert H0..H4 to hex strings (with leading zeros)
for (var h=0; h<H.length; h++) H[h] = ('00000000'+H[h].toString(16)).slice(-8);
// concatenate H0..H4, with separator if required
var separator = opt.outFormat=='hex-w' ? ' ' : '';
return H.join(separator);
};
Sha1.utf8Encode = function(str) {
return unescape(encodeURIComponent(str));
};
Sha1.hexBytesToString = function(hexStr) {
hexStr = hexStr.replace(' ', ''); // allow space-separated groups
var str = '';
for (var i=0; i<hexStr.length; i+=2) {
str += String.fromCharCode(parseInt(hexStr.slice(i, i+2), 16));
}
return str;
};
module.exports = Sha1; // CommonJs export

View File

@@ -0,0 +1,124 @@
{
"_args": [
[
{
"name": "node-uuid",
"raw": "node-uuid@~1.4.7",
"rawSpec": "~1.4.7",
"scope": null,
"spec": ">=1.4.7 <1.5.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "node-uuid@>=1.4.7 <1.5.0",
"_id": "node-uuid@1.4.8",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/node-uuid",
"_nodeVersion": "6.9.2",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/node-uuid-1.4.8.tgz_1490142638297_0.6400028455536813"
},
"_npmUser": {
"email": "robert@broofa.com",
"name": "broofa"
},
"_npmVersion": "4.3.0",
"_phantomChildren": {},
"_requested": {
"name": "node-uuid",
"raw": "node-uuid@~1.4.7",
"rawSpec": "~1.4.7",
"scope": null,
"spec": ">=1.4.7 <1.5.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz",
"_shasum": "b040eb0923968afabf8d32fb1f17f1167fdab907",
"_shrinkwrap": null,
"_spec": "node-uuid@~1.4.7",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "robert@broofa.com",
"name": "Robert Kieffer"
},
"bin": {
"uuid": "./bin/uuid"
},
"bugs": {
"url": "https://github.com/broofa/node-uuid/issues"
},
"contributors": [
{
"email": "coolaj86@gmail.com",
"name": "AJ ONeal"
},
{
"email": "dev@tavan.de",
"name": "Christoph Tavan"
}
],
"dependencies": {},
"deprecated": "Use uuid module instead",
"description": "Rigorous implementation of RFC4122 (v1 and v4) UUIDs.",
"devDependencies": {
"nyc": "^2.2.0"
},
"directories": {},
"dist": {
"integrity": "sha512-TkCET/3rr9mUuRp+CpO7qfgT++aAxfDRaalQhwPFzI9BY/2rCDn6OfpZOVggi1AXfTPpfkTrg5f5WQx5G1uLxA==",
"shasum": "b040eb0923968afabf8d32fb1f17f1167fdab907",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEUCIDJ4OKowqe2yOxdFIdAn9XKMnGob6+bmUQsLP6e53Wk1AiEArvbdXS3PSZVoi9+OUq/37gJxp4+idqCNcf2t2F8exqk="
}
],
"tarball": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz"
},
"gitHead": "6f0f31b997cd6bec7919223e8897454350ed820f",
"homepage": "https://github.com/broofa/node-uuid",
"installable": true,
"keywords": [
"guid",
"rfc4122",
"uuid"
],
"lib": ".",
"licenses": [
{
"type": "MIT",
"url": "https://raw.github.com/broofa/node-uuid/master/LICENSE.md"
}
],
"main": "./uuid.js",
"maintainers": [
{
"email": "robert@broofa.com",
"name": "broofa"
},
{
"email": "shtylman@gmail.com",
"name": "defunctzombie"
}
],
"name": "node-uuid",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/broofa/node-uuid.git"
},
"scripts": {
"coverage": "nyc npm test && nyc report",
"test": "node test/test.js"
},
"url": "http://github.com/broofa/node-uuid",
"version": "1.4.8"
}

View File

@@ -0,0 +1,63 @@
var assert = require('assert'),
nodeuuid = require('../uuid'),
uuidjs = require('uuid-js'),
libuuid = require('uuid').generate,
util = require('util'),
exec = require('child_process').exec,
os = require('os');
// On Mac Os X / macports there's only the ossp-uuid package that provides uuid
// On Linux there's uuid-runtime which provides uuidgen
var uuidCmd = os.type() === 'Darwin' ? 'uuid -1' : 'uuidgen -t';
function compare(ids) {
console.log(ids);
for (var i = 0; i < ids.length; i++) {
var id = ids[i].split('-');
id = [id[2], id[1], id[0]].join('');
ids[i] = id;
}
var sorted = ([].concat(ids)).sort();
if (sorted.toString() !== ids.toString()) {
console.log('Warning: sorted !== ids');
} else {
console.log('everything in order!');
}
}
// Test time order of v1 uuids
var ids = [];
while (ids.length < 10e3) ids.push(nodeuuid.v1());
var max = 10;
console.log('node-uuid:');
ids = [];
for (var i = 0; i < max; i++) ids.push(nodeuuid.v1());
compare(ids);
console.log('');
console.log('uuidjs:');
ids = [];
for (var i = 0; i < max; i++) ids.push(uuidjs.create(1).toString());
compare(ids);
console.log('');
console.log('libuuid:');
ids = [];
var count = 0;
var last = function() {
compare(ids);
}
var cb = function(err, stdout, stderr) {
ids.push(stdout.substring(0, stdout.length-1));
count++;
if (count < max) {
return next();
}
last();
};
var next = function() {
exec(uuidCmd, cb);
};
next();

View File

@@ -0,0 +1,17 @@
<html>
<head>
<style>
div {
font-family: monospace;
font-size: 8pt;
}
div.log {color: #444;}
div.warn {color: #550;}
div.error {color: #800; font-weight: bold;}
</style>
<script src="../uuid.js"></script>
</head>
<body>
<script src="./test.js"></script>
</body>
</html>

View File

@@ -0,0 +1,231 @@
if (!this.uuid) {
// node.js
uuid = require('../uuid');
if (!/_rb/.test(uuid._rng.toString())) {
throw new Error("should use crypto for node.js");
}
}
//
// x-platform log/assert shims
//
function _log(msg, type) {
type = type || 'log';
if (typeof(document) != 'undefined') {
document.write('<div class="' + type + '">' + msg.replace(/\n/g, '<br />') + '</div>');
}
if (typeof(console) != 'undefined') {
var color = {
log: '\033[39m',
warn: '\033[33m',
error: '\033[31m'
};
console[type](color[type] + msg + color.log);
}
}
function log(msg) {_log(msg, 'log');}
function warn(msg) {_log(msg, 'warn');}
function error(msg) {_log(msg, 'error');}
function assert(res, msg) {
if (!res) {
error('FAIL: ' + msg);
} else {
log('Pass: ' + msg);
}
}
//
// Unit tests
//
// Verify ordering of v1 ids created with explicit times
var TIME = 1321644961388; // 2011-11-18 11:36:01.388-08:00
function compare(name, ids) {
ids = ids.map(function(id) {
return id.split('-').reverse().join('-');
}).sort();
var sorted = ([].concat(ids)).sort();
assert(sorted.toString() == ids.toString(), name + ' have expected order');
}
// Verify ordering of v1 ids created using default behavior
compare('uuids with current time', [
uuid.v1(),
uuid.v1(),
uuid.v1(),
uuid.v1(),
uuid.v1()
]);
// Verify ordering of v1 ids created with explicit times
compare('uuids with time option', [
uuid.v1({msecs: TIME - 10*3600*1000}),
uuid.v1({msecs: TIME - 1}),
uuid.v1({msecs: TIME}),
uuid.v1({msecs: TIME + 1}),
uuid.v1({msecs: TIME + 28*24*3600*1000})
]);
assert(
uuid.v1({msecs: TIME}) != uuid.v1({msecs: TIME}),
'IDs created at same msec are different'
);
// Verify throw if too many ids created
var thrown = false;
try {
uuid.v1({msecs: TIME, nsecs: 10000});
} catch (e) {
thrown = true;
}
assert(thrown, 'Exception thrown when > 10K ids created in 1 ms');
// Verify clock regression bumps clockseq
var uidt = uuid.v1({msecs: TIME});
var uidtb = uuid.v1({msecs: TIME - 1});
assert(
parseInt(uidtb.split('-')[3], 16) - parseInt(uidt.split('-')[3], 16) === 1,
'Clock regression by msec increments the clockseq'
);
// Verify clock regression bumps clockseq
var uidtn = uuid.v1({msecs: TIME, nsecs: 10});
var uidtnb = uuid.v1({msecs: TIME, nsecs: 9});
assert(
parseInt(uidtnb.split('-')[3], 16) - parseInt(uidtn.split('-')[3], 16) === 1,
'Clock regression by nsec increments the clockseq'
);
// Verify explicit options produce expected id
var id = uuid.v1({
msecs: 1321651533573,
nsecs: 5432,
clockseq: 0x385c,
node: [ 0x61, 0xcd, 0x3c, 0xbb, 0x32, 0x10 ]
});
assert(id == 'd9428888-122b-11e1-b85c-61cd3cbb3210', 'Explicit options produce expected id');
// Verify adjacent ids across a msec boundary are 1 time unit apart
var u0 = uuid.v1({msecs: TIME, nsecs: 9999});
var u1 = uuid.v1({msecs: TIME + 1, nsecs: 0});
var before = u0.split('-')[0], after = u1.split('-')[0];
var dt = parseInt(after, 16) - parseInt(before, 16);
assert(dt === 1, 'Ids spanning 1ms boundary are 100ns apart');
//
// Test parse/unparse
//
id = '00112233445566778899aabbccddeeff';
assert(uuid.unparse(uuid.parse(id.substr(0,10))) ==
'00112233-4400-0000-0000-000000000000', 'Short parse');
assert(uuid.unparse(uuid.parse('(this is the uuid -> ' + id + id)) ==
'00112233-4455-6677-8899-aabbccddeeff', 'Dirty parse');
//
// Perf tests
//
var generators = {
v1: uuid.v1,
v4: uuid.v4
};
var UUID_FORMAT = {
v1: /[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i,
v4: /[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i
};
var N = 1e4;
// Get %'age an actual value differs from the ideal value
function divergence(actual, ideal) {
return Math.round(100*100*(actual - ideal)/ideal)/100;
}
function rate(msg, t) {
log(msg + ': ' + (N / (Date.now() - t) * 1e3 | 0) + ' uuids\/second');
}
for (var version in generators) {
var counts = {}, max = 0;
var generator = generators[version];
var format = UUID_FORMAT[version];
log('\nSanity check ' + N + ' ' + version + ' uuids');
for (var i = 0, ok = 0; i < N; i++) {
id = generator();
if (!format.test(id)) {
throw Error(id + ' is not a valid UUID string');
}
if (id != uuid.unparse(uuid.parse(id))) {
assert(fail, id + ' is not a valid id');
}
// Count digits for our randomness check
if (version == 'v4') {
var digits = id.replace(/-/g, '').split('');
for (var j = digits.length-1; j >= 0; j--) {
var c = digits[j];
max = Math.max(max, counts[c] = (counts[c] || 0) + 1);
}
}
}
// Check randomness for v4 UUIDs
if (version == 'v4') {
// Limit that we get worried about randomness. (Purely empirical choice, this!)
var limit = 2*100*Math.sqrt(1/N);
log('\nChecking v4 randomness. Distribution of Hex Digits (% deviation from ideal)');
for (var i = 0; i < 16; i++) {
var c = i.toString(16);
var bar = '', n = counts[c], p = Math.round(n/max*100|0);
// 1-3,5-8, and D-F: 1:16 odds over 30 digits
var ideal = N*30/16;
if (i == 4) {
// 4: 1:1 odds on 1 digit, plus 1:16 odds on 30 digits
ideal = N*(1 + 30/16);
} else if (i >= 8 && i <= 11) {
// 8-B: 1:4 odds on 1 digit, plus 1:16 odds on 30 digits
ideal = N*(1/4 + 30/16);
} else {
// Otherwise: 1:16 odds on 30 digits
ideal = N*30/16;
}
var d = divergence(n, ideal);
// Draw bar using UTF squares (just for grins)
var s = n/max*50 | 0;
while (s--) bar += '=';
assert(Math.abs(d) < limit, c + ' |' + bar + '| ' + counts[c] + ' (' + d + '% < ' + limit + '%)');
}
}
}
// Perf tests
for (var version in generators) {
log('\nPerformance testing ' + version + ' UUIDs');
var generator = generators[version];
var buf = new uuid.BufferClass(16);
for (var i = 0, t = Date.now(); i < N; i++) generator();
rate('uuid.' + version + '()', t);
for (var i = 0, t = Date.now(); i < N; i++) generator('binary');
rate('uuid.' + version + '(\'binary\')', t);
for (var i = 0, t = Date.now(); i < N; i++) generator('binary', buf);
rate('uuid.' + version + '(\'binary\', buffer)', t);
}

272
node_modules/phantomjs/node_modules/node-uuid/uuid.js generated vendored Normal file
View File

@@ -0,0 +1,272 @@
// uuid.js
//
// Copyright (c) 2010-2012 Robert Kieffer
// MIT License - http://opensource.org/licenses/mit-license.php
/*global window, require, define */
(function(_window) {
'use strict';
// Unique ID creation requires a high quality random # generator. We feature
// detect to determine the best RNG source, normalizing to a function that
// returns 128-bits of randomness, since that's what's usually required
var _rng, _mathRNG, _nodeRNG, _whatwgRNG, _previousRoot;
function setupBrowser() {
// Allow for MSIE11 msCrypto
var _crypto = _window.crypto || _window.msCrypto;
if (!_rng && _crypto && _crypto.getRandomValues) {
// WHATWG crypto-based RNG - http://wiki.whatwg.org/wiki/Crypto
//
// Moderately fast, high quality
try {
var _rnds8 = new Uint8Array(16);
_whatwgRNG = _rng = function whatwgRNG() {
_crypto.getRandomValues(_rnds8);
return _rnds8;
};
_rng();
} catch(e) {}
}
if (!_rng) {
// Math.random()-based (RNG)
//
// If all else fails, use Math.random(). It's fast, but is of unspecified
// quality.
var _rnds = new Array(16);
_mathRNG = _rng = function() {
for (var i = 0, r; i < 16; i++) {
if ((i & 0x03) === 0) { r = Math.random() * 0x100000000; }
_rnds[i] = r >>> ((i & 0x03) << 3) & 0xff;
}
return _rnds;
};
if ('undefined' !== typeof console && console.warn) {
console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()");
}
}
}
function setupNode() {
// Node.js crypto-based RNG - http://nodejs.org/docs/v0.6.2/api/crypto.html
//
// Moderately fast, high quality
if ('function' === typeof require) {
try {
var _rb = require('crypto').randomBytes;
_nodeRNG = _rng = _rb && function() {return _rb(16);};
_rng();
} catch(e) {}
}
}
if (_window) {
setupBrowser();
} else {
setupNode();
}
// Buffer class to use
var BufferClass = ('function' === typeof Buffer) ? Buffer : Array;
// Maps for number <-> hex string conversion
var _byteToHex = [];
var _hexToByte = {};
for (var i = 0; i < 256; i++) {
_byteToHex[i] = (i + 0x100).toString(16).substr(1);
_hexToByte[_byteToHex[i]] = i;
}
// **`parse()` - Parse a UUID into it's component bytes**
function parse(s, buf, offset) {
var i = (buf && offset) || 0, ii = 0;
buf = buf || [];
s.toLowerCase().replace(/[0-9a-f]{2}/g, function(oct) {
if (ii < 16) { // Don't overflow!
buf[i + ii++] = _hexToByte[oct];
}
});
// Zero out remaining bytes if string was short
while (ii < 16) {
buf[i + ii++] = 0;
}
return buf;
}
// **`unparse()` - Convert UUID byte array (ala parse()) into a string**
function unparse(buf, offset) {
var i = offset || 0, bth = _byteToHex;
return bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] + '-' +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]] +
bth[buf[i++]] + bth[buf[i++]];
}
// **`v1()` - Generate time-based UUID**
//
// Inspired by https://github.com/LiosK/UUID.js
// and http://docs.python.org/library/uuid.html
// random #'s we need to init node and clockseq
var _seedBytes = _rng();
// Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1)
var _nodeId = [
_seedBytes[0] | 0x01,
_seedBytes[1], _seedBytes[2], _seedBytes[3], _seedBytes[4], _seedBytes[5]
];
// Per 4.2.2, randomize (14 bit) clockseq
var _clockseq = (_seedBytes[6] << 8 | _seedBytes[7]) & 0x3fff;
// Previous uuid creation time
var _lastMSecs = 0, _lastNSecs = 0;
// See https://github.com/broofa/node-uuid for API details
function v1(options, buf, offset) {
var i = buf && offset || 0;
var b = buf || [];
options = options || {};
var clockseq = (options.clockseq != null) ? options.clockseq : _clockseq;
// UUID timestamps are 100 nano-second units since the Gregorian epoch,
// (1582-10-15 00:00). JSNumbers aren't precise enough for this, so
// time is handled internally as 'msecs' (integer milliseconds) and 'nsecs'
// (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00.
var msecs = (options.msecs != null) ? options.msecs : new Date().getTime();
// Per 4.2.1.2, use count of uuid's generated during the current clock
// cycle to simulate higher resolution clock
var nsecs = (options.nsecs != null) ? options.nsecs : _lastNSecs + 1;
// Time since last uuid creation (in msecs)
var dt = (msecs - _lastMSecs) + (nsecs - _lastNSecs)/10000;
// Per 4.2.1.2, Bump clockseq on clock regression
if (dt < 0 && options.clockseq == null) {
clockseq = clockseq + 1 & 0x3fff;
}
// Reset nsecs if clock regresses (new clockseq) or we've moved onto a new
// time interval
if ((dt < 0 || msecs > _lastMSecs) && options.nsecs == null) {
nsecs = 0;
}
// Per 4.2.1.2 Throw error if too many uuids are requested
if (nsecs >= 10000) {
throw new Error('uuid.v1(): Can\'t create more than 10M uuids/sec');
}
_lastMSecs = msecs;
_lastNSecs = nsecs;
_clockseq = clockseq;
// Per 4.1.4 - Convert from unix epoch to Gregorian epoch
msecs += 12219292800000;
// `time_low`
var tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000;
b[i++] = tl >>> 24 & 0xff;
b[i++] = tl >>> 16 & 0xff;
b[i++] = tl >>> 8 & 0xff;
b[i++] = tl & 0xff;
// `time_mid`
var tmh = (msecs / 0x100000000 * 10000) & 0xfffffff;
b[i++] = tmh >>> 8 & 0xff;
b[i++] = tmh & 0xff;
// `time_high_and_version`
b[i++] = tmh >>> 24 & 0xf | 0x10; // include version
b[i++] = tmh >>> 16 & 0xff;
// `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant)
b[i++] = clockseq >>> 8 | 0x80;
// `clock_seq_low`
b[i++] = clockseq & 0xff;
// `node`
var node = options.node || _nodeId;
for (var n = 0; n < 6; n++) {
b[i + n] = node[n];
}
return buf ? buf : unparse(b);
}
// **`v4()` - Generate random UUID**
// See https://github.com/broofa/node-uuid for API details
function v4(options, buf, offset) {
// Deprecated - 'format' argument, as supported in v1.2
var i = buf && offset || 0;
if (typeof(options) === 'string') {
buf = (options === 'binary') ? new BufferClass(16) : null;
options = null;
}
options = options || {};
var rnds = options.random || (options.rng || _rng)();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ii++) {
buf[i + ii] = rnds[ii];
}
}
return buf || unparse(rnds);
}
// Export public API
var uuid = v4;
uuid.v1 = v1;
uuid.v4 = v4;
uuid.parse = parse;
uuid.unparse = unparse;
uuid.BufferClass = BufferClass;
uuid._rng = _rng;
uuid._mathRNG = _mathRNG;
uuid._nodeRNG = _nodeRNG;
uuid._whatwgRNG = _whatwgRNG;
if (('undefined' !== typeof module) && module.exports) {
// Publish as node.js module
module.exports = uuid;
} else if (typeof define === 'function' && define.amd) {
// Publish as AMD module
define(function() {return uuid;});
} else {
// Publish as global (in browsers)
_previousRoot = _window.uuid;
// **`noConflict()` - (browser only) to reset global 'uuid' var**
uuid.noConflict = function() {
_window.uuid = _previousRoot;
return uuid;
};
_window.uuid = uuid;
}
})('undefined' !== typeof window ? window : null);

54
node_modules/phantomjs/node_modules/node-uuid/v3.js generated vendored Normal file
View File

@@ -0,0 +1,54 @@
var rng = require('./lib/rng');
var bytesToUuid = require('./lib/bytesToUuid');
function v3(name, namespaceUuid, buf, offset) {
var i = buf && offset || 0;
if (typeof(name) != 'string) {
throw TypeError('name must be defined')
}
if (typeof(namespaceUuid) != 'string) {
throw TypeError('name must be defined')
}
if (typeof(options) == 'string') {
buf = options == 'binary' ? new Array(16) : null;
options = null;
}
options = options || {};
var rnds = options.random || (options.rng || rng)();
// Per 4.4, set bits for version and `clock_seq_hi_and_reserved`
rnds[6] = (rnds[6] & 0x0f) | 0x40;
rnds[8] = (rnds[8] & 0x3f) | 0x80;
// Copy bytes to buffer, if provided
if (buf) {
for (var ii = 0; ii < 16; ++ii) {
buf[i + ii] = rnds[ii];
}
}
return buf || bytesToUuid(rnds);
}
exports.namespace = function(uuid) {
// Parse namespace uuid
var namespaceBytes = (uuid).match(/([0-9a-f][0-9a-f])/gi).map(function(s) {
return parseInt(s, 16);
});
return function(name) {
var bytes = [].concat(namespaceBytes);
var utf8String = unescape(encodeURIComponent(s))
for (var i = 0; i < utf8String.length; i++) {
bytes.push(utf8String.charCodeAt(i));
}
var hash = md5(bytes);
}
}
module.exports = v4;

55
node_modules/phantomjs/node_modules/oauth-sign/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,55 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,4 @@
oauth-sign
==========
OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module.

136
node_modules/phantomjs/node_modules/oauth-sign/index.js generated vendored Normal file
View File

@@ -0,0 +1,136 @@
var crypto = require('crypto')
, qs = require('querystring')
;
function sha1 (key, body) {
return crypto.createHmac('sha1', key).update(body).digest('base64')
}
function rsa (key, body) {
return crypto.createSign("RSA-SHA1").update(body).sign(key, 'base64');
}
function rfc3986 (str) {
return encodeURIComponent(str)
.replace(/!/g,'%21')
.replace(/\*/g,'%2A')
.replace(/\(/g,'%28')
.replace(/\)/g,'%29')
.replace(/'/g,'%27')
;
}
// Maps object to bi-dimensional array
// Converts { foo: 'A', bar: [ 'b', 'B' ]} to
// [ ['foo', 'A'], ['bar', 'b'], ['bar', 'B'] ]
function map (obj) {
var key, val, arr = []
for (key in obj) {
val = obj[key]
if (Array.isArray(val))
for (var i = 0; i < val.length; i++)
arr.push([key, val[i]])
else if (typeof val === "object")
for (var prop in val)
arr.push([key + '[' + prop + ']', val[prop]]);
else
arr.push([key, val])
}
return arr
}
// Compare function for sort
function compare (a, b) {
return a > b ? 1 : a < b ? -1 : 0
}
function generateBase (httpMethod, base_uri, params) {
// adapted from https://dev.twitter.com/docs/auth/oauth and
// https://dev.twitter.com/docs/auth/creating-signature
// Parameter normalization
// http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
var normalized = map(params)
// 1. First, the name and value of each parameter are encoded
.map(function (p) {
return [ rfc3986(p[0]), rfc3986(p[1] || '') ]
})
// 2. The parameters are sorted by name, using ascending byte value
// ordering. If two or more parameters share the same name, they
// are sorted by their value.
.sort(function (a, b) {
return compare(a[0], b[0]) || compare(a[1], b[1])
})
// 3. The name of each parameter is concatenated to its corresponding
// value using an "=" character (ASCII code 61) as a separator, even
// if the value is empty.
.map(function (p) { return p.join('=') })
// 4. The sorted name/value pairs are concatenated together into a
// single string by using an "&" character (ASCII code 38) as
// separator.
.join('&')
var base = [
rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'),
rfc3986(base_uri),
rfc3986(normalized)
].join('&')
return base
}
function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) {
var base = generateBase(httpMethod, base_uri, params)
var key = [
consumer_secret || '',
token_secret || ''
].map(rfc3986).join('&')
return sha1(key, base)
}
function rsasign (httpMethod, base_uri, params, private_key, token_secret) {
var base = generateBase(httpMethod, base_uri, params)
var key = private_key || ''
return rsa(key, base)
}
function plaintext (consumer_secret, token_secret) {
var key = [
consumer_secret || '',
token_secret || ''
].map(rfc3986).join('&')
return key
}
function sign (signMethod, httpMethod, base_uri, params, consumer_secret, token_secret) {
var method
var skipArgs = 1
switch (signMethod) {
case 'RSA-SHA1':
method = rsasign
break
case 'HMAC-SHA1':
method = hmacsign
break
case 'PLAINTEXT':
method = plaintext
skipArgs = 4
break
default:
throw new Error("Signature method not supported: " + signMethod)
}
return method.apply(null, [].slice.call(arguments, skipArgs))
}
exports.hmacsign = hmacsign
exports.rsasign = rsasign
exports.plaintext = plaintext
exports.sign = sign
exports.rfc3986 = rfc3986
exports.generateBase = generateBase

View File

@@ -0,0 +1,104 @@
{
"_args": [
[
{
"name": "oauth-sign",
"raw": "oauth-sign@~0.8.0",
"rawSpec": "~0.8.0",
"scope": null,
"spec": ">=0.8.0 <0.9.0",
"type": "range"
},
"/root/gitbook/node_modules/phantomjs/node_modules/request"
]
],
"_from": "oauth-sign@>=0.8.0 <0.9.0",
"_id": "oauth-sign@0.8.2",
"_inCache": true,
"_installable": true,
"_location": "/phantomjs/oauth-sign",
"_nodeVersion": "5.9.0",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/oauth-sign-0.8.2.tgz_1462396399020_0.8175400267355144"
},
"_npmUser": {
"email": "simeonvelichkov@gmail.com",
"name": "simov"
},
"_npmVersion": "2.15.3",
"_phantomChildren": {},
"_requested": {
"name": "oauth-sign",
"raw": "oauth-sign@~0.8.0",
"rawSpec": "~0.8.0",
"scope": null,
"spec": ">=0.8.0 <0.9.0",
"type": "range"
},
"_requiredBy": [
"/phantomjs/request"
],
"_resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
"_shasum": "46a6ab7f0aead8deae9ec0565780b7d4efeb9d43",
"_shrinkwrap": null,
"_spec": "oauth-sign@~0.8.0",
"_where": "/root/gitbook/node_modules/phantomjs/node_modules/request",
"author": {
"email": "mikeal.rogers@gmail.com",
"name": "Mikeal Rogers",
"url": "http://www.futurealoof.com"
},
"bugs": {
"url": "https://github.com/mikeal/oauth-sign/issues"
},
"dependencies": {},
"description": "OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module.",
"devDependencies": {},
"directories": {},
"dist": {
"integrity": "sha512-VlF07iu3VV3+BTXj43Nmp6Irt/G7j/NgEctUS6IweH1RGhURjjCc2NWtzXFPXXWWfc7hgbXQdtiQu2LGp6MxUg==",
"shasum": "46a6ab7f0aead8deae9ec0565780b7d4efeb9d43",
"signatures": [
{
"keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA",
"sig": "MEYCIQDsGDMpWVw5ht9ctwZdNWh1NhnqRkiUWUQira5SOdDJ2QIhAIIl3waE0bwT06kDDxjJ4l4tKzF2FIV8hg1Txv2C8xuN"
}
],
"tarball": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz"
},
"engines": {
"node": "*"
},
"files": [
"index.js"
],
"gitHead": "0b034206316132f57e26970152c2fb18e71bddd5",
"homepage": "https://github.com/mikeal/oauth-sign#readme",
"license": "Apache-2.0",
"main": "index.js",
"maintainers": [
{
"email": "mikeal.rogers@gmail.com",
"name": "mikeal"
},
{
"email": "jnylen@gmail.com",
"name": "nylen"
},
{
"email": "simeonvelichkov@gmail.com",
"name": "simov"
}
],
"name": "oauth-sign",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"url": "git+https://github.com/mikeal/oauth-sign.git"
},
"scripts": {
"test": "node test.js"
},
"version": "0.8.2"
}

1
node_modules/phantomjs/node_modules/qs/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1 @@
dist

18
node_modules/phantomjs/node_modules/qs/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,18 @@
.idea
*.iml
npm-debug.log
dump.rdb
node_modules
results.tap
results.xml
npm-shrinkwrap.json
config.json
.DS_Store
*/.DS_Store
*/*/.DS_Store
._*
*/._*
*/*/._*
coverage.*
lib-cov
complexity.md

8
node_modules/phantomjs/node_modules/qs/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,8 @@
language: node_js
node_js:
- 0.10
- 4.0
- 4
sudo: false

104
node_modules/phantomjs/node_modules/qs/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,104 @@
## **5.2.1**
- [Fix] ensure `key[]=x&key[]&key[]=y` results in 3, not 2, values
## [**5.2.0**](https://github.com/ljharb/qs/issues?milestone=30&state=closed)
- [**#64**](https://github.com/ljharb/qs/issues/64) Add option to sort object keys in the query string
## [**5.1.0**](https://github.com/ljharb/qs/issues?milestone=29&state=closed)
- [**#117**](https://github.com/ljharb/qs/issues/117) make URI encoding stringified results optional
- [**#106**](https://github.com/ljharb/qs/issues/106) Add flag `skipNulls` to optionally skip null values in stringify
## [**5.0.0**](https://github.com/ljharb/qs/issues?milestone=28&state=closed)
- [**#114**](https://github.com/ljharb/qs/issues/114) default allowDots to false
- [**#100**](https://github.com/ljharb/qs/issues/100) include dist to npm
## [**4.0.0**](https://github.com/ljharb/qs/issues?milestone=26&state=closed)
- [**#98**](https://github.com/ljharb/qs/issues/98) make returning plain objects and allowing prototype overwriting properties optional
## [**3.1.0**](https://github.com/ljharb/qs/issues?milestone=24&state=closed)
- [**#89**](https://github.com/ljharb/qs/issues/89) Add option to disable "Transform dot notation to bracket notation"
## [**3.0.0**](https://github.com/ljharb/qs/issues?milestone=23&state=closed)
- [**#80**](https://github.com/ljharb/qs/issues/80) qs.parse silently drops properties
- [**#77**](https://github.com/ljharb/qs/issues/77) Perf boost
- [**#60**](https://github.com/ljharb/qs/issues/60) Add explicit option to disable array parsing
- [**#74**](https://github.com/ljharb/qs/issues/74) Bad parse when turning array into object
- [**#81**](https://github.com/ljharb/qs/issues/81) Add a `filter` option
- [**#68**](https://github.com/ljharb/qs/issues/68) Fixed issue with recursion and passing strings into objects.
- [**#66**](https://github.com/ljharb/qs/issues/66) Add mixed array and object dot notation support Closes: #47
- [**#76**](https://github.com/ljharb/qs/issues/76) RFC 3986
- [**#85**](https://github.com/ljharb/qs/issues/85) No equal sign
- [**#84**](https://github.com/ljharb/qs/issues/84) update license attribute
## [**2.4.1**](https://github.com/ljharb/qs/issues?milestone=20&state=closed)
- [**#73**](https://github.com/ljharb/qs/issues/73) Property 'hasOwnProperty' of object #<Object> is not a function
## [**2.4.0**](https://github.com/ljharb/qs/issues?milestone=19&state=closed)
- [**#70**](https://github.com/ljharb/qs/issues/70) Add arrayFormat option
## [**2.3.3**](https://github.com/ljharb/qs/issues?milestone=18&state=closed)
- [**#59**](https://github.com/ljharb/qs/issues/59) make sure array indexes are >= 0, closes #57
- [**#58**](https://github.com/ljharb/qs/issues/58) make qs usable for browser loader
## [**2.3.2**](https://github.com/ljharb/qs/issues?milestone=17&state=closed)
- [**#55**](https://github.com/ljharb/qs/issues/55) allow merging a string into an object
## [**2.3.1**](https://github.com/ljharb/qs/issues?milestone=16&state=closed)
- [**#52**](https://github.com/ljharb/qs/issues/52) Return "undefined" and "false" instead of throwing "TypeError".
## [**2.3.0**](https://github.com/ljharb/qs/issues?milestone=15&state=closed)
- [**#50**](https://github.com/ljharb/qs/issues/50) add option to omit array indices, closes #46
## [**2.2.5**](https://github.com/ljharb/qs/issues?milestone=14&state=closed)
- [**#39**](https://github.com/ljharb/qs/issues/39) Is there an alternative to Buffer.isBuffer?
- [**#49**](https://github.com/ljharb/qs/issues/49) refactor utils.merge, fixes #45
- [**#41**](https://github.com/ljharb/qs/issues/41) avoid browserifying Buffer, for #39
## [**2.2.4**](https://github.com/ljharb/qs/issues?milestone=13&state=closed)
- [**#38**](https://github.com/ljharb/qs/issues/38) how to handle object keys beginning with a number
## [**2.2.3**](https://github.com/ljharb/qs/issues?milestone=12&state=closed)
- [**#37**](https://github.com/ljharb/qs/issues/37) parser discards first empty value in array
- [**#36**](https://github.com/ljharb/qs/issues/36) Update to lab 4.x
## [**2.2.2**](https://github.com/ljharb/qs/issues?milestone=11&state=closed)
- [**#33**](https://github.com/ljharb/qs/issues/33) Error when plain object in a value
- [**#34**](https://github.com/ljharb/qs/issues/34) use Object.prototype.hasOwnProperty.call instead of obj.hasOwnProperty
- [**#24**](https://github.com/ljharb/qs/issues/24) Changelog? Semver?
## [**2.2.1**](https://github.com/ljharb/qs/issues?milestone=10&state=closed)
- [**#32**](https://github.com/ljharb/qs/issues/32) account for circular references properly, closes #31
- [**#31**](https://github.com/ljharb/qs/issues/31) qs.parse stackoverflow on circular objects
## [**2.2.0**](https://github.com/ljharb/qs/issues?milestone=9&state=closed)
- [**#26**](https://github.com/ljharb/qs/issues/26) Don't use Buffer global if it's not present
- [**#30**](https://github.com/ljharb/qs/issues/30) Bug when merging non-object values into arrays
- [**#29**](https://github.com/ljharb/qs/issues/29) Don't call Utils.clone at the top of Utils.merge
- [**#23**](https://github.com/ljharb/qs/issues/23) Ability to not limit parameters?
## [**2.1.0**](https://github.com/ljharb/qs/issues?milestone=8&state=closed)
- [**#22**](https://github.com/ljharb/qs/issues/22) Enable using a RegExp as delimiter
## [**2.0.0**](https://github.com/ljharb/qs/issues?milestone=7&state=closed)
- [**#18**](https://github.com/ljharb/qs/issues/18) Why is there arrayLimit?
- [**#20**](https://github.com/ljharb/qs/issues/20) Configurable parametersLimit
- [**#21**](https://github.com/ljharb/qs/issues/21) make all limits optional, for #18, for #20
## [**1.2.2**](https://github.com/ljharb/qs/issues?milestone=6&state=closed)
- [**#19**](https://github.com/ljharb/qs/issues/19) Don't overwrite null values
## [**1.2.1**](https://github.com/ljharb/qs/issues?milestone=5&state=closed)
- [**#16**](https://github.com/ljharb/qs/issues/16) ignore non-string delimiters
- [**#15**](https://github.com/ljharb/qs/issues/15) Close code block
## [**1.2.0**](https://github.com/ljharb/qs/issues?milestone=4&state=closed)
- [**#12**](https://github.com/ljharb/qs/issues/12) Add optional delim argument
- [**#13**](https://github.com/ljharb/qs/issues/13) fix #11: flattened keys in array are now correctly parsed
## [**1.1.0**](https://github.com/ljharb/qs/issues?milestone=3&state=closed)
- [**#7**](https://github.com/ljharb/qs/issues/7) Empty values of a POST array disappear after being submitted
- [**#9**](https://github.com/ljharb/qs/issues/9) Should not omit equals signs (=) when value is null
- [**#6**](https://github.com/ljharb/qs/issues/6) Minor grammar fix in README
## [**1.0.2**](https://github.com/ljharb/qs/issues?milestone=2&state=closed)
- [**#5**](https://github.com/ljharb/qs/issues/5) array holes incorrectly copied into object on large index

View File

@@ -0,0 +1 @@
Please view our [hapijs contributing guide](https://github.com/hapijs/hapi/blob/master/CONTRIBUTING.md).

28
node_modules/phantomjs/node_modules/qs/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,28 @@
Copyright (c) 2014 Nathan LaFreniere and other contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The names of any contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* * *
The complete list of contributors can be found at: https://github.com/hapijs/qs/graphs/contributors

331
node_modules/phantomjs/node_modules/qs/README.md generated vendored Normal file
View File

@@ -0,0 +1,331 @@
# qs
A querystring parsing and stringifying library with some added security.
[![Build Status](https://secure.travis-ci.org/hapijs/qs.svg)](http://travis-ci.org/hapijs/qs)
Lead Maintainer: [Nathan LaFreniere](https://github.com/nlf)
The **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring).
## Usage
```javascript
var Qs = require('qs');
var obj = Qs.parse('a=c'); // { a: 'c' }
var str = Qs.stringify(obj); // 'a=c'
```
### Parsing Objects
```javascript
Qs.parse(string, [options]);
```
**qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`.
For example, the string `'foo[bar]=baz'` converts to:
```javascript
{
foo: {
bar: 'baz'
}
}
```
When using the `plainObjects` option the parsed value is returned as a plain object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
```javascript
Qs.parse('a.hasOwnProperty=b', { plainObjects: true });
// { a: { hasOwnProperty: 'b' } }
```
By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use `plainObjects` as mentioned above, or set `allowPrototypes` to `true` which will allow user input to overwrite those properties. *WARNING* It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.
```javascript
Qs.parse('a.hasOwnProperty=b', { allowPrototypes: true });
// { a: { hasOwnProperty: 'b' } }
```
URI encoded strings work too:
```javascript
Qs.parse('a%5Bb%5D=c');
// { a: { b: 'c' } }
```
You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`:
```javascript
{
foo: {
bar: {
baz: 'foobarbaz'
}
}
}
```
By default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like
`'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be:
```javascript
{
a: {
b: {
c: {
d: {
e: {
f: {
'[g][h][i]': 'j'
}
}
}
}
}
}
}
```
This depth can be overridden by passing a `depth` option to `Qs.parse(string, [options])`:
```javascript
Qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
// { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }
```
The depth limit helps mitigate abuse when **qs** is used to parse user input, and it is recommended to keep it a reasonably small number.
For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option:
```javascript
Qs.parse('a=b&c=d', { parameterLimit: 1 });
// { a: 'b' }
```
An optional delimiter can also be passed:
```javascript
Qs.parse('a=b;c=d', { delimiter: ';' });
// { a: 'b', c: 'd' }
```
Delimiters can be a regular expression too:
```javascript
Qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ });
// { a: 'b', c: 'd', e: 'f' }
```
Option `allowDots` can be used to enable dot notation:
```javascript
Qs.parse('a.b=c', { allowDots: true });
// { a: { b: 'c' } }
```
### Parsing Arrays
**qs** can also parse arrays using a similar `[]` notation:
```javascript
Qs.parse('a[]=b&a[]=c');
// { a: ['b', 'c'] }
```
You may specify an index as well:
```javascript
Qs.parse('a[1]=c&a[0]=b');
// { a: ['b', 'c'] }
```
Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number
to create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving
their order:
```javascript
Qs.parse('a[1]=b&a[15]=c');
// { a: ['b', 'c'] }
```
Note that an empty string is also a value, and will be preserved:
```javascript
Qs.parse('a[]=&a[]=b');
// { a: ['', 'b'] }
Qs.parse('a[0]=b&a[1]=&a[2]=c');
// { a: ['b', '', 'c'] }
```
**qs** will also limit specifying indices in an array to a maximum index of `20`. Any array members with an index of greater than `20` will
instead be converted to an object with the index as the key:
```javascript
Qs.parse('a[100]=b');
// { a: { '100': 'b' } }
```
This limit can be overridden by passing an `arrayLimit` option:
```javascript
Qs.parse('a[1]=b', { arrayLimit: 0 });
// { a: { '1': 'b' } }
```
To disable array parsing entirely, set `parseArrays` to `false`.
```javascript
Qs.parse('a[]=b', { parseArrays: false });
// { a: { '0': 'b' } }
```
If you mix notations, **qs** will merge the two items into an object:
```javascript
Qs.parse('a[0]=b&a[b]=c');
// { a: { '0': 'b', b: 'c' } }
```
You can also create arrays of objects:
```javascript
Qs.parse('a[][b]=c');
// { a: [{ b: 'c' }] }
```
### Stringifying
```javascript
Qs.stringify(object, [options]);
```
When stringifying, **qs** by default URI encodes output. Objects are stringified as you would expect:
```javascript
Qs.stringify({ a: 'b' });
// 'a=b'
Qs.stringify({ a: { b: 'c' } });
// 'a%5Bb%5D=c'
```
This encoding can be disabled by setting the `encode` option to `false`:
```javascript
Qs.stringify({ a: { b: 'c' } }, { encode: false });
// 'a[b]=c'
```
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases *will* be URI encoded during real usage.
When arrays are stringified, by default they are given explicit indices:
```javascript
Qs.stringify({ a: ['b', 'c', 'd'] });
// 'a[0]=b&a[1]=c&a[2]=d'
```
You may override this by setting the `indices` option to `false`:
```javascript
Qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
// 'a=b&a=c&a=d'
```
You may use the `arrayFormat` option to specify the format of the output array
```javascript
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
Qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'
```
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
```javascript
Qs.stringify({ a: '' });
// 'a='
```
Properties that are set to `undefined` will be omitted entirely:
```javascript
Qs.stringify({ a: null, b: undefined });
// 'a='
```
The delimiter may be overridden with stringify as well:
```javascript
Qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' });
// 'a=b;c=d'
```
Finally, you can use the `filter` option to restrict which keys will be included in the stringified output.
If you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you
pass an array, it will be used to select properties and array indices for stringification:
```javascript
function filterFunc(prefix, value) {
if (prefix == 'b') {
// Return an `undefined` value to omit a property.
return;
}
if (prefix == 'e[f]') {
return value.getTime();
}
if (prefix == 'e[g][0]') {
return value * 2;
}
return value;
}
Qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc })
// 'a=b&c=d&e[f]=123&e[g][0]=4'
Qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] })
// 'a=b&e=f'
Qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] })
// 'a[0]=b&a[2]=d'
```
### Handling of `null` values
By default, `null` values are treated like empty strings:
```javascript
Qs.stringify({ a: null, b: '' });
// 'a=&b='
```
Parsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings.
```javascript
Qs.parse('a&b=')
// { a: '', b: '' }
```
To distinguish between `null` values and empty strings use the `strictNullHandling` flag. In the result string the `null`
values have no `=` sign:
```javascript
Qs.stringify({ a: null, b: '' }, { strictNullHandling: true });
// 'a&b='
```
To parse values without `=` back to `null` use the `strictNullHandling` flag:
```javascript
Qs.parse('a&b=', { strictNullHandling: true });
// { a: null, b: '' }
```
To completely skip rendering keys with `null` values, use the `skipNulls` flag:
```javascript
qs.stringify({ a: 'b', c: null}, { skipNulls: true })
// 'a=b'
```

22
node_modules/phantomjs/node_modules/qs/bower.json generated vendored Normal file
View File

@@ -0,0 +1,22 @@
{
"name": "qs",
"main": "dist/qs.js",
"version": "5.1.0",
"homepage": "https://github.com/hapijs/qs",
"authors": [
"Nathan LaFreniere <quitlahok@gmail.com>"
],
"description": "A querystring parser that supports nesting and arrays, with a depth limit",
"keywords": [
"querystring",
"qs"
],
"license": "BSD-3-Clause",
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
]
}

15
node_modules/phantomjs/node_modules/qs/component.json generated vendored Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "qs",
"repository": "hapijs/qs",
"description": "query-string parser / stringifier with nesting support",
"version": "5.1.0",
"keywords": ["querystring", "query", "parser"],
"main": "lib/index.js",
"scripts": [
"lib/index.js",
"lib/parse.js",
"lib/stringify.js",
"lib/utils.js"
],
"license": "BSD-3-Clause"
}

551
node_modules/phantomjs/node_modules/qs/dist/qs.js generated vendored Normal file
View File

@@ -0,0 +1,551 @@
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Qs = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
// Load modules
var Stringify = require('./stringify');
var Parse = require('./parse');
// Declare internals
var internals = {};
module.exports = {
stringify: Stringify,
parse: Parse
};
},{"./parse":2,"./stringify":3}],2:[function(require,module,exports){
// Load modules
var Utils = require('./utils');
// Declare internals
var internals = {
delimiter: '&',
depth: 5,
arrayLimit: 20,
parameterLimit: 1000,
strictNullHandling: false,
plainObjects: false,
allowPrototypes: false,
allowDots: false
};
internals.parseValues = function (str, options) {
var obj = {};
var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit);
for (var i = 0, il = parts.length; i < il; ++i) {
var part = parts[i];
var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1;
var key, val;
if (pos === -1) {
key = Utils.decode(part);
val = options.strictNullHandling ? null : '';
} else {
key = Utils.decode(part.slice(0, pos));
val = Utils.decode(part.slice(pos + 1));
}
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj[key] = [].concat(obj[key]).concat(val);
} else {
obj[key] = val;
}
}
return obj;
};
internals.parseObject = function (chain, val, options) {
if (!chain.length) {
return val;
}
var root = chain.shift();
var obj;
if (root === '[]') {
obj = [];
obj = obj.concat(internals.parseObject(chain, val, options));
}
else {
obj = options.plainObjects ? Object.create(null) : {};
var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root;
var index = parseInt(cleanRoot, 10);
var indexString = '' + index;
if (!isNaN(index) &&
root !== cleanRoot &&
indexString === cleanRoot &&
index >= 0 &&
(options.parseArrays &&
index <= options.arrayLimit)) {
obj = [];
obj[index] = internals.parseObject(chain, val, options);
}
else {
obj[cleanRoot] = internals.parseObject(chain, val, options);
}
}
return obj;
};
internals.parseKeys = function (key, val, options) {
if (!key) {
return;
}
// Transform dot notation to bracket notation
if (options.allowDots) {
key = key.replace(/\.([^\.\[]+)/g, '[$1]');
}
// The regex chunks
var parent = /^([^\[\]]*)/;
var child = /(\[[^\[\]]*\])/g;
// Get the parent
var segment = parent.exec(key);
// Stash the parent if it exists
var keys = [];
if (segment[1]) {
// If we aren't using plain objects, optionally prefix keys
// that would overwrite object prototype properties
if (!options.plainObjects &&
Object.prototype.hasOwnProperty(segment[1])) {
if (!options.allowPrototypes) {
return;
}
}
keys.push(segment[1]);
}
// Loop through children appending to the array until we hit depth
var i = 0;
while ((segment = child.exec(key)) !== null && i < options.depth) {
++i;
if (!options.plainObjects &&
Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) {
if (!options.allowPrototypes) {
continue;
}
}
keys.push(segment[1]);
}
// If there's a remainder, just add whatever is left
if (segment) {
keys.push('[' + key.slice(segment.index) + ']');
}
return internals.parseObject(keys, val, options);
};
module.exports = function (str, options) {
options = options || {};
options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter;
options.depth = typeof options.depth === 'number' ? options.depth : internals.depth;
options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit;
options.parseArrays = options.parseArrays !== false;
options.allowDots = typeof options.allowDots === 'boolean' ? options.allowDots : internals.allowDots;
options.plainObjects = typeof options.plainObjects === 'boolean' ? options.plainObjects : internals.plainObjects;
options.allowPrototypes = typeof options.allowPrototypes === 'boolean' ? options.allowPrototypes : internals.allowPrototypes;
options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit;
options.strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
if (str === '' ||
str === null ||
typeof str === 'undefined') {
return options.plainObjects ? Object.create(null) : {};
}
var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str;
var obj = options.plainObjects ? Object.create(null) : {};
// Iterate over the keys and setup the new object
var keys = Object.keys(tempObj);
for (var i = 0, il = keys.length; i < il; ++i) {
var key = keys[i];
var newObj = internals.parseKeys(key, tempObj[key], options);
obj = Utils.merge(obj, newObj, options);
}
return Utils.compact(obj);
};
},{"./utils":4}],3:[function(require,module,exports){
// Load modules
var Utils = require('./utils');
// Declare internals
var internals = {
delimiter: '&',
arrayPrefixGenerators: {
brackets: function (prefix, key) {
return prefix + '[]';
},
indices: function (prefix, key) {
return prefix + '[' + key + ']';
},
repeat: function (prefix, key) {
return prefix;
}
},
strictNullHandling: false,
skipNulls: false,
encode: true
};
internals.stringify = function (obj, prefix, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort) {
if (typeof filter === 'function') {
obj = filter(prefix, obj);
}
else if (Utils.isBuffer(obj)) {
obj = obj.toString();
}
else if (obj instanceof Date) {
obj = obj.toISOString();
}
else if (obj === null) {
if (strictNullHandling) {
return encode ? Utils.encode(prefix) : prefix;
}
obj = '';
}
if (typeof obj === 'string' ||
typeof obj === 'number' ||
typeof obj === 'boolean') {
if (encode) {
return [Utils.encode(prefix) + '=' + Utils.encode(obj)];
}
return [prefix + '=' + obj];
}
var values = [];
if (typeof obj === 'undefined') {
return values;
}
var objKeys;
if (Array.isArray(filter)) {
objKeys = filter;
} else {
var keys = Object.keys(obj);
objKeys = sort ? keys.sort(sort) : keys;
}
for (var i = 0, il = objKeys.length; i < il; ++i) {
var key = objKeys[i];
if (skipNulls &&
obj[key] === null) {
continue;
}
if (Array.isArray(obj)) {
values = values.concat(internals.stringify(obj[key], generateArrayPrefix(prefix, key), generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
}
else {
values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']', generateArrayPrefix, strictNullHandling, skipNulls, encode, filter));
}
}
return values;
};
module.exports = function (obj, options) {
options = options || {};
var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter;
var strictNullHandling = typeof options.strictNullHandling === 'boolean' ? options.strictNullHandling : internals.strictNullHandling;
var skipNulls = typeof options.skipNulls === 'boolean' ? options.skipNulls : internals.skipNulls;
var encode = typeof options.encode === 'boolean' ? options.encode : internals.encode;
var sort = typeof options.sort === 'function' ? options.sort : null;
var objKeys;
var filter;
if (typeof options.filter === 'function') {
filter = options.filter;
obj = filter('', obj);
}
else if (Array.isArray(options.filter)) {
objKeys = filter = options.filter;
}
var keys = [];
if (typeof obj !== 'object' ||
obj === null) {
return '';
}
var arrayFormat;
if (options.arrayFormat in internals.arrayPrefixGenerators) {
arrayFormat = options.arrayFormat;
}
else if ('indices' in options) {
arrayFormat = options.indices ? 'indices' : 'repeat';
}
else {
arrayFormat = 'indices';
}
var generateArrayPrefix = internals.arrayPrefixGenerators[arrayFormat];
if (!objKeys) {
objKeys = Object.keys(obj);
}
if (sort) {
objKeys.sort(sort);
}
for (var i = 0, il = objKeys.length; i < il; ++i) {
var key = objKeys[i];
if (skipNulls &&
obj[key] === null) {
continue;
}
keys = keys.concat(internals.stringify(obj[key], key, generateArrayPrefix, strictNullHandling, skipNulls, encode, filter, sort));
}
return keys.join(delimiter);
};
},{"./utils":4}],4:[function(require,module,exports){
// Load modules
// Declare internals
var internals = {};
internals.hexTable = new Array(256);
for (var h = 0; h < 256; ++h) {
internals.hexTable[h] = '%' + ((h < 16 ? '0' : '') + h.toString(16)).toUpperCase();
}
exports.arrayToObject = function (source, options) {
var obj = options.plainObjects ? Object.create(null) : {};
for (var i = 0, il = source.length; i < il; ++i) {
if (typeof source[i] !== 'undefined') {
obj[i] = source[i];
}
}
return obj;
};
exports.merge = function (target, source, options) {
if (!source) {
return target;
}
if (typeof source !== 'object') {
if (Array.isArray(target)) {
target.push(source);
}
else if (typeof target === 'object') {
target[source] = true;
}
else {
target = [target, source];
}
return target;
}
if (typeof target !== 'object') {
target = [target].concat(source);
return target;
}
if (Array.isArray(target) &&
!Array.isArray(source)) {
target = exports.arrayToObject(target, options);
}
var keys = Object.keys(source);
for (var k = 0, kl = keys.length; k < kl; ++k) {
var key = keys[k];
var value = source[key];
if (!Object.prototype.hasOwnProperty.call(target, key)) {
target[key] = value;
}
else {
target[key] = exports.merge(target[key], value, options);
}
}
return target;
};
exports.decode = function (str) {
try {
return decodeURIComponent(str.replace(/\+/g, ' '));
} catch (e) {
return str;
}
};
exports.encode = function (str) {
// This code was originally written by Brian White (mscdex) for the io.js core querystring library.
// It has been adapted here for stricter adherence to RFC 3986
if (str.length === 0) {
return str;
}
if (typeof str !== 'string') {
str = '' + str;
}
var out = '';
for (var i = 0, il = str.length; i < il; ++i) {
var c = str.charCodeAt(i);
if (c === 0x2D || // -
c === 0x2E || // .
c === 0x5F || // _
c === 0x7E || // ~
(c >= 0x30 && c <= 0x39) || // 0-9
(c >= 0x41 && c <= 0x5A) || // a-z
(c >= 0x61 && c <= 0x7A)) { // A-Z
out += str[i];
continue;
}
if (c < 0x80) {
out += internals.hexTable[c];
continue;
}
if (c < 0x800) {
out += internals.hexTable[0xC0 | (c >> 6)] + internals.hexTable[0x80 | (c & 0x3F)];
continue;
}
if (c < 0xD800 || c >= 0xE000) {
out += internals.hexTable[0xE0 | (c >> 12)] + internals.hexTable[0x80 | ((c >> 6) & 0x3F)] + internals.hexTable[0x80 | (c & 0x3F)];
continue;
}
++i;
c = 0x10000 + (((c & 0x3FF) << 10) | (str.charCodeAt(i) & 0x3FF));
out += internals.hexTable[0xF0 | (c >> 18)] + internals.hexTable[0x80 | ((c >> 12) & 0x3F)] + internals.hexTable[0x80 | ((c >> 6) & 0x3F)] + internals.hexTable[0x80 | (c & 0x3F)];
}
return out;
};
exports.compact = function (obj, refs) {
if (typeof obj !== 'object' ||
obj === null) {
return obj;
}
refs = refs || [];
var lookup = refs.indexOf(obj);
if (lookup !== -1) {
return refs[lookup];
}
refs.push(obj);
if (Array.isArray(obj)) {
var compacted = [];
for (var i = 0, il = obj.length; i < il; ++i) {
if (typeof obj[i] !== 'undefined') {
compacted.push(obj[i]);
}
}
return compacted;
}
var keys = Object.keys(obj);
for (i = 0, il = keys.length; i < il; ++i) {
var key = keys[i];
obj[key] = exports.compact(obj[key], refs);
}
return obj;
};
exports.isRegExp = function (obj) {
return Object.prototype.toString.call(obj) === '[object RegExp]';
};
exports.isBuffer = function (obj) {
if (obj === null ||
typeof obj === 'undefined') {
return false;
}
return !!(obj.constructor &&
obj.constructor.isBuffer &&
obj.constructor.isBuffer(obj));
};
},{}]},{},[1])(1)
});

15
node_modules/phantomjs/node_modules/qs/lib/index.js generated vendored Normal file
View File

@@ -0,0 +1,15 @@
// Load modules
var Stringify = require('./stringify');
var Parse = require('./parse');
// Declare internals
var internals = {};
module.exports = {
stringify: Stringify,
parse: Parse
};

Some files were not shown because too many files have changed in this diff Show More