Added node-modules

This commit is contained in:
Dobie Wollert
2014-09-14 07:04:16 -04:00
parent 663941bf57
commit 6a92348cf5
4870 changed files with 670395 additions and 0 deletions

1
node_modules/googleapis/.cache/admindirectory_v1 generated vendored Normal file

File diff suppressed because one or more lines are too long

1
node_modules/googleapis/.cache/calendarv3 generated vendored Normal file

File diff suppressed because one or more lines are too long

4
node_modules/googleapis/.npmignore generated vendored Normal file
View File

@ -0,0 +1,4 @@
tests/*
examples/*
.cache/*
b041042364d89046c003ca151a6254ef/*

3
node_modules/googleapis/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- 0.8

202
node_modules/googleapis/COPYING generated vendored Normal file
View File

@ -0,0 +1,202 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2013 Google Inc.
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.

247
node_modules/googleapis/README.md generated vendored Normal file
View File

@ -0,0 +1,247 @@
# google-api-nodejs-client [alpha]
[![Build Status](https://travis-ci.org/google/google-api-nodejs-client.png)](https://travis-ci.org/google/google-api-nodejs-client)
`google-api-nodejs-client` is Google's officially supported
[node.js](http://nodejs.org/) client
library for accessing Google APIs, it also supports authorization and
authentication with OAuth 2.0.
**Note**: This library is currently in *alpha* status, meaning that we can make
changes in the future that *may not be compatible* with the previous versions.
## Installation
The library is distributed on `npm`. In order to add it as a dependency,
run the following command:
$ npm install googleapis
## Guide
### Discover APIs
Dynamically load Google APIs and start making requests:
~~~~ js
var googleapis = require('googleapis');
googleapis
.discover('urlshortener', 'v1')
.discover('plus', 'v1')
.execute(function(err, client) {
var params = { shortUrl: 'http://goo.gl/DdUKX' };
var req1 = client.urlshortener.url.get(params);
req1.execute(function (err, response) {
console.log('Long url is', response.longUrl);
});
var req2 = client.plus.people.get({ userId: '+BurcuDogan' });
req2.execute();
});
~~~~
Supported APIs are listed on
[Google APIs Explorer](https://developers.google.com/apis-explorer).
#### Discovery Document Caching
Discovery documents are being cached for 5 minutes locally.
You can configure the directory used to store cached discovery
files by using the `cache.path` option.
~~~~ js
googleapis
.discover('plus', 'v3')
.withOpts({ cache: { path: '<path>' }))
.execute();
~~~~
### API Client
Client libraries are generated during runtime by metadata provided by Google
APIs Discovery Service. Metadata provided by Discovery Service is cached,
and won't be requested each time you load a client. Below, there is an
example of loading a client for
[URL Shortener API](https://developers.google.com/url-shortener/).
~~~~ js
googleapis
.discover('urlshortener', 'v1')
.execute(function(err, client) {
// make requests
});
~~~~
### Requests
The following sample loads a client for URL Shortener and retrieves the long url
of the given short url:
~~~~ js
googleapis.discover('urlshortener', 'v1').execute(function(err, client) {
client.urlshortener.url.get({ shortUrl: 'http://goo.gl/DdUKX' })
.execute(function(err, result) {
// result.longUrl contains the long url.
});
});
~~~~
Alternatively, you may need to send an API key with the
request you are going to make. The following creates and executes a request from the Google+ API service to retrieve a person profile given a userId:
~~~~ js
googleapis
.discover('plus', 'v1')
.execute(function(err, client) {
var request1 = client.plus.people.get({ userId: '+BurcuDogan' })
.withApiKey(API_KEY);
request1.execute(function(err, result) {
console.log("Result: " + (err ? err.message : result.displayName));
});
});
~~~~
To learn more about API keys, please see the [documentation](https://developers.google.com/console/help/#UsingKeys).
### Batch requests
You can combine multiple requests in a single one by using batch requests.
~~~~ js
var request1 =
client.plus.people.get({ userId: '+BurcuDogan' });
var request2 =
client.urlshortener.url.insert({ longUrl: 'http://google.com' });
// Create from client service using the raw action name
var request3 = client.urlshortener.newRequest(
'urlshortener.url.get', { shortUrl: 'http://goo.gl/DdUKX' });
client
.newBatchRequest()
.add(request1)
.add(request2)
.add(request3)
.execute(function(err, results) {
});
~~~~
### Authorization and Authentication
This client comes with an OAuth2 client that allows you to retrieve an access token and
refreshes the token and re-try the request seamlessly if token is expired. The
basics of Google's OAuth 2.0 implementation is explained on
[Google Authorization and Authentication
documentation](https://developers.google.com/accounts/docs/OAuth2Login).
A complete sample application that authorizes and authenticates with OAuth2.0
client is available at `examples/oauth2.js`.
#### Consent Page Url
In order to ask for permissions from a user to retrieve an access token, you
should redirect them to a consent page. In order to create a consent page
URL:
~~~~ js
var googleapis = require('googleapis'),
OAuth2Client = googleapis.OAuth2Client;
var oauth2Client =
new OAuth2Client(CLIENT_ID, CLIENT_SECRET, REDIRECT_URL);
// generates a url that allows offline access and asks permissions
// for Google+ scope.
var url = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: 'https://www.googleapis.com/auth/plus.me'
});
~~~~
#### Retrieving Tokens
Once a user has given permissions on the consent page, Google will redirect
the page to the redirect url you have provided with a code query parameter.
GET /oauthcallback?code={authorizationCode}
With the code returned, you can ask for an access token as shown below:
~~~~ js
oauth2Client.getToken(code, function(err, tokens) {
// contains an access_token and optionally a refresh_token.
// save them permanently.
});
~~~~
#### Making Authenticated Requests
And you can start using oauth2Client to authorize and authenticate your
requests to Google APIs with the retrieved tokens. If you provide a
refresh_token, in cases when access_token is expired, it asks for a new
access_token and replays the request.
Following sample retrieves Google+ profile of the authenticated user.
~~~~ js
oauth2Client.credentials = {
access_token: 'ACCESS TOKEN HERE',
refresh_token: 'REFRESH TOKEN HERE'
};
client
.plus.people.get({ userId: 'me' })
.withAuthClient(oauth2Client)
.execute(callback);
~~~~
## License
`google-api-nodejs-client` is licensed with Apache 2.0. Full license text is
available on COPYING file.
## Contributors
Before making any contributions, please sign one of the contributor
license agreements below.
Fork the repo, develop and test your code changes.
Install all dependencies including development requirements by running:
$ npm install -d
Tests use mocha. To run all tests you can use
$ npm test
which looks for tests in the `./tests` directory.
Your code should honor the
[Google JavaScript Style Guide](http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml).
You can use
[Closure Linter](https://code.google.com/p/closure-linter/)
to detect style issues.
Submit a pull request. The repo owner will review your request. If it is
approved, the change will be merged. If it needs additional work, the repo
owner will respond with useful comments.
#### Contributor License Agreements
Before creating a pull request, please fill out either the individual or
corporate Contributor License Agreement.
* If you are an individual writing original source code and you're sure you
own the intellectual property, then you'll need to sign an
[individual CLA](http://code.google.com/legal/individual-cla-v1.0.html).
* If you work for a company that wants to allow you to contribute your work
to this client library, then you'll need to sign a
[corporate CLA](http://code.google.com/legal/corporate-cla-v1.0.html).
Follow either of the two links above to access the appropriate CLA and
instructions for how to sign and return it. Once we receive it, we'll add you
to the official list of contributors and be able to accept your patches.

41
node_modules/googleapis/lib/auth/authclient.js generated vendored Normal file
View File

@ -0,0 +1,41 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var DefaultTransporter = require('../transporters.js');
function AuthClient() {
this.transporter = new DefaultTransporter();
}
/**
* Provides an alternative request
* implementations with auth credentials.
*/
AuthClient.prototype.request = function() {
throw new Error('Not implemented yet.');
};
/**
* Sets auth credentials.
* @param {object} credentials Credentials.
*/
AuthClient.prototype.setCredentials = function(credentials) {
this.credentials = credentials;
};
/**
* Export AuthClient.
*/
module.exports = AuthClient;

79
node_modules/googleapis/lib/auth/computeclient.js generated vendored Normal file
View File

@ -0,0 +1,79 @@
/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var querystring = require('querystring');
var Auth2Client = require('./oauth2client.js');
var util = require('util');
/**
* @private
* Google Compute Engine metadata server token endpoint.
*/
Compute.GOOGLE_OAUTH2_TOKEN_URL_ =
'http://metadata/computeMetadata/v1beta1/instance/service-accounts/default/token';
/**
* @constructor
* Google Compute Engine service account credentials.
*
* Retrieve access token from the metadata server.
* See: https://developers.google.com/compute/docs/authentication
*
*/
function Compute() {
Compute.super_.call(this);
}
/**
* Inherit from Auth2Client.
*/
util.inherits(Compute, Auth2Client);
/**
* Get the initial access token from compute metadata server.
* @param {function=} opt_callback Optional callback.
*/
Compute.prototype.authorize = function(opt_callback) {
var that = this;
that.refreshToken_(null, function(err, result) {
if (!err) {
that.credentials = result;
that.credentials.refresh_token = 'compute-placeholder';
}
opt_callback && opt_callback(err, result);
});
};
/**
* @private
* Refreshes the access token.
* @param {object=} ignored_
* @param {function=} opt_callback Optional callback.
*/
Compute.prototype.refreshToken_ = function(ignored_, opt_callback) {
var uri = this.opts.tokenUrl || Compute.GOOGLE_OAUTH2_TOKEN_URL_;
// request for new token
this.transporter.request({
method: 'GET',
uri: uri,
json: true
}, opt_callback);
};
/**
* Export Compute.
*/
module.exports = Compute;

199
node_modules/googleapis/lib/auth/oauth2client.js generated vendored Normal file
View File

@ -0,0 +1,199 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var querystring = require('querystring');
var AuthClient = require('./authclient.js');
var util = require('util');
function OAuth2Client(clientId, clientSecret, redirectUri, opt_opts) {
OAuth2Client.super_.call(this);
this.clientId_ = clientId;
this.clientSecret_ = clientSecret;
this.redirectUri_ = redirectUri;
this.opts = opt_opts || {};
this.credentials = null;
}
/**
* Inherit from AuthClient.
*/
util.inherits(OAuth2Client, AuthClient);
/**
* The base URL for auth endpoints.
* @const
* @private
*
*/
OAuth2Client.GOOGLE_OAUTH2_AUTH_BASE_URL_ =
'https://accounts.google.com/o/oauth2/auth';
/**
* The base endpoint for token retrieval.
* @const
* @private
* The ..
*/
OAuth2Client.GOOGLE_OAUTH2_TOKEN_URL_ =
'https://accounts.google.com/o/oauth2/token';
/**
* The base endpoint to revoke tokens.
* @const
* @private
*/
OAuth2Client.GOOGLE_OAUTH2_REVOKE_URL_ =
'https://accounts.google.com/o/oauth2/revoke';
/**
* Generates URL for consent page landing.
* @param {object=} opt_opts Options.
* @return {string} URL to consent page.
*/
OAuth2Client.prototype.generateAuthUrl = function(opt_opts) {
var opts = opt_opts || {};
opts.response_type = opts.response_type || 'code';
opts.client_id = this.clientId_;
opts.redirect_uri = this.redirectUri_;
var rootUrl = this.opts.authBaseUrl ||
OAuth2Client.GOOGLE_OAUTH2_AUTH_BASE_URL_;
return rootUrl + '?' + querystring.stringify(opts);
};
/**
* Gets the access token for given code.
* @param {string} code The authorization code.
* @param {function=} opt_callback Optional callback fn.
*/
OAuth2Client.prototype.getToken = function(code, opt_callback) {
var uri = this.opts.tokenUrl || OAuth2Client.GOOGLE_OAUTH2_TOKEN_URL_;
var values = {
code: code,
client_id: this.clientId_,
client_secret: this.clientSecret_,
redirect_uri: this.redirectUri_,
grant_type: 'authorization_code'
};
this.transporter.request({
method: 'POST',
uri: uri,
form: values,
json: true
}, opt_callback);
};
/**
* @private
* Refreshes the access token.
* @param {string} refresh_token Existing refresh token.
* @param {function=} opt_callback Optional callback.
*/
OAuth2Client.prototype.refreshToken_ =
function(refresh_token, opt_callback) {
var uri = this.opts.tokenUrl || OAuth2Client.GOOGLE_OAUTH2_TOKEN_URL_;
var values = {
refresh_token: refresh_token,
client_id: this.clientId_,
client_secret: this.clientSecret_,
grant_type: 'refresh_token'
};
// request for new token
this.transporter.request({
method: 'POST',
uri: uri,
form: values,
json: true
}, opt_callback);
};
/**
* Revokes the access given to token.
* @param {string} token The existing token to be revoked.
* @param {function=} opt_callback Optional callback fn.
*/
OAuth2Client.prototype.revokeToken = function(token, opt_callback) {
this.transporter.request({
uri: OAuth2Client.GOOGLE_OAUTH2_REVOKE_URL_ +
'?' + querystring.stringify({ token: token }),
json: true
}, opt_callback);
};
/**
* Provides a request implementation with OAuth 2.0 flow.
* If credentials have a refresh_token, in cases of HTTP
* 401 and 403 responses, it automatically asks for a new
* access token and replays the unsuccessful request.
* @param {object} opts Request options.
* @param {function=} opt_callback Optional callback.
* @param {boolean=} opt_dontForceRefresh If set, don't ask for a new token
* with refresh_token.
*/
OAuth2Client.prototype.request =
function(opts, opt_callback, opt_dontForceRefresh) {
var that = this;
var credentials = this.credentials;
if (!credentials.access_token && !credentials.refresh_token) {
throw new Error('No access or refresh token is set.');
}
credentials.token_type = credentials.token_type || 'Bearer';
opts.headers = opts.headers || {};
opts.headers['Authorization']
= credentials.token_type + ' ' + credentials.access_token;
this.transporter.request(opts, function(err, body, res) {
var hasAuthError = false;
// TODO(burcud): Should we redo requests without
// an auth error? This question will be invalid when we switch
// to multi part batch requests.
err && err.forEach(function(e) {
hasAuthError = (e.code == 401 || e.code == 403);
});
// if there is an auth error, refresh the token
// and make the request again
if (!opt_dontForceRefresh && hasAuthError && credentials.refresh_token) {
// refresh access token and re-request
that.refreshToken_(credentials.refresh_token, function(err, result) {
if (err) {
opt_callback && opt_callback(err, null, null);
} else {
var tokens = result;
tokens.refresh_token = credentials.refresh_token;
that.credentials = tokens;
that.request(opts, opt_callback, true);
}
});
} else {
opt_callback && opt_callback(err, body, res);
}
});
};
/**
* Export OAuth2Client.
*/
module.exports = OAuth2Client;

112
node_modules/googleapis/lib/cache.js generated vendored Normal file
View File

@ -0,0 +1,112 @@
/**
* Copyright 2013 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var fs = require('fs');
/**
* @const
* @private
* Path to the temporary directory.
* @type {String}
*/
Cache.TMP_DIR_ = __dirname + '/../.cache';
/**
* @const
* @private
* Default encoding for cached files.
* @type {String}
*/
Cache.ENCODING_ = 'utf-8';
/**
* @const
* @private
* Default expires time in micro seconds.
* @type {Number}
*/
Cache.EXPIRES_IN_ = 5 * 60 * 1000;
/**
* @constructor
* Cache constructor.
* @param {String} opt_opts Optional options.
*/
function Cache(opt_opts) {
this.opts = opt_opts || {};
this.opts.path = this.opts.path || Cache.TMP_DIR_;
if (!fs.existsSync(this.opts.path)) {
fs.mkdirSync(this.opts.path, '700');
}
}
/**
* Loads discovery data from cache
* @param {object} api
* @return {object?} Returns the cached discovery data if exists
* or not expired.
*/
Cache.prototype.load = function(api) {
var path = this.getPath(api);
// check if file exists and not expired
if (!fs.existsSync(path)) {
return null;
}
if (this.isExpired(path)) {
// delete the expired cache file
fs.unlinkSync(path);
return null;
}
var data = fs.readFileSync(this.getPath(api), Cache.ENCODING_);
return data && JSON.parse(data);
};
/**
* Writes api discovery data to the cache.
* @param {object} api
* @param {object} data
*/
Cache.prototype.write = function(api, data) {
data && fs.writeFileSync(
this.getPath(api), JSON.stringify(data), Cache.ENCODING_);
};
/**
* Checks whether the file at path is expired or not
* @param {[type]} path The path of the file to check.
* @return {Boolean} Returns true or false depending on the expiration.
*/
Cache.prototype.isExpired = function(path) {
var expiresIn = this.opts.expiresIn || Cache.EXPIRES_IN_;
return new Date(fs.statSync(path).mtime).getTime() - expiresIn < 0;
};
/**
* Gets the path where the api data is stored at.
* @param {[type]} api
* @return {string} Path to the data file.
*/
Cache.prototype.getPath = function(api) {
return this.opts.path + '/' + api.name + api.version;
};
/**
* Exports Cache.
* @type {Cache}
*/
module.exports = Cache;

140
node_modules/googleapis/lib/client.js generated vendored Normal file
View File

@ -0,0 +1,140 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var Request = require('./requests.js').Request;
var BatchRequest = require('./requests.js').BatchRequest;
/**
* Constructs a new client with given API name and version.
* @constructor
*
* @param {object} apiMeta Schema returned by Discovery API.
*/
function Client(apiMeta) {
this.apiMeta = apiMeta;
this.authClient = null;
// generate helper methods
this.registerHelpers_();
}
/**
* Gets the API's name.
* @return {String}
*/
Client.prototype.getName = function() {
return this.apiMeta.name;
};
/**
* Gets the API's version.
* @return {String}
*/
Client.prototype.getVersion = function() {
return this.apiMeta.version;
};
/**
* @private
* Registers request builders for existing API methods.
*/
Client.prototype.registerHelpers_ = function() {
for (var i in this.apiMeta.methods) {
var methodMeta = this.apiMeta.methods[i];
this.extend_(this, methodMeta.id, this.generateHelper_(methodMeta));
}
};
/**
* @private
* TODO(burcud): move to utils
*
* @param {?object} root Object to be extended.
* @param {string} key Full key.
* @param {?object} obj Object to extend root object with.
* @return {object} Extended object.
*/
Client.prototype.extend_ = function(root, key, obj) {
if (!root) root = {};
var namespaceKeys = key.split('.');
var chain = root;
// avoid the client name
for (var i = 1; i < namespaceKeys.length; i++) {
var chainKey = namespaceKeys[i];
// if this is the last key, put obj in it.
if (i == namespaceKeys.length - 1) {
chain[chainKey] = obj;
} else if (!chain[chainKey]) {
chain[chainKey] = {};
}
// move to the next key
chain = chain[chainKey];
}
return root;
};
/**
* @private
* Generate a request builder helper.
*
* @param {object} methodMeta Method's schema returned by Discovery API.
* @return {Function} Function generated by methodMeta.
*/
Client.prototype.generateHelper_ = function(methodMeta) {
var that = this;
// generates a function to make a request
// to the resource on given method
return function(params, resource) {
return that.newRequest(methodMeta.id, params, resource);
};
};
/**
* Constructs a request to method with given parameters.
*
* @param {string} methodName Full name of the method.
* @param {?object} params Parameters.
* @param {object=} opt_resource Optional resource.
*
* @return {Request} New Request object constructed with given args.
*/
Client.prototype.newRequest = function(methodName, params, opt_resource) {
return new Request(this.apiMeta, methodName, params, opt_resource)
.withAuthClient(this.authClient);
};
/**
* Adds global auth client.
*
* @param {auth.AuthClient} client An auth client instance.
*
* @return {Client} Returns itself.
*/
Client.prototype.withAuthClient = function(client) {
this.authClient = client;
return this;
};
/**
* Exporting Client.
*/
module.exports = Client;

268
node_modules/googleapis/lib/googleapis.js generated vendored Normal file
View File

@ -0,0 +1,268 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var async = require('async'),
Cache = require('./cache.js'),
Client = require('./client.js'),
DefaultTransporter = require('./transporters.js'),
qs = require('querystring'),
requests = require('./requests.js'),
fs = require('fs');
/**
* @constructor
* GoogleApisClient constructor.
*/
function GoogleApisClient() {
this.clients = [];
this.ops = {};
this.authClient = null;
}
/**
* Add a new individual client to the instance.
* @param {String} name
* @param {Client} client
*/
GoogleApisClient.prototype.add = function(name, client) {
this[name] = client.withAuthClient(this.authClient);
};
/**
* Creates a new batch request.
* @return {BatchRequest} New batch request.
*/
GoogleApisClient.prototype.newBatchRequest = function() {
return new requests.BatchRequest()
.withAuthClient(this.authClient);
};
/**
* Adds global auth client.
*
* @param {auth.AuthClient} client An auth client instance.
*
* @return {Client} Returns itself.
*/
GoogleApisClient.prototype.withAuthClient = function(client) {
this.authClient = client;
return this;
};
/**
* @constructor
* GoogleApis constructor.
*/
function GoogleApis() {
this.opts = {};
this.toBeDiscovered = [];
this.transporter = exports.Transporter || new DefaultTransporter();
this.authClient = null;
}
/**
* @const
* @private
* Base path for discovery API.
* @type {string}
*/
GoogleApis.BASE_DISCOVERY_URL_ =
'https://www.googleapis.com/discovery/v1/apis/';
/**
* @const
* @private
* Discovery type.
* @type {string}
*/
// TODO(burcud): Switch to REST.
GoogleApis.DISCOVERY_TYPE_ = 'rpc';
/**
* @const
* @private
* Additional discovery parameters.
* @type {object}
*/
GoogleApis.DISCOVERY_PARAMS_ = null;
/**
* Discover the API with the given name, version and opt options.
* @param {String} name The name of the API.
* @param {String} version The version of the API.
* @param {Object} opt_opts Additional options.
* @return {GoogleApis} Returns itself.
*/
GoogleApis.prototype.discover = function(name, version, opt_opts) {
this.toBeDiscovered.push({
name: name, version: version, opts: opt_opts });
return this;
};
/**
* Executes requests to discover APIs.
* @param {Function=} opt_callback
*/
GoogleApis.prototype.execute = function(opt_callback) {
var that = this,
operations = [],
client = new GoogleApisClient()
.withAuthClient(this.authClient);
this.toBeDiscovered.forEach(function(obj) {
operations.push(function(callback) {
that.load.call(that, obj, callback);
});
});
async.parallel(operations, function(err, results) {
if (err) {
opt_callback && opt_callback(err, null);
} else {
results = results || [];
results.forEach(function(result) {
// extend client object with indivual clients.
client.add(result.getName(), result);
});
opt_callback && opt_callback(null, client);
}
});
};
/**
* Generates a client through discovery API.
* @param {String} api An object to represent the api name, version and opts.
* @param {Function=} opt_callback Optional callback function.
*/
GoogleApis.prototype.load = function(api, opt_callback) {
var that = this;
var cache = new Cache(this.opts.cache);
if (api.opts && api.opts.localDiscoveryFilePath) {
that.loadFromFile(api.opts.localDiscoveryFilePath, opt_callback);
return;
}
var generateClient = function(err, data) {
var client = null;
if (!err && data) {
cache.write(api, data);
client = new Client(data);
}
opt_callback && opt_callback(err, client);
};
var data = cache.load(api);
if (data) {
generateClient(null, data);
} else {
that.transporter.request({
uri: that.generateDiscoveryUrl(api), json: true
}, generateClient);
}
};
/**
* Generates a client from a local discovery file.
* @param {String} filename Path of the local discovery file.
* @param {Function=} opt_callback Optional callback function.
*/
GoogleApis.prototype.loadFromFile = function(filename, opt_callback) {
fs.readFile(filename, function(err, data) {
var client = null;
if (!err && data) {
client = new Client(JSON.parse(data));
}
opt_callback && opt_callback(err, client);
});
};
/**
* Generates the discovery url.
* @param {String} api An object to represent the api name, version and opts.
* @return {string} discoveryUrl.
*/
GoogleApis.prototype.generateDiscoveryUrl = function(api) {
api.opts = api.opts || {};
var baseDiscoveryUrl = api.opts.baseDiscoveryUrl ||
GoogleApis.BASE_DISCOVERY_URL_;
var discoveryParams = api.opts.discoveryParams ||
GoogleApis.DISCOVERY_PARAMS_;
var discoveryUrl = baseDiscoveryUrl;
discoveryUrl += encodeURIComponent(api.name) +
'/' + encodeURIComponent(api.version) +
'/' + GoogleApis.DISCOVERY_TYPE_;
if (discoveryParams) {
discoveryUrl += '?' + qs.stringify(discoveryParams);
}
return discoveryUrl;
};
/**
* Adds options.
*
* @param {object} opts Options.
* @return {GoogleApis} Returns itself.
*/
GoogleApis.prototype.withOpts = function(opts) {
this.opts = opts;
return this;
};
/**
* Adds global auth client.
*
* @param {auth.AuthClient} client An auth client instance.
* @return {GoogleApis} Returns itself.
*/
GoogleApis.prototype.withAuthClient = function(client) {
this.authClient = client;
return this;
};
var googleapis = new GoogleApis();
/**
* Shortcut to GoogleApis.
*/
googleapis.GoogleApis = GoogleApis;
/**
* Shortcut to OAuth2Client.
*/
googleapis.OAuth2Client = require('./auth/oauth2client.js');
/**
* Shortcut to Auth.
*/
googleapis.auth = {
Compute: require('./auth/computeclient.js'),
OAuth2Client: googleapis.OAuth2Client
};
/**
* Exports googleapis.
*/
module.exports = googleapis;
/**
* Exports Transporter.
*/
exports.Transporter = null;

286
node_modules/googleapis/lib/requests.js generated vendored Normal file
View File

@ -0,0 +1,286 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var util = require('util');
var querystring = require('querystring');
var DefaultTransporter = require('./transporters.js');
function BaseRequest(apiMeta) {
this.transporter = new DefaultTransporter();
this.authClient = null;
this.apiKey = null;
}
/**
* @const
* @type {String}
*/
BaseRequest.JSONRPC_VERSION = '2.0';
/**
* @const
* @type {String}
*/
BaseRequest.JSONRPC_URL = 'https://www.googleapis.com/rpc';
/**
* Sets the auth client.
* @param {AuthClient} client An auth client instance.
* @return {BaseRequest} Returns itself.
*/
BaseRequest.prototype.withAuthClient = function(client) {
this.authClient = client;
return this;
};
/**
* Sets an API key.
* @param {String} apiKey
* @return {BaseRequest} Returns itself.
*/
BaseRequest.prototype.withApiKey = function(apiKey) {
this.apiKey = apiKey;
return this;
};
/**
* Returns true if request requires a parameter.
* If no metadata is known about the request's method, true is returned.
* @return {boolean} Returns whether a parameter is required or not.
*/
BaseRequest.prototype.doesRequireParams = function() {
if (!this.apiMeta || !this.apiMeta.methods ||
!this.apiMeta.methods[this.methodName]) {
// nothing to do here, dont have enough
// info about the parameters
return true;
}
var methodMeta = this.apiMeta.methods[this.methodName];
for (var i in methodMeta.parameters) {
if (methodMeta.parameters[i].required) {
return true;
}
}
return false;
};
/**
* @protected
* Generates uri end-point with given params.
*
* @param {object=} opt_params Query parameters or null.
* @return {string} Generated uri.
*/
BaseRequest.prototype.generateUri = function(opt_params) {
var url = BaseRequest.JSONRPC_URL;
opt_params = opt_params || {};
if (this.apiKey) {
opt_params.key = this.apiKey;
}
var params = querystring.stringify(opt_params);
if (params) {
url += '?' + params;
}
return url;
};
/**
* @protected
* Generates payload body of the request.
* @return {object?} Request payload.
*/
BaseRequest.prototype.generatePayload = function() {
return null;
};
/**
* Executes the batch request.
*
* @param {Function=} opt_callback Optional callback function.
*/
BaseRequest.prototype.execute = function(opt_callback) {
// TODO(burcud): Switch to REST.
opt_callback = opt_callback || function() {};
var callback = this.handleResponse(opt_callback);
var requestOpts = {
method: 'POST',
uri: this.generateUri(),
json: this.generatePayload()
};
if (this.authClient) {
this.authClient.request(requestOpts, callback);
} else {
// make the request with default client
this.transporter.request(requestOpts, callback);
}
};
/**
* @protected
* Wraps request callbacks.
*
* @param {Function=} opt_fn Optional callback function to be wrapped.
* @return {Function} Wrapped callback function.
*/
BaseRequest.prototype.handleResponse = function(opt_fn) {
throw new Error('Not implemented...');
};
/**
* Constructs a new Request.
* @constructor
*
* @param {object} apiMeta Schema returned by Discovery API.
* @param {string} methodName Method name.
* @param {?object} opt_params Required Parameters. If none are required,
* expected to be not passed.
* @param {object=} opt_resource Optional resource.
*/
function Request(
apiMeta, methodName, opt_params, opt_resource) {
Request.super_.call(this);
this.apiMeta = apiMeta;
this.methodName = methodName;
if (!this.doesRequireParams() && !opt_resource) {
this.params = {};
this.resource = opt_params;
} else {
this.params = opt_params || {};
this.resource = opt_resource;
}
}
/**
* Inherits from BaseRequest.
*/
util.inherits(Request, BaseRequest);
/**
* Generates JSON-RPC payload with a single request.
* @return {Array.<object>} Returns request payload.
*/
Request.prototype.generatePayload = function() {
this.params.resource = this.resource;
console.dir(this.params);
var request = {
jsonrpc: BaseRequest.JSONRPC_VERSION,
id: 0,
method: this.methodName,
params: this.params,
apiVersion: this.apiMeta.version
};
return [request];
};
/**
* Handles response.
* @param {Function=} opt_fn Optional callback function.
* @return {Function} Wraps response callback and returns.
*/
Request.prototype.handleResponse = function(opt_fn) {
return function(err, results, res) {
var result = results && results[0] && results[0].result;
err = err && util.isArray(err) ? err[0] : err;
opt_fn && opt_fn(err, result, res);
};
};
/**
* Constructs a new batch request.
* @constructor
*/
function BatchRequest() {
BatchRequest.super_.call(this);
this.requests_ = [];
}
/**
* Inherits from BaseRequest.
*/
util.inherits(BatchRequest, BaseRequest);
/**
* Adds a request to the batch request.
* @param {Request} request A Request object to add to the batch.
*
* @return {BatchRequest} Returns itself.
*/
BatchRequest.prototype.add = function(request) {
this.requests_.push({
apiMeta: request.apiMeta,
method: request.methodName,
params: request.params,
resource: request.resource
});
return this;
};
/**
* @protected
* Generates JSON-RPC payload.
*
* @return {Array.<object>} Generated payload.
*/
BatchRequest.prototype.generatePayload = function() {
var payload = [];
for (var i = 0; i < this.requests_.length; i++) {
var request = this.requests_[i];
request.params.resource = request.resource;
payload.push({
jsonrpc: BaseRequest.JSONRPC_VERSION,
id: i,
method: request.method,
params: request.params,
apiVersion: request.apiMeta.version
});
}
return payload;
};
/**
* @protected
* Wraps request callbacks.
*
* @param {Function=} opt_fn Optional callback function to be wrapped.
* @return {Function} Wrapped callback function.
*/
BatchRequest.prototype.handleResponse = function(opt_fn) {
return function(err, body, res) {
var results = null;
if (body) {
results = [];
for (var i in body) {
results.push(body[i].result || null);
}
}
opt_fn && opt_fn(err, results, res);
};
};
/**
* Exports Request.
*/
exports.Request = Request;
/**
* Exports BatchRequest.
*/
exports.BatchRequest = BatchRequest;

90
node_modules/googleapis/lib/transporters.js generated vendored Normal file
View File

@ -0,0 +1,90 @@
/**
* Copyright 2012 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var request = require('request'),
pkg = require('../package.json');
/**
* Default transporter constructor.
* Wraps request and callback functions.
*/
function DefaultTransporter() {}
/**
* Default user agent.
*/
DefaultTransporter.prototype.USER_AGENT =
'google-api-nodejs-client/' + pkg.version;
/**
* Configures request options before making a request.
* @param {object} opts Options to configure.
* @return {object} Configured options.
*/
DefaultTransporter.prototype.configure = function(opts) {
// set transporter user agent
opts.headers = opts.headers || {};
opts.headers['User-Agent'] = opts.headers['User-Agent'] ?
opts.headers['User-Agent'] + ' ' + this.USER_AGENT : this.USER_AGENT;
return opts;
};
/**
* Makes a request with given options and invokes callback.
* @param {object} opts Options.
* @param {Function=} opt_callback Optional callback.
*/
DefaultTransporter.prototype.request = function(opts, opt_callback) {
opts = this.configure(opts);
request(opts, this.wrapCallback_(opt_callback));
};
/**
* @private
* Wraps the response callback.
* @param {Function=} opt_callback Optional callback.
* @return {Function} Wrapped callback function.
*/
DefaultTransporter.prototype.wrapCallback_ = function(opt_callback) {
return function(err, res, body) {
if (err || !body) {
opt_callback && opt_callback(err, null, res);
} else if (body && body.error) {
// handle single request errors
err = body.error;
delete body.error;
opt_callback(err, body, res);
} else {
// TODO(burcud): Logic not related to the means of transportation
// should be handled elsewhere.
var errors = null;
// iterate over objects to check if there are errors or not.
for (var i = 0; i < body.length; i++) {
if (body[i].error) {
errors = errors || [];
errors[i] = body[i].error;
delete body[i].error;
}
}
opt_callback && opt_callback(errors, body, res);
}
};
};
/**
* Exports DefaultTransporter.
*/
module.exports = DefaultTransporter;

19
node_modules/googleapis/node_modules/async/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2010 Caolan McMahon
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.

1365
node_modules/googleapis/node_modules/async/README.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

982
node_modules/googleapis/node_modules/async/lib/async.js generated vendored Executable file
View File

@ -0,0 +1,982 @@
/*global setImmediate: false, setTimeout: false, console: false */
(function () {
var async = {};
// global on the server, window in the browser
var root, previous_async;
root = this;
if (root != null) {
previous_async = root.async;
}
async.noConflict = function () {
root.async = previous_async;
return async;
};
function only_once(fn) {
var called = false;
return function() {
if (called) throw new Error("Callback was already called.");
called = true;
fn.apply(root, arguments);
}
}
//// cross-browser compatiblity functions ////
var _each = function (arr, iterator) {
if (arr.forEach) {
return arr.forEach(iterator);
}
for (var i = 0; i < arr.length; i += 1) {
iterator(arr[i], i, arr);
}
};
var _map = function (arr, iterator) {
if (arr.map) {
return arr.map(iterator);
}
var results = [];
_each(arr, function (x, i, a) {
results.push(iterator(x, i, a));
});
return results;
};
var _reduce = function (arr, iterator, memo) {
if (arr.reduce) {
return arr.reduce(iterator, memo);
}
_each(arr, function (x, i, a) {
memo = iterator(memo, x, i, a);
});
return memo;
};
var _keys = function (obj) {
if (Object.keys) {
return Object.keys(obj);
}
var keys = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
keys.push(k);
}
}
return keys;
};
//// exported async module functions ////
//// nextTick implementation with browser-compatible fallback ////
if (typeof process === 'undefined' || !(process.nextTick)) {
if (typeof setImmediate === 'function') {
async.nextTick = function (fn) {
setImmediate(fn);
};
}
else {
async.nextTick = function (fn) {
setTimeout(fn, 0);
};
}
}
else {
async.nextTick = process.nextTick;
}
async.each = function (arr, iterator, callback) {
callback = callback || function () {};
if (!arr.length) {
return callback();
}
var completed = 0;
_each(arr, function (x) {
iterator(x, only_once(function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed >= arr.length) {
callback(null);
}
}
}));
});
};
async.forEach = async.each;
async.eachSeries = function (arr, iterator, callback) {
callback = callback || function () {};
if (!arr.length) {
return callback();
}
var completed = 0;
var iterate = function () {
var sync = true;
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed >= arr.length) {
callback(null);
}
else {
if (sync) {
async.nextTick(iterate);
}
else {
iterate();
}
}
}
});
sync = false;
};
iterate();
};
async.forEachSeries = async.eachSeries;
async.eachLimit = function (arr, limit, iterator, callback) {
var fn = _eachLimit(limit);
fn.apply(null, [arr, iterator, callback]);
};
async.forEachLimit = async.eachLimit;
var _eachLimit = function (limit) {
return function (arr, iterator, callback) {
callback = callback || function () {};
if (!arr.length || limit <= 0) {
return callback();
}
var completed = 0;
var started = 0;
var running = 0;
(function replenish () {
if (completed >= arr.length) {
return callback();
}
while (running < limit && started < arr.length) {
started += 1;
running += 1;
iterator(arr[started - 1], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
running -= 1;
if (completed >= arr.length) {
callback();
}
else {
replenish();
}
}
});
}
})();
};
};
var doParallel = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.each].concat(args));
};
};
var doParallelLimit = function(limit, fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [_eachLimit(limit)].concat(args));
};
};
var doSeries = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.eachSeries].concat(args));
};
};
var _asyncMap = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (err, v) {
results[x.index] = v;
callback(err);
});
}, function (err) {
callback(err, results);
});
};
async.map = doParallel(_asyncMap);
async.mapSeries = doSeries(_asyncMap);
async.mapLimit = function (arr, limit, iterator, callback) {
return _mapLimit(limit)(arr, iterator, callback);
};
var _mapLimit = function(limit) {
return doParallelLimit(limit, _asyncMap);
};
// reduce only has a series version, as doing reduce in parallel won't
// work in many situations.
async.reduce = function (arr, memo, iterator, callback) {
async.eachSeries(arr, function (x, callback) {
iterator(memo, x, function (err, v) {
memo = v;
callback(err);
});
}, function (err) {
callback(err, memo);
});
};
// inject alias
async.inject = async.reduce;
// foldl alias
async.foldl = async.reduce;
async.reduceRight = function (arr, memo, iterator, callback) {
var reversed = _map(arr, function (x) {
return x;
}).reverse();
async.reduce(reversed, memo, iterator, callback);
};
// foldr alias
async.foldr = async.reduceRight;
var _filter = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.filter = doParallel(_filter);
async.filterSeries = doSeries(_filter);
// select alias
async.select = async.filter;
async.selectSeries = async.filterSeries;
var _reject = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (!v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.reject = doParallel(_reject);
async.rejectSeries = doSeries(_reject);
var _detect = function (eachfn, arr, iterator, main_callback) {
eachfn(arr, function (x, callback) {
iterator(x, function (result) {
if (result) {
main_callback(x);
main_callback = function () {};
}
else {
callback();
}
});
}, function (err) {
main_callback();
});
};
async.detect = doParallel(_detect);
async.detectSeries = doSeries(_detect);
async.some = function (arr, iterator, main_callback) {
async.each(arr, function (x, callback) {
iterator(x, function (v) {
if (v) {
main_callback(true);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(false);
});
};
// any alias
async.any = async.some;
async.every = function (arr, iterator, main_callback) {
async.each(arr, function (x, callback) {
iterator(x, function (v) {
if (!v) {
main_callback(false);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(true);
});
};
// all alias
async.all = async.every;
async.sortBy = function (arr, iterator, callback) {
async.map(arr, function (x, callback) {
iterator(x, function (err, criteria) {
if (err) {
callback(err);
}
else {
callback(null, {value: x, criteria: criteria});
}
});
}, function (err, results) {
if (err) {
return callback(err);
}
else {
var fn = function (left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
};
callback(null, _map(results.sort(fn), function (x) {
return x.value;
}));
}
});
};
async.auto = function (tasks, callback) {
callback = callback || function () {};
var keys = _keys(tasks);
if (!keys.length) {
return callback(null);
}
var results = {};
var listeners = [];
var addListener = function (fn) {
listeners.unshift(fn);
};
var removeListener = function (fn) {
for (var i = 0; i < listeners.length; i += 1) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
return;
}
}
};
var taskComplete = function () {
_each(listeners.slice(0), function (fn) {
fn();
});
};
addListener(function () {
if (_keys(results).length === keys.length) {
callback(null, results);
callback = function () {};
}
});
_each(keys, function (k) {
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
var taskCallback = function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
if (err) {
var safeResults = {};
_each(_keys(results), function(rkey) {
safeResults[rkey] = results[rkey];
});
safeResults[k] = args;
callback(err, safeResults);
// stop subsequent errors hitting callback multiple times
callback = function () {};
}
else {
results[k] = args;
async.nextTick(taskComplete);
}
};
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
var ready = function () {
return _reduce(requires, function (a, x) {
return (a && results.hasOwnProperty(x));
}, true) && !results.hasOwnProperty(k);
};
if (ready()) {
task[task.length - 1](taskCallback, results);
}
else {
var listener = function () {
if (ready()) {
removeListener(listener);
task[task.length - 1](taskCallback, results);
}
};
addListener(listener);
}
});
};
async.waterfall = function (tasks, callback) {
callback = callback || function () {};
if (!tasks.length) {
return callback();
}
var wrapIterator = function (iterator) {
return function (err) {
if (err) {
callback.apply(null, arguments);
callback = function () {};
}
else {
var args = Array.prototype.slice.call(arguments, 1);
var next = iterator.next();
if (next) {
args.push(wrapIterator(next));
}
else {
args.push(callback);
}
async.nextTick(function () {
iterator.apply(null, args);
});
}
};
};
wrapIterator(async.iterator(tasks))();
};
var _parallel = function(eachfn, tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
eachfn.map(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
eachfn.each(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.parallel = function (tasks, callback) {
_parallel({ map: async.map, each: async.each }, tasks, callback);
};
async.parallelLimit = function(tasks, limit, callback) {
_parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
};
async.series = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.mapSeries(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
async.eachSeries(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.iterator = function (tasks) {
var makeCallback = function (index) {
var fn = function () {
if (tasks.length) {
tasks[index].apply(null, arguments);
}
return fn.next();
};
fn.next = function () {
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
};
return fn;
};
return makeCallback(0);
};
async.apply = function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
return fn.apply(
null, args.concat(Array.prototype.slice.call(arguments))
);
};
};
var _concat = function (eachfn, arr, fn, callback) {
var r = [];
eachfn(arr, function (x, cb) {
fn(x, function (err, y) {
r = r.concat(y || []);
cb(err);
});
}, function (err) {
callback(err, r);
});
};
async.concat = doParallel(_concat);
async.concatSeries = doSeries(_concat);
async.whilst = function (test, iterator, callback) {
if (test()) {
var sync = true;
iterator(function (err) {
if (err) {
return callback(err);
}
if (sync) {
async.nextTick(function () {
async.whilst(test, iterator, callback);
});
}
else {
async.whilst(test, iterator, callback);
}
});
sync = false;
}
else {
callback();
}
};
async.doWhilst = function (iterator, test, callback) {
var sync = true;
iterator(function (err) {
if (err) {
return callback(err);
}
if (test()) {
if (sync) {
async.nextTick(function () {
async.doWhilst(iterator, test, callback);
});
}
else {
async.doWhilst(iterator, test, callback);
}
}
else {
callback();
}
});
sync = false;
};
async.until = function (test, iterator, callback) {
if (!test()) {
var sync = true;
iterator(function (err) {
if (err) {
return callback(err);
}
if (sync) {
async.nextTick(function () {
async.until(test, iterator, callback);
});
}
else {
async.until(test, iterator, callback);
}
});
sync = false;
}
else {
callback();
}
};
async.doUntil = function (iterator, test, callback) {
var sync = true;
iterator(function (err) {
if (err) {
return callback(err);
}
if (!test()) {
if (sync) {
async.nextTick(function () {
async.doUntil(iterator, test, callback);
});
}
else {
async.doUntil(iterator, test, callback);
}
}
else {
callback();
}
});
sync = false;
};
async.queue = function (worker, concurrency) {
if (concurrency === undefined) {
concurrency = 1;
}
function _insert(q, data, pos, callback) {
if(data.constructor !== Array) {
data = [data];
}
_each(data, function(task) {
var item = {
data: task,
callback: typeof callback === 'function' ? callback : null
};
if (pos) {
q.tasks.unshift(item);
} else {
q.tasks.push(item);
}
if (q.saturated && q.tasks.length === concurrency) {
q.saturated();
}
async.nextTick(q.process);
});
}
var workers = 0;
var q = {
tasks: [],
concurrency: concurrency,
saturated: null,
empty: null,
drain: null,
push: function (data, callback) {
_insert(q, data, false, callback);
},
unshift: function (data, callback) {
_insert(q, data, true, callback);
},
process: function () {
if (workers < q.concurrency && q.tasks.length) {
var task = q.tasks.shift();
if (q.empty && q.tasks.length === 0) {
q.empty();
}
workers += 1;
var sync = true;
var next = function () {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if (q.drain && q.tasks.length + workers === 0) {
q.drain();
}
q.process();
};
var cb = only_once(function () {
var cbArgs = arguments;
if (sync) {
async.nextTick(function () {
next.apply(null, cbArgs);
});
} else {
next.apply(null, arguments);
}
});
worker(task.data, cb);
sync = false;
}
},
length: function () {
return q.tasks.length;
},
running: function () {
return workers;
}
};
return q;
};
async.cargo = function (worker, payload) {
var working = false,
tasks = [];
var cargo = {
tasks: tasks,
payload: payload,
saturated: null,
empty: null,
drain: null,
push: function (data, callback) {
if(data.constructor !== Array) {
data = [data];
}
_each(data, function(task) {
tasks.push({
data: task,
callback: typeof callback === 'function' ? callback : null
});
if (cargo.saturated && tasks.length === payload) {
cargo.saturated();
}
});
async.nextTick(cargo.process);
},
process: function process() {
if (working) return;
if (tasks.length === 0) {
if(cargo.drain) cargo.drain();
return;
}
var ts = typeof payload === 'number'
? tasks.splice(0, payload)
: tasks.splice(0);
var ds = _map(ts, function (task) {
return task.data;
});
if(cargo.empty) cargo.empty();
working = true;
worker(ds, function () {
working = false;
var args = arguments;
_each(ts, function (data) {
if (data.callback) {
data.callback.apply(null, args);
}
});
process();
});
},
length: function () {
return tasks.length;
},
running: function () {
return working;
}
};
return cargo;
};
var _console_fn = function (name) {
return function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
fn.apply(null, args.concat([function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (typeof console !== 'undefined') {
if (err) {
if (console.error) {
console.error(err);
}
}
else if (console[name]) {
_each(args, function (x) {
console[name](x);
});
}
}
}]));
};
};
async.log = _console_fn('log');
async.dir = _console_fn('dir');
/*async.info = _console_fn('info');
async.warn = _console_fn('warn');
async.error = _console_fn('error');*/
async.memoize = function (fn, hasher) {
var memo = {};
var queues = {};
hasher = hasher || function (x) {
return x;
};
var memoized = function () {
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
var key = hasher.apply(null, args);
if (key in memo) {
callback.apply(null, memo[key]);
}
else if (key in queues) {
queues[key].push(callback);
}
else {
queues[key] = [callback];
fn.apply(null, args.concat([function () {
memo[key] = arguments;
var q = queues[key];
delete queues[key];
for (var i = 0, l = q.length; i < l; i++) {
q[i].apply(null, arguments);
}
}]));
}
};
memoized.memo = memo;
memoized.unmemoized = fn;
return memoized;
};
async.unmemoize = function (fn) {
return function () {
return (fn.unmemoized || fn).apply(null, arguments);
};
};
async.times = function (count, iterator, callback) {
var counter = [];
for (var i = 0; i < count; i++) {
counter.push(i);
}
return async.map(counter, iterator, callback);
};
async.timesSeries = function (count, iterator, callback) {
var counter = [];
for (var i = 0; i < count; i++) {
counter.push(i);
}
return async.mapSeries(counter, iterator, callback);
};
async.compose = function (/* functions... */) {
var fns = Array.prototype.reverse.call(arguments);
return function () {
var that = this;
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
async.reduce(fns, args, function (newargs, fn, cb) {
fn.apply(that, newargs.concat([function () {
var err = arguments[0];
var nextargs = Array.prototype.slice.call(arguments, 1);
cb(err, nextargs);
}]))
},
function (err, results) {
callback.apply(that, [err].concat(results));
});
};
};
async.applyEach = function (fns /*args...*/) {
var go = function () {
var that = this;
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
return async.each(fns, function (fn, cb) {
fn.apply(that, args.concat([cb]));
},
callback);
};
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
return go.apply(this, args);
}
else {
return go;
}
};
// AMD / RequireJS
if (typeof define !== 'undefined' && define.amd) {
define([], function () {
return async;
});
}
// Node.js
else if (typeof module !== 'undefined' && module.exports) {
module.exports = async;
}
// included directly via <script> tag
else {
root.async = async;
}
}());

File diff suppressed because one or more lines are too long

55
node_modules/googleapis/node_modules/request/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

331
node_modules/googleapis/node_modules/request/README.md generated vendored Normal file
View File

@ -0,0 +1,331 @@
# Request -- Simplified HTTP request method
## Install
<pre>
npm install request
</pre>
Or from source:
<pre>
git clone git://github.com/mikeal/request.git
cd request
npm link
</pre>
## Super simple to use
Request is designed to be the simplest way possible to make http calls. It supports HTTPS and follows redirects by default.
```javascript
var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the google web page.
}
})
```
## Streaming
You can stream any response to a file stream.
```javascript
request('http://google.com/doodle.png').pipe(fs.createWriteStream('doodle.png'))
```
You can also stream a file to a PUT or POST request. This method will also check the file extension against a mapping of file extensions to content-types, in this case `application/json`, and use the proper content-type in the PUT request if one is not already provided in the headers.
```javascript
fs.createReadStream('file.json').pipe(request.put('http://mysite.com/obj.json'))
```
Request can also pipe to itself. When doing so the content-type and content-length will be preserved in the PUT headers.
```javascript
request.get('http://google.com/img.png').pipe(request.put('http://mysite.com/img.png'))
```
Now let's get fancy.
```javascript
http.createServer(function (req, resp) {
if (req.url === '/doodle.png') {
if (req.method === 'PUT') {
req.pipe(request.put('http://mysite.com/doodle.png'))
} else if (req.method === 'GET' || req.method === 'HEAD') {
request.get('http://mysite.com/doodle.png').pipe(resp)
}
}
})
```
You can also pipe() from a http.ServerRequest instance and to a http.ServerResponse instance. The HTTP method and headers will be sent as well as the entity-body data. Which means that, if you don't really care about security, you can do:
```javascript
http.createServer(function (req, resp) {
if (req.url === '/doodle.png') {
var x = request('http://mysite.com/doodle.png')
req.pipe(x)
x.pipe(resp)
}
})
```
And since pipe() returns the destination stream in node 0.5.x you can do one line proxying :)
```javascript
req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)
```
Also, none of this new functionality conflicts with requests previous features, it just expands them.
```javascript
var r = request.defaults({'proxy':'http://localproxy.com'})
http.createServer(function (req, resp) {
if (req.url === '/doodle.png') {
r.get('http://google.com/doodle.png').pipe(resp)
}
})
```
You can still use intermediate proxies, the requests will still follow HTTP forwards, etc.
## Forms
`request` supports `application/x-www-form-urlencoded` and `multipart/form-data` form uploads. For `multipart/related` refer to the `multipart` API.
Url encoded forms are simple
```javascript
request.post('http://service.com/upload', {form:{key:'value'}})
// or
request.post('http://service.com/upload').form({key:'value'})
```
For `multipart/form-data` we use the [form-data](https://github.com/felixge/node-form-data) library by [@felixge](https://github.com/felixge). You don't need to worry about piping the form object or setting the headers, `request` will handle that for you.
```javascript
var r = request.post('http://service.com/upload')
var form = r.form()
form.append('my_field', 'my_value')
form.append('my_buffer', new Buffer([1, 2, 3]))
form.append('my_file', fs.createReadStream(path.join(__dirname, 'doodle.png'))
form.append('remote_file', request('http://google.com/doodle.png'))
```
## HTTP Authentication
```javascript
request.auth('username', 'password', false).get('http://some.server.com/');
// or
request.get('http://some.server.com/', {
'auth': {
'user': 'username',
'pass': 'password',
'sendImmediately': false
}
});
```
If passed as an option, `auth` should be a hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). The method form takes parameters `auth(username, password, sendImmediately)`.
`sendImmediately` defaults to true, which will cause a basic authentication header to be sent. If `sendImmediately` is `false`, then `request` will retry with a proper authentication header after receiving a 401 response from the server (which must contain a `WWW-Authenticate` header indicating the required authentication method).
Digest authentication is supported, but it only works with `sendImmediately` set to `false` (otherwise `request` will send basic authentication on the initial request, which will probably cause the request to fail).
## OAuth Signing
```javascript
// Twitter OAuth
var qs = require('querystring')
, oauth =
{ callback: 'http://mysite.com/callback/'
, consumer_key: CONSUMER_KEY
, consumer_secret: CONSUMER_SECRET
}
, url = 'https://api.twitter.com/oauth/request_token'
;
request.post({url:url, oauth:oauth}, function (e, r, body) {
// Assume by some stretch of magic you aquired the verifier
var access_token = qs.parse(body)
, oauth =
{ consumer_key: CONSUMER_KEY
, consumer_secret: CONSUMER_SECRET
, token: access_token.oauth_token
, verifier: VERIFIER
, token_secret: access_token.oauth_token_secret
}
, url = 'https://api.twitter.com/oauth/access_token'
;
request.post({url:url, oauth:oauth}, function (e, r, body) {
var perm_token = qs.parse(body)
, oauth =
{ consumer_key: CONSUMER_KEY
, consumer_secret: CONSUMER_SECRET
, token: perm_token.oauth_token
, token_secret: perm_token.oauth_token_secret
}
, url = 'https://api.twitter.com/1/users/show.json?'
, params =
{ screen_name: perm_token.screen_name
, user_id: perm_token.user_id
}
;
url += qs.stringify(params)
request.get({url:url, oauth:oauth, json:true}, function (e, r, user) {
console.log(user)
})
})
})
```
### request(options, callback)
The first argument can be either a url or an options object. The only required option is uri, all others are optional.
* `uri` || `url` - fully qualified uri or a parsed url object from url.parse()
* `qs` - object containing querystring values to be appended to the uri
* `method` - http method, defaults to GET
* `headers` - http headers, defaults to {}
* `body` - entity body for POST and PUT requests. Must be buffer or string.
* `form` - when passed an object this will set `body` but to a querystring representation of value and adds `Content-type: application/x-www-form-urlencoded; charset=utf-8` header. When passed no option a FormData instance is returned that will be piped to request.
* `auth` - A hash containing values `user` || `username`, `password` || `pass`, and `sendImmediately` (optional). See documentation above.
* `json` - sets `body` but to JSON representation of value and adds `Content-type: application/json` header. Additionally, parses the response body as json.
* `multipart` - (experimental) array of objects which contains their own headers and `body` attribute. Sends `multipart/related` request. See example below.
* `followRedirect` - follow HTTP 3xx responses as redirects. defaults to true.
* `followAllRedirects` - follow non-GET HTTP 3xx responses as redirects. defaults to false.
* `maxRedirects` - the maximum number of redirects to follow, defaults to 10.
* `encoding` - Encoding to be used on `setEncoding` of response data. If set to `null`, the body is returned as a Buffer.
* `pool` - A hash object containing the agents for these requests. If omitted this request will use the global pool which is set to node's default maxSockets.
* `pool.maxSockets` - Integer containing the maximum amount of sockets in the pool.
* `timeout` - Integer containing the number of milliseconds to wait for a request to respond before aborting the request
* `proxy` - An HTTP proxy to be used. Support proxy Auth with Basic Auth the same way it's supported with the `url` parameter by embedding the auth info in the uri.
* `oauth` - Options for OAuth HMAC-SHA1 signing, see documentation above.
* `strictSSL` - Set to `true` to require that SSL certificates be valid. Note: to use your own certificate authority, you need to specify an agent that was created with that ca as an option.
* `jar` - Set to `false` if you don't want cookies to be remembered for future use or define your custom cookie jar (see examples section)
* `aws` - object containing aws signing information, should have the properties `key` and `secret` as well as `bucket` unless you're specifying your bucket as part of the path, or you are making a request that doesn't use a bucket (i.e. GET Services)
The callback argument gets 3 arguments. The first is an error when applicable (usually from the http.Client option not the http.ClientRequest object). The second in an http.ClientResponse object. The third is the response body String or Buffer.
## Convenience methods
There are also shorthand methods for different HTTP METHODs and some other conveniences.
### request.defaults(options)
This method returns a wrapper around the normal request API that defaults to whatever options you pass in to it.
### request.put
Same as request() but defaults to `method: "PUT"`.
```javascript
request.put(url)
```
### request.post
Same as request() but defaults to `method: "POST"`.
```javascript
request.post(url)
```
### request.head
Same as request() but defaults to `method: "HEAD"`.
```javascript
request.head(url)
```
### request.del
Same as request() but defaults to `method: "DELETE"`.
```javascript
request.del(url)
```
### request.get
Alias to normal request method for uniformity.
```javascript
request.get(url)
```
### request.cookie
Function that creates a new cookie.
```javascript
request.cookie('cookie_string_here')
```
### request.jar
Function that creates a new cookie jar.
```javascript
request.jar()
```
## Examples:
```javascript
var request = require('request')
, rand = Math.floor(Math.random()*100000000).toString()
;
request(
{ method: 'PUT'
, uri: 'http://mikeal.iriscouch.com/testjs/' + rand
, multipart:
[ { 'content-type': 'application/json'
, body: JSON.stringify({foo: 'bar', _attachments: {'message.txt': {follows: true, length: 18, 'content_type': 'text/plain' }}})
}
, { body: 'I am an attachment' }
]
}
, function (error, response, body) {
if(response.statusCode == 201){
console.log('document saved as: http://mikeal.iriscouch.com/testjs/'+ rand)
} else {
console.log('error: '+ response.statusCode)
console.log(body)
}
}
)
```
Cookies are enabled by default (so they can be used in subsequent requests). To disable cookies set jar to false (either in defaults or in the options sent).
```javascript
var request = request.defaults({jar: false})
request('http://www.google.com', function () {
request('http://images.google.com')
})
```
If you to use a custom cookie jar (instead of letting request use its own global cookie jar) you do so by setting the jar default or by specifying it as an option:
```javascript
var j = request.jar()
var request = request.defaults({jar:j})
request('http://www.google.com', function () {
request('http://images.google.com')
})
```
OR
```javascript
var j = request.jar()
var cookie = request.cookie('your_cookie_here')
j.add(cookie)
request({url: 'http://www.google.com', jar: j}, function () {
request('http://images.google.com')
})
```

191
node_modules/googleapis/node_modules/request/aws.js generated vendored Normal file
View File

@ -0,0 +1,191 @@
/*!
* knox - auth
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
* MIT Licensed
*/
/**
* 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
*/
exports.authorization = function(options){
return 'AWS ' + options.key + ':' + exports.sign(options)
}
/**
* Simple HMAC-SHA1 Wrapper
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.hmacSha1 = function(options){
return crypto.createHmac('sha1', options.secret).update(options.message).digest('base64')
}
/**
* Create a base64 sha1 HMAC for `options`.
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.sign = function(options){
options.message = exports.stringToSign(options)
return exports.hmacSha1(options)
}
/**
* Create a base64 sha1 HMAC for `options`.
*
* Specifically to be used with S3 presigned URLs
*
* @param {Object} options
* @return {String}
* @api private
*/
exports.signQuery = function(options){
options.message = exports.queryStringToSign(options)
return exports.hmacSha1(options)
}
/**
* 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
*/
exports.stringToSign = function(options){
var headers = options.amazonHeaders || ''
if (headers) headers += '\n'
var r =
[ options.verb
, options.md5
, options.contentType
, options.date.toUTCString()
, headers + options.resource
]
return r.join('\n')
}
/**
* 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
*/
exports.queryStringToSign = function(options){
return 'GET\n\n\n' + options.date + '\n' + options.resource
};
/**
* Perform the following:
*
* - ignore non-amazon headers
* - lowercase fields
* - sort lexicographically
* - trim whitespace between ":"
* - join with newline
*
* @param {Object} headers
* @return {String}
* @api private
*/
exports.canonicalizeHeaders = function(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')
};
/**
* Perform the following:
*
* - ignore non sub-resources
* - sort lexicographically
*
* @param {String} resource
* @return {String}
* @api private
*/
exports.canonicalizeResource = function(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('&') : '')
};

103
node_modules/googleapis/node_modules/request/forever.js generated vendored Normal file
View File

@ -0,0 +1,103 @@
module.exports = ForeverAgent
ForeverAgent.SSL = ForeverAgentSSL
var util = require('util')
, Agent = require('http').Agent
, net = require('net')
, tls = require('tls')
, AgentSSL = require('https').Agent
function ForeverAgent(options) {
var self = this
self.options = options || {}
self.requests = {}
self.sockets = {}
self.freeSockets = {}
self.maxSockets = self.options.maxSockets || Agent.defaultMaxSockets
self.minSockets = self.options.minSockets || ForeverAgent.defaultMinSockets
self.on('free', function(socket, host, port) {
var name = host + ':' + port
if (self.requests[name] && self.requests[name].length) {
self.requests[name].shift().onSocket(socket)
} else if (self.sockets[name].length < self.minSockets) {
if (!self.freeSockets[name]) self.freeSockets[name] = []
self.freeSockets[name].push(socket)
// if an error happens while we don't use the socket anyway, meh, throw the socket away
function onIdleError() {
socket.destroy()
}
socket._onIdleError = onIdleError
socket.on('error', onIdleError)
} else {
// If there are no pending requests just destroy the
// socket and it will get removed from the pool. This
// gets us out of timeout issues and allows us to
// default to Connection:keep-alive.
socket.destroy()
}
})
}
util.inherits(ForeverAgent, Agent)
ForeverAgent.defaultMinSockets = 5
ForeverAgent.prototype.createConnection = net.createConnection
ForeverAgent.prototype.addRequestNoreuse = Agent.prototype.addRequest
ForeverAgent.prototype.addRequest = function(req, host, port) {
var name = host + ':' + port
if (this.freeSockets[name] && this.freeSockets[name].length > 0 && !req.useChunkedEncodingByDefault) {
var idleSocket = this.freeSockets[name].pop()
idleSocket.removeListener('error', idleSocket._onIdleError)
delete idleSocket._onIdleError
req._reusedSocket = true
req.onSocket(idleSocket)
} else {
this.addRequestNoreuse(req, host, port)
}
}
ForeverAgent.prototype.removeSocket = function(s, name, host, port) {
if (this.sockets[name]) {
var index = this.sockets[name].indexOf(s)
if (index !== -1) {
this.sockets[name].splice(index, 1)
}
} else if (this.sockets[name] && this.sockets[name].length === 0) {
// don't leak
delete this.sockets[name]
delete this.requests[name]
}
if (this.freeSockets[name]) {
var index = this.freeSockets[name].indexOf(s)
if (index !== -1) {
this.freeSockets[name].splice(index, 1)
if (this.freeSockets[name].length === 0) {
delete this.freeSockets[name]
}
}
}
if (this.requests[name] && this.requests[name].length) {
// If we have pending requests and a socket gets closed a new one
// needs to be created to take over in the pool for the one that closed.
this.createSocket(name, host, port).emit('free')
}
}
function ForeverAgentSSL (options) {
ForeverAgent.call(this, options)
}
util.inherits(ForeverAgentSSL, ForeverAgent)
ForeverAgentSSL.prototype.createConnection = createConnectionSSL
ForeverAgentSSL.prototype.addRequestNoreuse = AgentSSL.prototype.addRequest
function createConnectionSSL (port, host, options) {
options.port = port
options.host = host
return tls.connect(options)
}

1245
node_modules/googleapis/node_modules/request/main.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
*.un~
/node_modules/*
/test/tmp
/.idea
*.iml

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.

View File

@ -0,0 +1,7 @@
SHELL := /bin/bash
test:
@./test/run.js
.PHONY: test

View File

@ -0,0 +1,118 @@
# form-data
A module to create readable `"multipart/form-data"` streams. Can be used to
submit forms and file uploads to other web applications.
The API of this module 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
## Install
Sorry, this isn't ready for you yet.
## 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 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, 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');
});
```
For edge cases, like POST request to URL with query string or to pass HTTP auth creadentials, 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);
});
```
[xhr2-fd]: http://dev.w3.org/2006/webapi/XMLHttpRequest-2/Overview.html#the-formdata-interface

View File

@ -0,0 +1,291 @@
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');
var async = require('async');
module.exports = FormData;
function FormData() {
this._overheadLength = 0;
this._valueLength = 0;
this._lengthRetrievers = [];
CombinedStream.call(this);
}
util.inherits(FormData, CombinedStream);
FormData.LINE_BREAK = '\r\n';
FormData.prototype.append = function(field, value, options) {
options = options || {};
var append = CombinedStream.prototype.append.bind(this);
// all that streamy business can't handle numbers
if (typeof value == 'number') value = ''+value;
var header = this._multiPartHeader(field, value, options);
var footer = this._multiPartFooter(field, value, options);
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/ trackLengthSync(), 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;
}
this._lengthRetrievers.push(function(next) {
// do we already know the size?
// 0 additional leaves value from getSyncLength()
if (options.knownLength != null) {
next(null, 0);
// check if it's local file
} else if (value.hasOwnProperty('fd')) {
fs.stat(value.path, function(err, stat) {
if (err) {
next(err);
return;
}
next(null, stat.size);
});
// 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) {
var boundary = this.getBoundary();
var header = '';
// custom header specified (as string)?
// it becomes responsible for boundary
// (e.g. to handle extra CRLFs on .NET servers)
if (options.header != null) {
header = options.header;
} else {
header += '--' + boundary + FormData.LINE_BREAK +
'Content-Disposition: form-data; name="' + field + '"';
// fs- and request- streams have path property
// TODO: Use request's response mime-type
if (value.path) {
header +=
'; filename="' + path.basename(value.path) + '"' + FormData.LINE_BREAK +
'Content-Type: ' + mime.lookup(value.path);
// http response has not
} else if (value.readable && value.hasOwnProperty('httpVersion')) {
header +=
'; filename="' + path.basename(value.client._httpMessage.path) + '"' + FormData.LINE_BREAK +
'Content-Type: ' + value.headers['content-type'];
}
header += FormData.LINE_BREAK + FormData.LINE_BREAK;
}
return header;
};
FormData.prototype._multiPartFooter = function(field, value, options) {
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.prototype.getHeaders = function(userHeaders) {
var formHeaders = {
'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
};
for (var header in userHeaders) {
formHeaders[header.toLowerCase()] = userHeaders[header];
}
return formHeaders;
}
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;
};
FormData.prototype.getLengthSync = function() {
var knownLength = this._overheadLength + this._valueLength;
if (this._streams.length) {
knownLength += this._lastBoundary().length;
}
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) {
this.getLength(function(err, length) {
var request
, options
, defaults = {
method : 'post',
port : 80,
headers: this.getHeaders({'Content-Length': length})
};
// 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);
}
else // use custom params
{
options = populate(params, defaults);
}
// https if specified, fallback to http in any other case
if (params.protocol == 'https:') {
// override default port
if (!params.port) options.port = 443;
request = https.request(options);
} else {
request = http.request(options);
}
this.pipe(request);
if (cb) {
request.on('error', cb);
request.on('response', cb.bind(this, null));
}
return request;
}.bind(this));
};
/*
* Santa's little helpers
*/
// populates missing values
function populate(dst, src) {
for (var prop in src) {
if (!dst[prop]) dst[prop] = src[prop];
}
return dst;
}

View File

@ -0,0 +1,9 @@
[submodule "deps/nodeunit"]
path = deps/nodeunit
url = git://github.com/caolan/nodeunit.git
[submodule "deps/UglifyJS"]
path = deps/UglifyJS
url = https://github.com/mishoo/UglifyJS.git
[submodule "deps/nodelint"]
path = deps/nodelint
url = https://github.com/tav/nodelint.git

View File

@ -0,0 +1,4 @@
deps
dist
test
nodelint.cfg

View File

@ -0,0 +1,19 @@
Copyright (c) 2010 Caolan McMahon
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,25 @@
PACKAGE = asyncjs
NODEJS = $(if $(shell test -f /usr/bin/nodejs && echo "true"),nodejs,node)
CWD := $(shell pwd)
NODEUNIT = $(CWD)/node_modules/nodeunit/bin/nodeunit
UGLIFY = $(CWD)/node_modules/uglify-js/bin/uglifyjs
NODELINT = $(CWD)/node_modules/nodelint/nodelint
BUILDDIR = dist
all: clean test build
build: $(wildcard lib/*.js)
mkdir -p $(BUILDDIR)
$(UGLIFY) lib/async.js > $(BUILDDIR)/async.min.js
test:
$(NODEUNIT) test
clean:
rm -rf $(BUILDDIR)
lint:
$(NODELINT) --config nodelint.cfg lib/async.js
.PHONY: test build all

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,3 @@
// This file is just added for convenience so this repository can be
// directly checked out into a project's deps folder
module.exports = require('./lib/async');

View File

@ -0,0 +1,692 @@
/*global setTimeout: false, console: false */
(function () {
var async = {};
// global on the server, window in the browser
var root = this,
previous_async = root.async;
if (typeof module !== 'undefined' && module.exports) {
module.exports = async;
}
else {
root.async = async;
}
async.noConflict = function () {
root.async = previous_async;
return async;
};
//// cross-browser compatiblity functions ////
var _forEach = function (arr, iterator) {
if (arr.forEach) {
return arr.forEach(iterator);
}
for (var i = 0; i < arr.length; i += 1) {
iterator(arr[i], i, arr);
}
};
var _map = function (arr, iterator) {
if (arr.map) {
return arr.map(iterator);
}
var results = [];
_forEach(arr, function (x, i, a) {
results.push(iterator(x, i, a));
});
return results;
};
var _reduce = function (arr, iterator, memo) {
if (arr.reduce) {
return arr.reduce(iterator, memo);
}
_forEach(arr, function (x, i, a) {
memo = iterator(memo, x, i, a);
});
return memo;
};
var _keys = function (obj) {
if (Object.keys) {
return Object.keys(obj);
}
var keys = [];
for (var k in obj) {
if (obj.hasOwnProperty(k)) {
keys.push(k);
}
}
return keys;
};
//// exported async module functions ////
//// nextTick implementation with browser-compatible fallback ////
if (typeof process === 'undefined' || !(process.nextTick)) {
async.nextTick = function (fn) {
setTimeout(fn, 0);
};
}
else {
async.nextTick = process.nextTick;
}
async.forEach = function (arr, iterator, callback) {
callback = callback || function () {};
if (!arr.length) {
return callback();
}
var completed = 0;
_forEach(arr, function (x) {
iterator(x, function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed === arr.length) {
callback(null);
}
}
});
});
};
async.forEachSeries = function (arr, iterator, callback) {
callback = callback || function () {};
if (!arr.length) {
return callback();
}
var completed = 0;
var iterate = function () {
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed === arr.length) {
callback(null);
}
else {
iterate();
}
}
});
};
iterate();
};
async.forEachLimit = function (arr, limit, iterator, callback) {
callback = callback || function () {};
if (!arr.length || limit <= 0) {
return callback();
}
var completed = 0;
var started = 0;
var running = 0;
(function replenish () {
if (completed === arr.length) {
return callback();
}
while (running < limit && started < arr.length) {
started += 1;
running += 1;
iterator(arr[started - 1], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
running -= 1;
if (completed === arr.length) {
callback();
}
else {
replenish();
}
}
});
}
})();
};
var doParallel = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.forEach].concat(args));
};
};
var doSeries = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [async.forEachSeries].concat(args));
};
};
var _asyncMap = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (err, v) {
results[x.index] = v;
callback(err);
});
}, function (err) {
callback(err, results);
});
};
async.map = doParallel(_asyncMap);
async.mapSeries = doSeries(_asyncMap);
// reduce only has a series version, as doing reduce in parallel won't
// work in many situations.
async.reduce = function (arr, memo, iterator, callback) {
async.forEachSeries(arr, function (x, callback) {
iterator(memo, x, function (err, v) {
memo = v;
callback(err);
});
}, function (err) {
callback(err, memo);
});
};
// inject alias
async.inject = async.reduce;
// foldl alias
async.foldl = async.reduce;
async.reduceRight = function (arr, memo, iterator, callback) {
var reversed = _map(arr, function (x) {
return x;
}).reverse();
async.reduce(reversed, memo, iterator, callback);
};
// foldr alias
async.foldr = async.reduceRight;
var _filter = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.filter = doParallel(_filter);
async.filterSeries = doSeries(_filter);
// select alias
async.select = async.filter;
async.selectSeries = async.filterSeries;
var _reject = function (eachfn, arr, iterator, callback) {
var results = [];
arr = _map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (!v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(_map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
async.reject = doParallel(_reject);
async.rejectSeries = doSeries(_reject);
var _detect = function (eachfn, arr, iterator, main_callback) {
eachfn(arr, function (x, callback) {
iterator(x, function (result) {
if (result) {
main_callback(x);
main_callback = function () {};
}
else {
callback();
}
});
}, function (err) {
main_callback();
});
};
async.detect = doParallel(_detect);
async.detectSeries = doSeries(_detect);
async.some = function (arr, iterator, main_callback) {
async.forEach(arr, function (x, callback) {
iterator(x, function (v) {
if (v) {
main_callback(true);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(false);
});
};
// any alias
async.any = async.some;
async.every = function (arr, iterator, main_callback) {
async.forEach(arr, function (x, callback) {
iterator(x, function (v) {
if (!v) {
main_callback(false);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(true);
});
};
// all alias
async.all = async.every;
async.sortBy = function (arr, iterator, callback) {
async.map(arr, function (x, callback) {
iterator(x, function (err, criteria) {
if (err) {
callback(err);
}
else {
callback(null, {value: x, criteria: criteria});
}
});
}, function (err, results) {
if (err) {
return callback(err);
}
else {
var fn = function (left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
};
callback(null, _map(results.sort(fn), function (x) {
return x.value;
}));
}
});
};
async.auto = function (tasks, callback) {
callback = callback || function () {};
var keys = _keys(tasks);
if (!keys.length) {
return callback(null);
}
var results = {};
var listeners = [];
var addListener = function (fn) {
listeners.unshift(fn);
};
var removeListener = function (fn) {
for (var i = 0; i < listeners.length; i += 1) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
return;
}
}
};
var taskComplete = function () {
_forEach(listeners.slice(0), function (fn) {
fn();
});
};
addListener(function () {
if (_keys(results).length === keys.length) {
callback(null, results);
callback = function () {};
}
});
_forEach(keys, function (k) {
var task = (tasks[k] instanceof Function) ? [tasks[k]]: tasks[k];
var taskCallback = function (err) {
if (err) {
callback(err);
// stop subsequent errors hitting callback multiple times
callback = function () {};
}
else {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
taskComplete();
}
};
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
var ready = function () {
return _reduce(requires, function (a, x) {
return (a && results.hasOwnProperty(x));
}, true) && !results.hasOwnProperty(k);
};
if (ready()) {
task[task.length - 1](taskCallback, results);
}
else {
var listener = function () {
if (ready()) {
removeListener(listener);
task[task.length - 1](taskCallback, results);
}
};
addListener(listener);
}
});
};
async.waterfall = function (tasks, callback) {
callback = callback || function () {};
if (!tasks.length) {
return callback();
}
var wrapIterator = function (iterator) {
return function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
var args = Array.prototype.slice.call(arguments, 1);
var next = iterator.next();
if (next) {
args.push(wrapIterator(next));
}
else {
args.push(callback);
}
async.nextTick(function () {
iterator.apply(null, args);
});
}
};
};
wrapIterator(async.iterator(tasks))();
};
async.parallel = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.map(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
async.forEach(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.series = function (tasks, callback) {
callback = callback || function () {};
if (tasks.constructor === Array) {
async.mapSeries(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
async.forEachSeries(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
async.iterator = function (tasks) {
var makeCallback = function (index) {
var fn = function () {
if (tasks.length) {
tasks[index].apply(null, arguments);
}
return fn.next();
};
fn.next = function () {
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
};
return fn;
};
return makeCallback(0);
};
async.apply = function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
return fn.apply(
null, args.concat(Array.prototype.slice.call(arguments))
);
};
};
var _concat = function (eachfn, arr, fn, callback) {
var r = [];
eachfn(arr, function (x, cb) {
fn(x, function (err, y) {
r = r.concat(y || []);
cb(err);
});
}, function (err) {
callback(err, r);
});
};
async.concat = doParallel(_concat);
async.concatSeries = doSeries(_concat);
async.whilst = function (test, iterator, callback) {
if (test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
async.whilst(test, iterator, callback);
});
}
else {
callback();
}
};
async.until = function (test, iterator, callback) {
if (!test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
async.until(test, iterator, callback);
});
}
else {
callback();
}
};
async.queue = function (worker, concurrency) {
var workers = 0;
var q = {
tasks: [],
concurrency: concurrency,
saturated: null,
empty: null,
drain: null,
push: function (data, callback) {
if(data.constructor !== Array) {
data = [data];
}
_forEach(data, function(task) {
q.tasks.push({
data: task,
callback: typeof callback === 'function' ? callback : null
});
if (q.saturated && q.tasks.length == concurrency) {
q.saturated();
}
async.nextTick(q.process);
});
},
process: function () {
if (workers < q.concurrency && q.tasks.length) {
var task = q.tasks.shift();
if(q.empty && q.tasks.length == 0) q.empty();
workers += 1;
worker(task.data, function () {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if(q.drain && q.tasks.length + workers == 0) q.drain();
q.process();
});
}
},
length: function () {
return q.tasks.length;
},
running: function () {
return workers;
}
};
return q;
};
var _console_fn = function (name) {
return function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
fn.apply(null, args.concat([function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (typeof console !== 'undefined') {
if (err) {
if (console.error) {
console.error(err);
}
}
else if (console[name]) {
_forEach(args, function (x) {
console[name](x);
});
}
}
}]));
};
};
async.log = _console_fn('log');
async.dir = _console_fn('dir');
/*async.info = _console_fn('info');
async.warn = _console_fn('warn');
async.error = _console_fn('error');*/
async.memoize = function (fn, hasher) {
var memo = {};
var queues = {};
hasher = hasher || function (x) {
return x;
};
var memoized = function () {
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
var key = hasher.apply(null, args);
if (key in memo) {
callback.apply(null, memo[key]);
}
else if (key in queues) {
queues[key].push(callback);
}
else {
queues[key] = [callback];
fn.apply(null, args.concat([function () {
memo[key] = arguments;
var q = queues[key];
delete queues[key];
for (var i = 0, l = q.length; i < l; i++) {
q[i].apply(null, arguments);
}
}]));
}
};
memoized.unmemoized = fn;
return memoized;
};
async.unmemoize = function (fn) {
return function () {
return (fn.unmemoized || fn).apply(null, arguments);
};
};
}());

View File

@ -0,0 +1,42 @@
{
"name": "async",
"description": "Higher-order functions and common patterns for asynchronous code",
"main": "./index",
"author": {
"name": "Caolan McMahon"
},
"version": "0.1.22",
"repository": {
"type": "git",
"url": "git://github.com/caolan/async.git"
},
"bugs": {
"url": "http://github.com/caolan/async/issues"
},
"licenses": [
{
"type": "MIT",
"url": "http://github.com/caolan/async/raw/master/LICENSE"
}
],
"devDependencies": {
"nodeunit": ">0.0.0",
"uglify-js": "1.2.x",
"nodelint": ">0.0.0"
},
"_npmUser": {
"name": "mikeal",
"email": "mikeal.rogers@gmail.com"
},
"_id": "async@0.1.22",
"dependencies": {},
"optionalDependencies": {},
"engines": {
"node": "*"
},
"_engineSupported": true,
"_npmVersion": "1.1.24",
"_nodeVersion": "v0.8.1",
"_defaultsLoaded": true,
"_from": "async@~0.1.9"
}

View File

@ -0,0 +1,3 @@
*.un~
/node_modules
/test/tmp

View File

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

View File

@ -0,0 +1,7 @@
SHELL := /bin/bash
test:
@./test/run.js
.PHONY: test

View File

@ -0,0 +1,132 @@
# combined-stream
A stream that emits multiple other streams one after another.
## Installation
``` bash
npm install combined-stream
```
## Usage
Here is a simple example that shows how you can use combined-stream to combine
two files into one:
``` javascript
var CombinedStream = require('combined-stream');
var fs = require('fs');
var combinedStream = CombinedStream.create();
combinedStream.append(fs.createReadStream('file1.txt'));
combinedStream.append(fs.createReadStream('file2.txt'));
combinedStream.pipe(fs.createWriteStream('combined.txt'));
```
While the example above works great, it will pause all source streams until
they are needed. If you don't want that to happen, you can set `pauseStreams`
to `false`:
``` javascript
var CombinedStream = require('combined-stream');
var fs = require('fs');
var combinedStream = CombinedStream.create({pauseStreams: false});
combinedStream.append(fs.createReadStream('file1.txt'));
combinedStream.append(fs.createReadStream('file2.txt'));
combinedStream.pipe(fs.createWriteStream('combined.txt'));
```
However, what if you don't have all the source streams yet, or you don't want
to allocate the resources (file descriptors, memory, etc.) for them right away?
Well, in that case you can simply provide a callback that supplies the stream
by calling a `next()` function:
``` javascript
var CombinedStream = require('combined-stream');
var fs = require('fs');
var combinedStream = CombinedStream.create();
combinedStream.append(function(next) {
next(fs.createReadStream('file1.txt'));
});
combinedStream.append(function(next) {
next(fs.createReadStream('file2.txt'));
});
combinedStream.pipe(fs.createWriteStream('combined.txt'));
```
## API
### CombinedStream.create([options])
Returns a new combined stream object. Available options are:
* `maxDataSize`
* `pauseStreams`
The effect of those options is described below.
### combinedStream.pauseStreams = true
Whether to apply back pressure to the underlaying streams. If set to `false`,
the underlaying streams will never be paused. If set to `true`, the
underlaying streams will be paused right after being appended, as well as when
`delayedStream.pipe()` wants to throttle.
### combinedStream.maxDataSize = 2 * 1024 * 1024
The maximum amount of bytes (or characters) to buffer for all source streams.
If this value is exceeded, `combinedStream` emits an `'error'` event.
### combinedStream.dataSize = 0
The amount of bytes (or characters) currently buffered by `combinedStream`.
### combinedStream.append(stream)
Appends the given `stream` to the combinedStream object. If `pauseStreams` is
set to `true, this stream will also be paused right away.
`streams` can also be a function that takes one parameter called `next`. `next`
is a function that must be invoked in order to provide the `next` stream, see
example above.
Regardless of how the `stream` is appended, combined-stream always attaches an
`'error'` listener to it, so you don't have to do that manually.
Special case: `stream` can also be a String or Buffer.
### combinedStream.write(data)
You should not call this, `combinedStream` takes care of piping the appended
streams into itself for you.
### combinedStream.resume()
Causes `combinedStream` to start drain the streams it manages. The function is
idempotent, and also emits a `'resume'` event each time which usually goes to
the stream that is currently being drained.
### combinedStream.pause();
If `combinedStream.pauseStreams` is set to `false`, this does nothing.
Otherwise a `'pause'` event is emitted, this goes to the stream that is
currently being drained, so you can use it to apply back pressure.
### combinedStream.end();
Sets `combinedStream.writable` to false, emits an `'end'` event, and removes
all streams from the queue.
### combinedStream.destroy();
Same as `combinedStream.end()`, except it emits a `'close'` event instead of
`'end'`.
## License
combined-stream is licensed under the MIT license.

View File

@ -0,0 +1,185 @@
var util = require('util');
var Stream = require('stream').Stream;
var DelayedStream = require('delayed-stream');
module.exports = CombinedStream;
function CombinedStream() {
this.writable = false;
this.readable = true;
this.dataSize = 0;
this.maxDataSize = 2 * 1024 * 1024;
this.pauseStreams = true;
this._released = false;
this._streams = [];
this._currentStream = null;
}
util.inherits(CombinedStream, Stream);
CombinedStream.create = function(options) {
var combinedStream = new this();
options = options || {};
for (var option in options) {
combinedStream[option] = options[option];
}
return combinedStream;
};
CombinedStream.isStreamLike = function(stream) {
return (typeof stream !== 'function')
&& (typeof stream !== 'string')
&& (typeof stream !== 'boolean')
&& (typeof stream !== 'number')
&& (!Buffer.isBuffer(stream));
};
CombinedStream.prototype.append = function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
if (!(stream instanceof DelayedStream)) {
stream.on('data', this._checkDataSize.bind(this));
stream = DelayedStream.create(stream, {
maxDataSize: Infinity,
pauseStream: this.pauseStreams,
});
}
this._handleErrors(stream);
if (this.pauseStreams) {
stream.pause();
}
}
this._streams.push(stream);
return this;
};
CombinedStream.prototype.pipe = function(dest, options) {
Stream.prototype.pipe.call(this, dest, options);
this.resume();
};
CombinedStream.prototype._getNext = function() {
this._currentStream = null;
var stream = this._streams.shift();
if (typeof stream == 'undefined') {
this.end();
return;
}
if (typeof stream !== 'function') {
this._pipeNext(stream);
return;
}
var getStream = stream;
getStream(function(stream) {
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('data', this._checkDataSize.bind(this));
this._handleErrors(stream);
}
this._pipeNext(stream);
}.bind(this));
};
CombinedStream.prototype._pipeNext = function(stream) {
this._currentStream = stream;
var isStreamLike = CombinedStream.isStreamLike(stream);
if (isStreamLike) {
stream.on('end', this._getNext.bind(this))
stream.pipe(this, {end: false});
return;
}
var value = stream;
this.write(value);
this._getNext();
};
CombinedStream.prototype._handleErrors = function(stream) {
var self = this;
stream.on('error', function(err) {
self._emitError(err);
});
};
CombinedStream.prototype.write = function(data) {
this.emit('data', data);
};
CombinedStream.prototype.pause = function() {
if (!this.pauseStreams) {
return;
}
this.emit('pause');
};
CombinedStream.prototype.resume = function() {
if (!this._released) {
this._released = true;
this.writable = true;
this._getNext();
}
this.emit('resume');
};
CombinedStream.prototype.end = function() {
this._reset();
this.emit('end');
};
CombinedStream.prototype.destroy = function() {
this._reset();
this.emit('close');
};
CombinedStream.prototype._reset = function() {
this.writable = false;
this._streams = [];
this._currentStream = null;
};
CombinedStream.prototype._checkDataSize = function() {
this._updateDataSize();
if (this.dataSize <= this.maxDataSize) {
return;
}
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
this._emitError(new Error(message));
};
CombinedStream.prototype._updateDataSize = function() {
this.dataSize = 0;
var self = this;
this._streams.forEach(function(stream) {
if (!stream.dataSize) {
return;
}
self.dataSize += stream.dataSize;
});
if (this._currentStream && this._currentStream.dataSize) {
this.dataSize += this._currentStream.dataSize;
}
};
CombinedStream.prototype._emitError = function(err) {
this._reset();
this.emit('error', err);
};

View File

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

View File

@ -0,0 +1,7 @@
SHELL := /bin/bash
test:
@./test/run.js
.PHONY: test

View File

@ -0,0 +1,154 @@
# delayed-stream
Buffers events from a stream until you are ready to handle them.
## Installation
``` bash
npm install delayed-stream
```
## Usage
The following example shows how to write a http echo server that delays its
response by 1000 ms.
``` javascript
var DelayedStream = require('delayed-stream');
var http = require('http');
http.createServer(function(req, res) {
var delayed = DelayedStream.create(req);
setTimeout(function() {
res.writeHead(200);
delayed.pipe(res);
}, 1000);
});
```
If you are not using `Stream#pipe`, you can also manually release the buffered
events by calling `delayedStream.resume()`:
``` javascript
var delayed = DelayedStream.create(req);
setTimeout(function() {
// Emit all buffered events and resume underlaying source
delayed.resume();
}, 1000);
```
## Implementation
In order to use this meta stream properly, here are a few things you should
know about the implementation.
### Event Buffering / Proxying
All events of the `source` stream are hijacked by overwriting the `source.emit`
method. Until node implements a catch-all event listener, this is the only way.
However, delayed-stream still continues to emit all events it captures on the
`source`, regardless of whether you have released the delayed stream yet or
not.
Upon creation, delayed-stream captures all `source` events and stores them in
an internal event buffer. Once `delayedStream.release()` is called, all
buffered events are emitted on the `delayedStream`, and the event buffer is
cleared. After that, delayed-stream merely acts as a proxy for the underlaying
source.
### Error handling
Error events on `source` are buffered / proxied just like any other events.
However, `delayedStream.create` attaches a no-op `'error'` listener to the
`source`. This way you only have to handle errors on the `delayedStream`
object, rather than in two places.
### Buffer limits
delayed-stream provides a `maxDataSize` property that can be used to limit
the amount of data being buffered. In order to protect you from bad `source`
streams that don't react to `source.pause()`, this feature is enabled by
default.
## API
### DelayedStream.create(source, [options])
Returns a new `delayedStream`. Available options are:
* `pauseStream`
* `maxDataSize`
The description for those properties can be found below.
### delayedStream.source
The `source` stream managed by this object. This is useful if you are
passing your `delayedStream` around, and you still want to access properties
on the `source` object.
### delayedStream.pauseStream = true
Whether to pause the underlaying `source` when calling
`DelayedStream.create()`. Modifying this property afterwards has no effect.
### delayedStream.maxDataSize = 1024 * 1024
The amount of data to buffer before emitting an `error`.
If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
refers to bytes.
If the underlaying source is emitting JavaScript strings, the size refers to
characters.
If you know what you are doing, you can set this property to `Infinity` to
disable this feature. You can also modify this property during runtime.
### delayedStream.maxDataSize = 1024 * 1024
The amount of data to buffer before emitting an `error`.
If the underlaying source is emitting `Buffer` objects, the `maxDataSize`
refers to bytes.
If the underlaying source is emitting JavaScript strings, the size refers to
characters.
If you know what you are doing, you can set this property to `Infinity` to
disable this feature.
### delayedStream.dataSize = 0
The amount of data buffered so far.
### delayedStream.readable
An ECMA5 getter that returns the value of `source.readable`.
### delayedStream.resume()
If the `delayedStream` has not been released so far, `delayedStream.release()`
is called.
In either case, `source.resume()` is called.
### delayedStream.pause()
Calls `source.pause()`.
### delayedStream.pipe(dest)
Calls `delayedStream.resume()` and then proxies the arguments to `source.pipe`.
### delayedStream.release()
Emits and clears all events that have been buffered up so far. This does not
resume the underlaying source, use `delayedStream.resume()` instead.
## License
delayed-stream is licensed under the MIT license.

View File

@ -0,0 +1,99 @@
var Stream = require('stream').Stream;
var util = require('util');
module.exports = DelayedStream;
function DelayedStream() {
this.source = null;
this.dataSize = 0;
this.maxDataSize = 1024 * 1024;
this.pauseStream = true;
this._maxDataSizeExceeded = false;
this._released = false;
this._bufferedEvents = [];
}
util.inherits(DelayedStream, Stream);
DelayedStream.create = function(source, options) {
var delayedStream = new this();
options = options || {};
for (var option in options) {
delayedStream[option] = options[option];
}
delayedStream.source = source;
var realEmit = source.emit;
source.emit = function() {
delayedStream._handleEmit(arguments);
return realEmit.apply(source, arguments);
};
source.on('error', function() {});
if (delayedStream.pauseStream) {
source.pause();
}
return delayedStream;
};
DelayedStream.prototype.__defineGetter__('readable', function() {
return this.source.readable;
});
DelayedStream.prototype.resume = function() {
if (!this._released) {
this.release();
}
this.source.resume();
};
DelayedStream.prototype.pause = function() {
this.source.pause();
};
DelayedStream.prototype.release = function() {
this._released = true;
this._bufferedEvents.forEach(function(args) {
this.emit.apply(this, args);
}.bind(this));
this._bufferedEvents = [];
};
DelayedStream.prototype.pipe = function() {
var r = Stream.prototype.pipe.apply(this, arguments);
this.resume();
return r;
};
DelayedStream.prototype._handleEmit = function(args) {
if (this._released) {
this.emit.apply(this, args);
return;
}
if (args[0] === 'data') {
this.dataSize += args[1].length;
this._checkIfMaxDataSizeExceeded();
}
this._bufferedEvents.push(args);
};
DelayedStream.prototype._checkIfMaxDataSizeExceeded = function() {
if (this._maxDataSizeExceeded) {
return;
}
if (this.dataSize <= this.maxDataSize) {
return;
}
this._maxDataSizeExceeded = true;
var message =
'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'
this.emit('error', new Error(message));
};

View File

@ -0,0 +1,38 @@
{
"author": {
"name": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/"
},
"name": "delayed-stream",
"description": "Buffers events from a stream until you are ready to handle them.",
"version": "0.0.5",
"homepage": "https://github.com/felixge/node-delayed-stream",
"repository": {
"type": "git",
"url": "git://github.com/felixge/node-delayed-stream.git"
},
"main": "./lib/delayed_stream",
"engines": {
"node": ">=0.4.0"
},
"dependencies": {},
"devDependencies": {
"fake": "0.2.0",
"far": "0.0.1"
},
"_npmUser": {
"name": "mikeal",
"email": "mikeal.rogers@gmail.com"
},
"_id": "delayed-stream@0.0.5",
"optionalDependencies": {},
"_engineSupported": true,
"_npmVersion": "1.1.24",
"_nodeVersion": "v0.8.1",
"_defaultsLoaded": true,
"dist": {
"shasum": "56f46a53506f656e1a549c63d8794c6cf8b6e1fc"
},
"_from": "delayed-stream@0.0.5"
}

View File

@ -0,0 +1,6 @@
var common = module.exports;
common.DelayedStream = require('..');
common.assert = require('assert');
common.fake = require('fake');
common.PORT = 49252;

View File

@ -0,0 +1,38 @@
var common = require('../common');
var assert = common.assert;
var DelayedStream = common.DelayedStream;
var http = require('http');
var UPLOAD = new Buffer(10 * 1024 * 1024);
var server = http.createServer(function(req, res) {
var delayed = DelayedStream.create(req, {maxDataSize: UPLOAD.length});
setTimeout(function() {
res.writeHead(200);
delayed.pipe(res);
}, 10);
});
server.listen(common.PORT, function() {
var request = http.request({
method: 'POST',
port: common.PORT,
});
request.write(UPLOAD);
request.end();
request.on('response', function(res) {
var received = 0;
res
.on('data', function(chunk) {
received += chunk.length;
})
.on('end', function() {
assert.equal(received, UPLOAD.length);
server.close();
});
});
});

View File

@ -0,0 +1,21 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testAutoPause() {
var source = new Stream();
fake.expect(source, 'pause', 1);
var delayedStream = DelayedStream.create(source);
fake.verify();
})();
(function testDisableAutoPause() {
var source = new Stream();
fake.expect(source, 'pause', 0);
var delayedStream = DelayedStream.create(source, {pauseStream: false});
fake.verify();
})();

View File

@ -0,0 +1,14 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testDelayEventsUntilResume() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {pauseStream: false});
fake.expect(source, 'pause');
delayedStream.pause();
fake.verify();
})();

View File

@ -0,0 +1,48 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testDelayEventsUntilResume() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {pauseStream: false});
// delayedStream must not emit until we resume
fake.expect(delayedStream, 'emit', 0);
// but our original source must emit
var params = [];
source.on('foo', function(param) {
params.push(param);
});
source.emit('foo', 1);
source.emit('foo', 2);
// Make sure delayedStream did not emit, and source did
assert.deepEqual(params, [1, 2]);
fake.verify();
// After resume, delayedStream must playback all events
fake
.stub(delayedStream, 'emit')
.times(Infinity)
.withArg(1, 'newListener');
fake.expect(delayedStream, 'emit', ['foo', 1]);
fake.expect(delayedStream, 'emit', ['foo', 2]);
fake.expect(source, 'resume');
delayedStream.resume();
fake.verify();
// Calling resume again will delegate to source
fake.expect(source, 'resume');
delayedStream.resume();
fake.verify();
// Emitting more events directly leads to them being emitted
fake.expect(delayedStream, 'emit', ['foo', 3]);
source.emit('foo', 3);
fake.verify();
})();

View File

@ -0,0 +1,15 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testHandleSourceErrors() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {pauseStream: false});
// We deal with this by attaching a no-op listener to 'error' on the source
// when creating a new DelayedStream. This way error events on the source
// won't throw.
source.emit('error', new Error('something went wrong'));
})();

View File

@ -0,0 +1,18 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testMaxDataSize() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {maxDataSize: 1024, pauseStream: false});
source.emit('data', new Buffer(1024));
fake
.expect(delayedStream, 'emit')
.withArg(1, 'error');
source.emit('data', new Buffer(1));
fake.verify();
})();

View File

@ -0,0 +1,13 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testPipeReleases() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {pauseStream: false});
fake.expect(delayedStream, 'resume');
delayedStream.pipe(new Stream());
})();

View File

@ -0,0 +1,13 @@
var common = require('../common');
var assert = common.assert;
var fake = common.fake.create();
var DelayedStream = common.DelayedStream;
var Stream = require('stream').Stream;
(function testProxyReadableProperty() {
var source = new Stream();
var delayedStream = DelayedStream.create(source, {pauseStream: false});
source.readable = fake.value('source.readable');
assert.strictEqual(delayedStream.readable, source.readable);
})();

View File

@ -0,0 +1,7 @@
#!/usr/bin/env node
var far = require('far').create();
far.add(__dirname);
far.include(/test-.*\.js$/);
far.execute();

View File

@ -0,0 +1,39 @@
{
"author": {
"name": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/"
},
"name": "combined-stream",
"description": "A stream that emits multiple other streams one after another.",
"version": "0.0.4",
"homepage": "https://github.com/felixge/node-combined-stream",
"repository": {
"type": "git",
"url": "git://github.com/felixge/node-combined-stream.git"
},
"main": "./lib/combined_stream",
"engines": {
"node": "*"
},
"dependencies": {
"delayed-stream": "0.0.5"
},
"devDependencies": {
"far": "0.0.1"
},
"_npmUser": {
"name": "mikeal",
"email": "mikeal.rogers@gmail.com"
},
"_id": "combined-stream@0.0.4",
"optionalDependencies": {},
"_engineSupported": true,
"_npmVersion": "1.1.24",
"_nodeVersion": "v0.8.1",
"_defaultsLoaded": true,
"dist": {
"shasum": "2d1a43347dbe9515a4a2796732e5b88473840b22"
},
"_from": "combined-stream@~0.0.4"
}

View File

@ -0,0 +1,23 @@
var common = module.exports;
var path = require('path');
var fs = require('fs');
var root = path.join(__dirname, '..');
common.dir = {
fixture: root + '/test/fixture',
tmp: root + '/test/tmp',
};
// Create tmp directory if it does not exist
// Not using fs.exists so as to be node 0.6.x compatible
try {
fs.statSync(common.dir.tmp);
}
catch (e) {
// Dir does not exist
fs.mkdirSync(common.dir.tmp);
}
common.CombinedStream = require(root);
common.assert = require('assert');

View File

@ -0,0 +1,256 @@
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101
10101010101010101010101010101010101010101010101010101010101010101010101010101010
01010101010101010101010101010101010101010101010101010101010101010101010101010101

View File

@ -0,0 +1,256 @@
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202
20202020202020202020202020202020202020202020202020202020202020202020202020202020
02020202020202020202020202020202020202020202020202020202020202020202020202020202

View File

@ -0,0 +1,27 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var fs = require('fs');
var FILE1 = common.dir.fixture + '/file1.txt';
var FILE2 = common.dir.fixture + '/file2.txt';
var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
(function testDelayedStreams() {
var combinedStream = CombinedStream.create();
combinedStream.append(function(next) {
next(fs.createReadStream(FILE1));
});
combinedStream.append(function(next) {
next(fs.createReadStream(FILE2));
});
var tmpFile = common.dir.tmp + '/combined.txt';
var dest = fs.createWriteStream(tmpFile);
combinedStream.pipe(dest);
dest.on('end', function() {
var written = fs.readFileSync(tmpFile, 'utf8');
assert.strictEqual(written, EXPECTED);
});
})();

View File

@ -0,0 +1,34 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
(function testDataSizeGetter() {
var combinedStream = CombinedStream.create();
assert.strictEqual(combinedStream.dataSize, 0);
// Test one stream
combinedStream._streams.push({dataSize: 10});
combinedStream._updateDataSize();
assert.strictEqual(combinedStream.dataSize, 10);
// Test two streams
combinedStream._streams.push({dataSize: 23});
combinedStream._updateDataSize();
assert.strictEqual(combinedStream.dataSize, 33);
// Test currentStream
combinedStream._currentStream = {dataSize: 20};
combinedStream._updateDataSize();
assert.strictEqual(combinedStream.dataSize, 53);
// Test currentStream without dataSize
combinedStream._currentStream = {};
combinedStream._updateDataSize();
assert.strictEqual(combinedStream.dataSize, 33);
// Test stream function
combinedStream._streams.push(function() {});
combinedStream._updateDataSize();
assert.strictEqual(combinedStream.dataSize, 33);
})();

View File

@ -0,0 +1,38 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var fs = require('fs');
var FILE1 = common.dir.fixture + '/file1.txt';
var BUFFER = new Buffer('Bacon is delicious');
var FILE2 = common.dir.fixture + '/file2.txt';
var STRING = 'The € kicks the $\'s ass!';
var EXPECTED =
fs.readFileSync(FILE1)
+ BUFFER
+ fs.readFileSync(FILE2)
+ STRING;
var GOT;
(function testDelayedStreams() {
var combinedStream = CombinedStream.create();
combinedStream.append(fs.createReadStream(FILE1));
combinedStream.append(BUFFER);
combinedStream.append(fs.createReadStream(FILE2));
combinedStream.append(function(next) {
next(STRING);
});
var tmpFile = common.dir.tmp + '/combined-file1-buffer-file2-string.txt';
var dest = fs.createWriteStream(tmpFile);
combinedStream.pipe(dest);
dest.on('close', function() {
GOT = fs.readFileSync(tmpFile, 'utf8');
});
})();
process.on('exit', function() {
assert.strictEqual(GOT, EXPECTED);
});

View File

@ -0,0 +1,35 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var fs = require('fs');
var FILE1 = common.dir.fixture + '/file1.txt';
var FILE2 = common.dir.fixture + '/file2.txt';
var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
var GOT;
(function testDelayedStreams() {
var combinedStream = CombinedStream.create();
combinedStream.append(fs.createReadStream(FILE1));
combinedStream.append(fs.createReadStream(FILE2));
var stream1 = combinedStream._streams[0];
var stream2 = combinedStream._streams[1];
stream1.on('end', function() {
assert.equal(stream2.dataSize, 0);
});
var tmpFile = common.dir.tmp + '/combined.txt';
var dest = fs.createWriteStream(tmpFile);
combinedStream.pipe(dest);
dest.on('close', function() {
GOT = fs.readFileSync(tmpFile, 'utf8');
});
})();
process.on('exit', function() {
console.error(GOT.length, EXPECTED.length);
assert.strictEqual(GOT, EXPECTED);
});

View File

@ -0,0 +1,39 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var util = require('util');
var Stream = require('stream').Stream;
var s = CombinedStream.create();
function StringStream(){
this.writable=true;
this.str=""
}
util.inherits(StringStream,Stream);
StringStream.prototype.write=function(chunk,encoding){
this.str+=chunk.toString();
this.emit('data',chunk);
}
StringStream.prototype.end=function(chunk,encoding){
this.emit('end');
}
StringStream.prototype.toString=function(){
return this.str;
}
s.append("foo.");
s.append("");
s.append("bar");
var ss = new StringStream();
s.pipe(ss);
s.resume();
assert.equal(ss.toString(),"foo.bar");

View File

@ -0,0 +1,17 @@
var fs = require('fs');
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var FILE1 = common.dir.fixture + '/file1.txt';
var fileStream = fs.createReadStream(FILE1);
var foo = function(){};
(function testIsStreamLike() {
assert(! CombinedStream.isStreamLike(true));
assert(! CombinedStream.isStreamLike("I am a string"));
assert(! CombinedStream.isStreamLike(7));
assert(! CombinedStream.isStreamLike(foo));
assert(CombinedStream.isStreamLike(fileStream));
})();

View File

@ -0,0 +1,24 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var fs = require('fs');
var FILE1 = common.dir.fixture + '/file1.txt';
var FILE2 = common.dir.fixture + '/file2.txt';
var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
(function testDelayedStreams() {
var combinedStream = CombinedStream.create({pauseStreams: false, maxDataSize: 20736});
combinedStream.append(fs.createReadStream(FILE1));
combinedStream.append(fs.createReadStream(FILE2));
var gotErr = null;
combinedStream.on('error', function(err) {
gotErr = err;
});
process.on('exit', function() {
assert.ok(gotErr);
assert.ok(gotErr.message.match(/bytes/));
});
})();

View File

@ -0,0 +1,30 @@
var common = require('../common');
var assert = common.assert;
var CombinedStream = common.CombinedStream;
var fs = require('fs');
var FILE1 = common.dir.fixture + '/file1.txt';
var FILE2 = common.dir.fixture + '/file2.txt';
var EXPECTED = fs.readFileSync(FILE1) + fs.readFileSync(FILE2);
(function testDelayedStreams() {
var combinedStream = CombinedStream.create({pauseStreams: false});
combinedStream.append(fs.createReadStream(FILE1));
combinedStream.append(fs.createReadStream(FILE2));
var stream1 = combinedStream._streams[0];
var stream2 = combinedStream._streams[1];
stream1.on('end', function() {
assert.ok(stream2.dataSize > 0);
});
var tmpFile = common.dir.tmp + '/combined.txt';
var dest = fs.createWriteStream(tmpFile);
combinedStream.pipe(dest);
dest.on('end', function() {
var written = fs.readFileSync(tmpFile, 'utf8');
assert.strictEqual(written, EXPECTED);
});
})();

View File

@ -0,0 +1,7 @@
#!/usr/bin/env node
var far = require('far').create();
far.add(__dirname);
far.include(/test-.*\.js$/);
far.execute();

View File

@ -0,0 +1,43 @@
{
"author": {
"name": "Felix Geisendörfer",
"email": "felix@debuggable.com",
"url": "http://debuggable.com/"
},
"name": "form-data",
"description": "A module to create readable `\"multipart/form-data\"` streams. Can be used to submit forms and file uploads to other web applications.",
"version": "0.0.7",
"repository": {
"type": "git",
"url": "git://github.com/felixge/node-form-data.git"
},
"main": "./lib/form_data",
"engines": {
"node": "*"
},
"dependencies": {
"combined-stream": "~0.0.4",
"mime": "~1.2.2",
"async": "~0.1.9"
},
"devDependencies": {
"fake": "0.2.1",
"far": "0.0.1",
"formidable": "1.0.2",
"request": "~2.9.203"
},
"_npmUser": {
"name": "mikeal",
"email": "mikeal.rogers@gmail.com"
},
"_id": "form-data@0.0.7",
"optionalDependencies": {},
"_engineSupported": true,
"_npmVersion": "1.1.24",
"_nodeVersion": "v0.8.1",
"_defaultsLoaded": true,
"dist": {
"shasum": "7211182a26a266ce39710dc8bc4a81b7040859be"
},
"_from": "form-data@~0.0.3"
}

View File

@ -0,0 +1,14 @@
var common = module.exports;
var path = require('path');
var rootDir = path.join(__dirname, '..');
common.dir = {
lib: rootDir + '/lib',
fixture: rootDir + '/test/fixture',
tmp: rootDir + '/test/tmp',
};
common.assert = require('assert');
common.fake = require('fake');
common.port = 8432;

View File

@ -0,0 +1 @@
Bacon is delicious.

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,75 @@
/*
test custom headers, added in pull request:
https://github.com/felixge/node-form-data/pull/17
*/
var common = require('../common');
var assert = common.assert;
var http = require('http');
var FormData = require(common.dir.lib + '/form_data');
var CRLF = '\r\n';
var testHeader = 'X-Test-Fake: 123';
var expectedLength;
var server = http.createServer(function(req, res) {
var data = '';
req.setEncoding('utf8');
req.on('data', function(d) {
data += d;
});
req.on('end', function() {
assert.ok( data.indexOf( testHeader ) != -1 );
// content-length would be 1000+ w/actual buffer size,
// but smaller w/overridden size.
assert.ok( typeof req.headers['content-length'] !== 'undefined' );
assert.equal(req.headers['content-length'], expectedLength);
res.writeHead(200);
res.end('done');
});
});
server.listen(common.port, function() {
var form = new FormData();
var options = {
header:
CRLF + '--' + form.getBoundary() + CRLF +
testHeader +
CRLF + CRLF,
// override content-length,
// much lower than actual buffer size (1000)
knownLength: 1
};
var bufferData = [];
for (var z = 0; z < 1000; z++) {
bufferData.push(1);
}
var buffer = new Buffer(bufferData);
form.append('my_buffer', buffer, options);
// (available to req handler)
expectedLength = form._lastBoundary().length + form._overheadLength + options.knownLength;
form.submit('http://localhost:' + common.port + '/', function(err, res) {
if (err) {
throw err;
}
assert.strictEqual(res.statusCode, 200);
server.close();
});
});

View File

@ -0,0 +1,93 @@
var common = require('../common');
var assert = common.assert;
var FormData = require(common.dir.lib + '/form_data');
var fake = require('fake').create();
var fs = require('fs');
(function testEmptyForm() {
var form = new FormData();
var callback = fake.callback(arguments.callee.name + '-getLength');
var calls = fake.expectAnytime(callback, [null, 0]).calls;
form.getLength(callback);
// Make sure our response is async
assert.strictEqual(calls.length, 0);
})();
(function testUtf8String() {
var FIELD = 'my_field';
var VALUE = 'May the € be with you';
var form = new FormData();
form.append(FIELD, VALUE);
var callback = fake.callback(arguments.callee.name + '-getLength');
var expectedLength =
form._overheadLength +
Buffer.byteLength(VALUE) +
form._lastBoundary().length;
fake.expectAnytime(callback, [null, expectedLength]);
form.getLength(callback);
})();
(function testBuffer() {
var FIELD = 'my_field';
var VALUE = new Buffer(23);
var form = new FormData();
form.append(FIELD, VALUE);
var callback = fake.callback(arguments.callee.name + '-getLength');
var expectedLength =
form._overheadLength +
VALUE.length +
form._lastBoundary().length;
fake.expectAnytime(callback, [null, expectedLength]);
form.getLength(callback);
})();
(function testStringFileBufferFile() {
var fields = [
{
name: 'my_field',
value: 'Test 123',
},
{
name: 'my_image',
value: fs.createReadStream(common.dir.fixture + '/unicycle.jpg'),
},
{
name: 'my_buffer',
value: new Buffer('123'),
},
{
name: 'my_txt',
value: fs.createReadStream(common.dir.fixture + '/bacon.txt'),
},
];
var form = new FormData();
var expectedLength = 0;
fields.forEach(function(field) {
form.append(field.name, field.value);
if (field.value.path) {
var stat = fs.statSync(field.value.path);
expectedLength += stat.size;
} else {
expectedLength += field.value.length;
}
});
expectedLength += form._overheadLength + form._lastBoundary().length;
var callback = fake.callback(arguments.callee.name + '-getLength');
fake.expectAnytime(callback, [null, expectedLength]);
form.getLength(callback);
})();

View File

@ -0,0 +1,18 @@
var common = require('../common');
var assert = common.assert;
var FormData = require(common.dir.lib + '/form_data');
(function testOneBoundaryPerForm() {
var form = new FormData();
var boundary = form.getBoundary();
assert.equal(boundary, form.getBoundary());
assert.equal(boundary.length, 50);
})();
(function testUniqueBoundaryPerForm() {
var formA = new FormData();
var formB = new FormData();
assert.notEqual(formA.getBoundary(), formB.getBoundary());
})();

View File

@ -0,0 +1,121 @@
var common = require('../common');
var assert = common.assert;
var http = require('http');
var path = require('path');
var mime = require('mime');
var request = require('request');
var parseUrl = require('url').parse;
var fs = require('fs');
var FormData = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;
var remoteFile = 'http://nodejs.org/images/logo.png';
var FIELDS;
var server;
var parsedUrl = parseUrl(remoteFile)
, options = {
method: 'get',
port: parsedUrl.port || 80,
path: parsedUrl.pathname,
host: parsedUrl.hostname
}
;
http.request(options, function(res) {
FIELDS = [
{name: 'my_field', value: 'my_value'},
{name: 'my_buffer', value: new Buffer([1, 2, 3])},
{name: 'remote_file', value: res }
];
var form = new FormData();
FIELDS.forEach(function(field) {
form.append(field.name, field.value);
});
server.listen(common.port, function() {
form.submit('http://localhost:' + common.port + '/', function(err, res) {
if (err) {
throw err;
}
assert.strictEqual(res.statusCode, 200);
server.close();
});
});
}).end();
server = http.createServer(function(req, res) {
// formidable is broken so let's do it manual way
//
// var form = new IncomingForm();
// form.uploadDir = common.dir.tmp;
// form.parse(req);
// form
// .on('field', function(name, value) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(value, field.value+'');
// })
// .on('file', function(name, file) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(file.name, path.basename(field.value.path));
// // mime.lookup file.NAME == 'my_file' ?
// assert.strictEqual(file.type, mime.lookup(file.name));
// })
// .on('end', function() {
// res.writeHead(200);
// res.end('done');
// });
// temp workaround
var data = '';
req.setEncoding('utf8');
req.on('data', function(d) {
data += d;
});
req.on('end', function() {
// check for the fields' traces
// 1st field : my_field
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 2nd field : my_buffer
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 3rd field : remote_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(remoteFile)+'"') != -1 );
// check for http://nodejs.org/images/logo.png traces
assert.ok( data.indexOf('ImageReady') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
res.writeHead(200);
res.end('done');
});
});
process.on('exit', function() {
assert.strictEqual(FIELDS.length, 0);
});

View File

@ -0,0 +1,120 @@
var common = require('../common');
var assert = common.assert;
var http = require('http');
var path = require('path');
var mime = require('mime');
var request = require('request');
var fs = require('fs');
var FormData = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;
var remoteFile = 'http://nodejs.org/images/logo.png';
// wrap non simple values into function
// just to deal with ReadStream "autostart"
// Can't wait for 0.10
var FIELDS = [
{name: 'my_field', value: 'my_value'},
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
{name: 'remote_file', value: function(){ return request(remoteFile)} }
];
var server = http.createServer(function(req, res) {
// formidable is fixed on github
// but still 7 month old in npm
//
// var form = new IncomingForm();
// form.uploadDir = common.dir.tmp;
// form.parse(req);
// form
// .on('field', function(name, value) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(value, field.value+'');
// })
// .on('file', function(name, file) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(file.name, path.basename(field.value.path));
// assert.strictEqual(file.type, mime.lookup(file.name));
// })
// .on('end', function() {
// res.writeHead(200);
// res.end('done');
// });
// temp workaround
var data = '';
req.setEncoding('utf8');
req.on('data', function(d) {
data += d;
});
req.on('end', function() {
// check for the fields' traces
// 1st field : my_field
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 2nd field : my_buffer
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 3rd field : my_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for unicycle.jpg traces
assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
// 4th field : remote_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for http://nodejs.org/images/logo.png traces
assert.ok( data.indexOf('ImageReady') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
res.writeHead(200);
res.end('done');
});
});
server.listen(common.port, function() {
var form = new FormData();
FIELDS.forEach(function(field) {
// important to append ReadStreams within the same tick
if ((typeof field.value == 'function')) {
field.value = field.value();
}
form.append(field.name, field.value);
});
var request = http.request({
method: 'post',
port: common.port,
path: '/upload',
headers: form.getHeaders()
});
form.pipe(request);
request.on('response', function(res) {
server.close();
});
});
process.on('exit', function() {
assert.strictEqual(FIELDS.length, 0);
});

View File

@ -0,0 +1,121 @@
var common = require('../common');
var assert = common.assert;
var http = require('http');
var path = require('path');
var mime = require('mime');
var request = require('request');
var fs = require('fs');
var FormData = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;
var remoteFile = 'http://nodejs.org/images/logo.png';
// wrap non simple values into function
// just to deal with ReadStream "autostart"
// Can't wait for 0.10
var FIELDS = [
{name: 'my_field', value: 'my_value'},
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
{name: 'remote_file', value: function(){ return request(remoteFile)} }
];
var server = http.createServer(function(req, res) {
// formidable is fixed on github
// but still 7 month old in npm
//
// var form = new IncomingForm();
// form.uploadDir = common.dir.tmp;
// form.parse(req);
// form
// .on('field', function(name, value) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(value, field.value+'');
// })
// .on('file', function(name, file) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(file.name, path.basename(field.value.path));
// // mime.lookup file.NAME == 'my_file' ?
// assert.strictEqual(file.type, mime.lookup(file.name));
// })
// .on('end', function() {
// res.writeHead(200);
// res.end('done');
// });
// temp workaround
var data = '';
req.setEncoding('utf8');
req.on('data', function(d) {
data += d;
});
req.on('end', function() {
// check for the fields' traces
// 1st field : my_field
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 2nd field : my_buffer
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 3rd field : my_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for unicycle.jpg traces
assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
// 4th field : remote_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for http://nodejs.org/images/logo.png traces
assert.ok( data.indexOf('ImageReady') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
res.writeHead(200);
res.end('done');
});
});
server.listen(common.port, function() {
var form = new FormData();
FIELDS.forEach(function(field) {
// important to append ReadStreams within the same tick
if ((typeof field.value == 'function')) {
field.value = field.value();
}
form.append(field.name, field.value);
});
// custom params object passed to submit
form.submit({
port: common.port,
path: '/'
}, function(err, res) {
if (err) {
throw err;
}
assert.strictEqual(res.statusCode, 200);
server.close();
});
});
process.on('exit', function() {
assert.strictEqual(FIELDS.length, 0);
});

View File

@ -0,0 +1,117 @@
var common = require('../common');
var assert = common.assert;
var http = require('http');
var path = require('path');
var mime = require('mime');
var request = require('request');
var fs = require('fs');
var FormData = require(common.dir.lib + '/form_data');
var IncomingForm = require('formidable').IncomingForm;
var remoteFile = 'http://nodejs.org/images/logo.png';
// wrap non simple values into function
// just to deal with ReadStream "autostart"
// Can't wait for 0.10
var FIELDS = [
{name: 'my_field', value: 'my_value'},
{name: 'my_buffer', value: function(){ return new Buffer([1, 2, 3])} },
{name: 'my_file', value: function(){ return fs.createReadStream(common.dir.fixture + '/unicycle.jpg')} },
{name: 'remote_file', value: function(){ return request(remoteFile)} }
];
var server = http.createServer(function(req, res) {
// formidable is fixed on github
// but still 7 month old in npm
//
// var form = new IncomingForm();
// form.uploadDir = common.dir.tmp;
// form.parse(req);
// form
// .on('field', function(name, value) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(value, field.value+'');
// })
// .on('file', function(name, file) {
// var field = FIELDS.shift();
// assert.strictEqual(name, field.name);
// assert.strictEqual(file.name, path.basename(field.value.path));
// // mime.lookup file.NAME == 'my_file' ?
// assert.strictEqual(file.type, mime.lookup(file.name));
// })
// .on('end', function() {
// res.writeHead(200);
// res.end('done');
// });
// temp workaround
var data = '';
req.setEncoding('utf8');
req.on('data', function(d) {
data += d;
});
req.on('end', function() {
// check for the fields' traces
// 1st field : my_field
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 2nd field : my_buffer
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf(field.value) != -1 );
// 3rd field : my_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for unicycle.jpg traces
assert.ok( data.indexOf('2005:06:21 01:44:12') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(field.value.path) ) != -1 );
// 4th field : remote_file
var field = FIELDS.shift();
assert.ok( data.indexOf('form-data; name="'+field.name+'"') != -1 );
assert.ok( data.indexOf('; filename="'+path.basename(field.value.path)+'"') != -1 );
// check for http://nodejs.org/images/logo.png traces
assert.ok( data.indexOf('ImageReady') != -1 );
assert.ok( data.indexOf('Content-Type: '+mime.lookup(remoteFile) ) != -1 );
res.writeHead(200);
res.end('done');
});
});
server.listen(common.port, function() {
var form = new FormData();
FIELDS.forEach(function(field) {
// important to append ReadStreams within the same tick
if ((typeof field.value == 'function')) {
field.value = field.value();
}
form.append(field.name, field.value);
});
form.submit('http://localhost:' + common.port + '/', function(err, res) {
if (err) {
throw err;
}
assert.strictEqual(res.statusCode, 200);
server.close();
});
});
process.on('exit', function() {
assert.strictEqual(FIELDS.length, 0);
});

View File

@ -0,0 +1,7 @@
#!/usr/bin/env node
var far = require('far').create();
far.add(__dirname);
far.include(/test-.*\.js$/);
far.execute();

View File

@ -0,0 +1,19 @@
Copyright (c) 2010 Benjamin Thomas, 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,63 @@
# mime
Comprehensive MIME type mapping API. Includes all 600+ types and 800+ extensions defined by the Apache project, plus additional types submitted by the node.js community.
## Install
Install with [npm](http://github.com/isaacs/npm):
npm install mime
## API - Queries
### mime.lookup(path)
Get the mime type associated with a file. Performs a case-insensitive lookup using the extension in `path` (the substring after the last '/' or '.'). E.g.
var mime = require('mime');
mime.lookup('/path/to/file.txt'); // => 'text/plain'
mime.lookup('file.txt'); // => 'text/plain'
mime.lookup('.TXT'); // => 'text/plain'
mime.lookup('htm'); // => 'text/html'
### mime.extension(type)
Get the default extension for `type`
mime.extension('text/html'); // => 'html'
mime.extension('application/octet-stream'); // => 'bin'
### mime.charsets.lookup()
Map mime-type to charset
mime.charsets.lookup('text/plain'); // => 'UTF-8'
(The logic for charset lookups is pretty rudimentary. Feel free to suggest improvements.)
## API - Defining Custom Types
The following APIs allow you to add your own type mappings within your project. If you feel a type should be included as part of node-mime, see [requesting new types](https://github.com/broofa/node-mime/wiki/Requesting-New-Types).
### mime.define()
Add custom mime/extension mappings
mime.define({
'text/x-some-format': ['x-sf', 'x-sft', 'x-sfml'],
'application/x-my-type': ['x-mt', 'x-mtt'],
// etc ...
});
mime.lookup('x-sft'); // => 'text/x-some-format'
The first entry in the extensions array is returned by `mime.extension()`. E.g.
mime.extension('text/x-some-format'); // => 'x-sf'
### mime.load(filepath)
Load mappings from an Apache ".types" format file
mime.load('./my_project.types');
The .types file format is simple - See the `types` dir for examples.

View File

@ -0,0 +1,113 @@
var path = require('path');
var fs = require('fs');
function Mime() {
// Map of extension -> mime type
this.types = Object.create(null);
// Map of mime type -> extension
this.extensions = Object.create(null);
}
/**
* Define mimetype -> extension mappings. Each key is a mime-type that maps
* to an array of extensions associated with the type. The first extension is
* used as the default extension for the type.
*
* e.g. mime.define({'audio/ogg', ['oga', 'ogg', 'spx']});
*
* @param map (Object) type definitions
*/
Mime.prototype.define = function (map) {
for (var type in map) {
var exts = map[type];
for (var i = 0; i < exts.length; i++) {
if (process.env.DEBUG_MIME && this.types[exts]) {
console.warn(this._loading.replace(/.*\//, ''), 'changes "' + exts[i] + '" extension type from ' +
this.types[exts] + ' to ' + type);
}
this.types[exts[i]] = type;
}
// Default extension is the first one we encounter
if (!this.extensions[type]) {
this.extensions[type] = exts[0];
}
}
};
/**
* Load an Apache2-style ".types" file
*
* This may be called multiple times (it's expected). Where files declare
* overlapping types/extensions, the last file wins.
*
* @param file (String) path of file to load.
*/
Mime.prototype.load = function(file) {
this._loading = file;
// Read file and split into lines
var map = {},
content = fs.readFileSync(file, 'ascii'),
lines = content.split(/[\r\n]+/);
lines.forEach(function(line) {
// Clean up whitespace/comments, and split into fields
var fields = line.replace(/\s*#.*|^\s*|\s*$/g, '').split(/\s+/);
map[fields.shift()] = fields;
});
this.define(map);
this._loading = null;
};
/**
* Lookup a mime type based on extension
*/
Mime.prototype.lookup = function(path, fallback) {
var ext = path.replace(/.*[\.\/]/, '').toLowerCase();
return this.types[ext] || fallback || this.default_type;
};
/**
* Return file extension associated with a mime type
*/
Mime.prototype.extension = function(mimeType) {
return this.extensions[mimeType];
};
// Default instance
var mime = new Mime();
// Load local copy of
// http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types
mime.load(path.join(__dirname, 'types/mime.types'));
// Load additional types from node.js community
mime.load(path.join(__dirname, 'types/node.types'));
// Default type
mime.default_type = mime.lookup('bin');
//
// Additional API specific to the default instance
//
mime.Mime = Mime;
/**
* Lookup a charset based on mime type.
*/
mime.charsets = {
lookup: function(mimeType, fallback) {
// Assume text types are utf8
return (/^text\//).test(mimeType) ? 'UTF-8' : fallback;
}
};
module.exports = mime;

View File

@ -0,0 +1,42 @@
{
"author": {
"name": "Robert Kieffer",
"email": "robert@broofa.com",
"url": "http://github.com/broofa"
},
"contributors": [
{
"name": "Benjamin Thomas",
"email": "benjamin@benjaminthomas.org",
"url": "http://github.com/bentomas"
}
],
"dependencies": {},
"description": "A comprehensive library for mime-type mapping",
"devDependencies": {},
"keywords": [
"util",
"mime"
],
"main": "mime.js",
"name": "mime",
"repository": {
"url": "git://github.com/broofa/node-mime.git",
"type": "git"
},
"version": "1.2.9",
"_npmUser": {
"name": "mikeal",
"email": "mikeal.rogers@gmail.com"
},
"_id": "mime@1.2.9",
"optionalDependencies": {},
"engines": {
"node": "*"
},
"_engineSupported": true,
"_npmVersion": "1.1.24",
"_nodeVersion": "v0.8.1",
"_defaultsLoaded": true,
"_from": "mime@~1.2.7"
}

View File

@ -0,0 +1,55 @@
/**
* Usage: node test.js
*/
var mime = require('./mime');
var assert = require('assert');
function eq(a, b) {
console.log('Test: ' + a + ' === ' + b);
assert.strictEqual.apply(null, arguments);
}
console.log(Object.keys(mime.extensions).length + ' types');
console.log(Object.keys(mime.types).length + ' extensions\n');
//
// Test mime lookups
//
eq('text/plain', mime.lookup('text.txt'));
eq('text/plain', mime.lookup('.text.txt'));
eq('text/plain', mime.lookup('.txt'));
eq('text/plain', mime.lookup('txt'));
eq('application/octet-stream', mime.lookup('text.nope'));
eq('fallback', mime.lookup('text.fallback', 'fallback'));
eq('application/octet-stream', mime.lookup('constructor'));
eq('text/plain', mime.lookup('TEXT.TXT'));
eq('text/event-stream', mime.lookup('text/event-stream'));
eq('application/x-web-app-manifest+json', mime.lookup('text.webapp'));
//
// Test extensions
//
eq('txt', mime.extension(mime.types.text));
eq('html', mime.extension(mime.types.htm));
eq('bin', mime.extension('application/octet-stream'));
eq(undefined, mime.extension('constructor'));
//
// Test node types
//
eq('application/octet-stream', mime.lookup('file.buffer'));
eq('audio/mp4', mime.lookup('file.m4a'));
//
// Test charsets
//
eq('UTF-8', mime.charsets.lookup('text/plain'));
eq(undefined, mime.charsets.lookup(mime.types.js));
eq('fallback', mime.charsets.lookup('application/octet-stream', 'fallback'));
console.log('\nOK');

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,60 @@
# What: WebVTT
# Why: To allow formats intended for marking up external text track resources.
# http://dev.w3.org/html5/webvtt/
# Added by: niftylettuce
text/vtt vtt
# What: Google Chrome Extension
# Why: To allow apps to (work) be served with the right content type header.
# http://codereview.chromium.org/2830017
# Added by: niftylettuce
application/x-chrome-extension crx
# What: HTC support
# Why: To properly render .htc files such as CSS3PIE
# Added by: niftylettuce
text/x-component htc
# What: HTML5 application cache manifest
# Why: De-facto standard. Required by Mozilla browser when serving HTML5 apps
# per https://developer.mozilla.org/en/offline_resources_in_firefox
# Added by: louisremi
text/cache-manifest appcache manifest
# What: node binary buffer format
# Why: semi-standard extension w/in the node community
# Added by: tootallnate
application/octet-stream buffer
# What: The "protected" MP-4 formats used by iTunes.
# Why: Required for streaming music to browsers (?)
# Added by: broofa
application/mp4 m4p
audio/mp4 m4a
# What: Video format, Part of RFC1890
# Why: See https://github.com/bentomas/node-mime/pull/6
# Added by: mjrusso
video/MP2T ts
# What: EventSource mime type
# Why: mime type of Server-Sent Events stream
# http://www.w3.org/TR/eventsource/#text-event-stream
# Added by: francois2metz
text/event-stream event-stream
# What: Mozilla App manifest mime type
# Why: https://developer.mozilla.org/en/Apps/Manifest#Serving_manifests
# Added by: ednapiranha
application/x-web-app-manifest+json webapp
# What: Lua file types
# Why: Googling around shows de-facto consensus on these
# Added by: creationix (Issue #45)
text/x-lua lua
application/x-lua-bytecode luac
# What: Markdown files, as per http://daringfireball.net/projects/markdown/syntax
# Why: http://stackoverflow.com/questions/10701983/what-is-the-mime-type-for-markdown
# Added by: avoidwork
text/x-markdown markdown md mkd

43
node_modules/googleapis/node_modules/request/oauth.js generated vendored Normal file
View File

@ -0,0 +1,43 @@
var crypto = require('crypto')
, qs = require('querystring')
;
function sha1 (key, body) {
return crypto.createHmac('sha1', key).update(body).digest('base64')
}
function rfc3986 (str) {
return encodeURIComponent(str)
.replace(/!/g,'%21')
.replace(/\*/g,'%2A')
.replace(/\(/g,'%28')
.replace(/\)/g,'%29')
.replace(/'/g,'%27')
;
}
function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) {
// adapted from https://dev.twitter.com/docs/auth/oauth and
// https://dev.twitter.com/docs/auth/creating-signature
var querystring = Object.keys(params).sort().map(function(key){
// big WTF here with the escape + encoding but it's what twitter wants
return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key]))
}).join('%26')
var base = [
httpMethod ? httpMethod.toUpperCase() : 'GET',
rfc3986(base_uri),
querystring
].join('&')
var key = [
consumer_secret,
token_secret || ''
].map(rfc3986).join('&')
return sha1(key, base)
}
exports.hmacsign = hmacsign
exports.rfc3986 = rfc3986

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@ -0,0 +1,59 @@
var spawn = require('child_process').spawn
, exitCode = 0
, timeout = 10000
;
var tests = [
'test-basic-auth.js'
, 'test-body.js'
, 'test-cookie.js'
, 'test-cookiejar.js'
, 'test-defaults.js'
, 'test-digest-auth.js'
, 'test-errors.js'
, 'test-form.js'
, 'test-follow-all-303.js'
, 'test-follow-all.js'
, 'test-headers.js'
, 'test-httpModule.js'
, 'test-https.js'
, 'test-https-strict.js'
, 'test-oauth.js'
, 'test-params.js'
, 'test-pipes.js'
, 'test-pool.js'
, 'test-protocol-changing-redirect.js'
, 'test-proxy.js'
, 'test-piped-redirect.js'
, 'test-qs.js'
, 'test-redirect.js'
, 'test-timeout.js'
, 'test-toJSON.js'
, 'test-tunnel.js'
]
var next = function () {
if (tests.length === 0) process.exit(exitCode);
var file = tests.shift()
console.log(file)
var proc = spawn('node', [ 'tests/' + file ])
var killed = false
var t = setTimeout(function () {
proc.kill()
exitCode += 1
console.error(file + ' timeout')
killed = true
}, timeout)
proc.stdout.pipe(process.stdout)
proc.stderr.pipe(process.stderr)
proc.on('exit', function (code) {
if (code && !killed) console.error(file + ' failed')
exitCode += code || 0
clearTimeout(t)
next()
})
}
next()

View File

@ -0,0 +1,90 @@
var fs = require('fs')
, http = require('http')
, path = require('path')
, https = require('https')
, events = require('events')
, stream = require('stream')
, assert = require('assert')
;
exports.createServer = function (port) {
port = port || 6767
var s = http.createServer(function (req, resp) {
s.emit(req.url, req, resp);
})
s.port = port
s.url = 'http://localhost:'+port
return s;
}
exports.createSSLServer = function(port, opts) {
port = port || 16767
var options = { 'key' : path.join(__dirname, 'ssl', 'test.key')
, 'cert': path.join(__dirname, 'ssl', 'test.crt')
}
if (opts) {
for (var i in opts) options[i] = opts[i]
}
for (var i in options) {
options[i] = fs.readFileSync(options[i])
}
var s = https.createServer(options, function (req, resp) {
s.emit(req.url, req, resp);
})
s.port = port
s.url = 'https://localhost:'+port
return s;
}
exports.createPostStream = function (text) {
var postStream = new stream.Stream();
postStream.writeable = true;
postStream.readable = true;
setTimeout(function () {postStream.emit('data', new Buffer(text)); postStream.emit('end')}, 0);
return postStream;
}
exports.createPostValidator = function (text, reqContentType) {
var l = function (req, resp) {
var r = '';
req.on('data', function (chunk) {r += chunk})
req.on('end', function () {
if (req.headers['content-type'] && req.headers['content-type'].indexOf('boundary=') >= 0) {
var boundary = req.headers['content-type'].split('boundary=')[1];
text = text.replace(/__BOUNDARY__/g, boundary);
}
if (r !== text) console.log(r, text);
assert.equal(r, text)
if (reqContentType) {
assert.ok(req.headers['content-type'])
assert.ok(~req.headers['content-type'].indexOf(reqContentType))
}
resp.writeHead(200, {'content-type':'text/plain'})
resp.write('OK')
resp.end()
})
}
return l;
}
exports.createGetResponse = function (text, contentType) {
var l = function (req, resp) {
contentType = contentType || 'text/plain'
resp.writeHead(200, {'content-type':contentType})
resp.write(text)
resp.end()
}
return l;
}
exports.createChunkResponse = function (chunks, contentType) {
var l = function (req, resp) {
contentType = contentType || 'text/plain'
resp.writeHead(200, {'content-type':contentType})
chunks.forEach(function (chunk) {
resp.write(chunk)
})
resp.end()
}
return l;
}

View File

@ -0,0 +1,77 @@
#
# Recommended minimum configuration:
#
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
#
# Recommended minimum Access Permission configuration:
#
# Only allow cachemgr access from localhost
http_access allow manager localhost
http_access deny manager
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
#http_access deny CONNECT !SSL_ports
# We strongly recommend the following be uncommented to protect innocent
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# Adapt localnet in the ACL section to list your (internal) IP networks
# from where browsing should be allowed
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3128
# We recommend you to use at least the following line.
hierarchy_stoplist cgi-bin ?
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/local/var/cache 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /usr/local/var/cache
# Add any of your own refresh_pattern entries above these.
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320

View File

@ -0,0 +1,20 @@
[ req ]
default_bits = 1024
days = 3650
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
output_password = password
[ req_distinguished_name ]
C = US
ST = CA
L = Oakland
O = request
OU = request Certificate Authority
CN = requestCA
emailAddress = mikeal@mikealrogers.com
[ req_attributes ]
challengePassword = password challenge

View File

View File

@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICvTCCAiYCCQDn+P/MSbDsWjANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
ZXJzLmNvbTAeFw0xMjAzMDEyMjUwNTZaFw0yMjAyMjcyMjUwNTZaMIGiMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
B3JlcXVlc3QxJjAkBgNVBAsTHXJlcXVlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5
MRIwEAYDVQQDEwlyZXF1ZXN0Q0ExJjAkBgkqhkiG9w0BCQEWF21pa2VhbEBtaWtl
YWxyb2dlcnMuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7t9pQUAK4
5XJYTI6NrF0n3G2HZsfN+rPYSVzzL8SuVyb1tHXos+vbPm3NKI4E8X1yVAXU8CjJ
5SqXnp4DAypAhaseho81cbhk7LXUhFz78OvAa+OD+xTAEAnNQ8tGUr4VGyplEjfD
xsBVuqV2j8GPNTftr+drOCFlqfAgMrBn4wIDAQABMA0GCSqGSIb3DQEBBQUAA4GB
ADVdTlVAL45R+PACNS7Gs4o81CwSclukBu4FJbxrkd4xGQmurgfRrYYKjtqiopQm
D7ysRamS3HMN9/VKq2T7r3z1PMHPAy7zM4uoXbbaTKwlnX4j/8pGPn8Ca3qHXYlo
88L/OOPc6Di7i7qckS3HFbXQCTiULtxWmy97oEuTwrAj
-----END CERTIFICATE-----

View File

@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICBjCCAW8CAQAwgaIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEmMCQGA1UECxMdcmVxdWVzdCBD
ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxEjAQBgNVBAMTCXJlcXVlc3RDQTEmMCQGCSqG
SIb3DQEJARYXbWlrZWFsQG1pa2VhbHJvZ2Vycy5jb20wgZ8wDQYJKoZIhvcNAQEB
BQADgY0AMIGJAoGBALu32lBQArjlclhMjo2sXSfcbYdmx836s9hJXPMvxK5XJvW0
deiz69s+bc0ojgTxfXJUBdTwKMnlKpeengMDKkCFqx6GjzVxuGTstdSEXPvw68Br
44P7FMAQCc1Dy0ZSvhUbKmUSN8PGwFW6pXaPwY81N+2v52s4IWWp8CAysGfjAgMB
AAGgIzAhBgkqhkiG9w0BCQcxFBMScGFzc3dvcmQgY2hhbGxlbmdlMA0GCSqGSIb3
DQEBBQUAA4GBAGJO7grHeVHXetjHEK8urIxdnvfB2qeZeObz4GPKIkqUurjr0rfj
bA3EK1kDMR5aeQWR8RunixdM16Q6Ry0lEdLVWkdSwRN9dmirIHT9cypqnD/FYOia
SdezZ0lUzXgmJIwRYRwB1KSMMocIf52ll/xC2bEGg7/ZAEuAyAgcZV3X
-----END CERTIFICATE REQUEST-----

View File

@ -0,0 +1,18 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,C8B5887048377F02
nyD5ZH0Wup2uWsDvurq5mKDaDrf8lvNn9w0SH/ZkVnfR1/bkwqrFriqJWvZNUG+q
nS0iBYczsWLJnbub9a1zLOTENWUKVD5uqbC3aGHhnoUTNSa27DONgP8gHOn6JgR+
GAKo01HCSTiVT4LjkwN337QKHnMP2fTzg+IoC/CigvMcq09hRLwU1/guq0GJKGwH
gTxYNuYmQC4Tjh8vdS4liF+Ve/P3qPR2CehZrIOkDT8PHJBGQJRo4xGUIB7Tpk38
VCk+UZ0JCS2coY8VkY/9tqFJp/ZnnQQVmaNbdRqg7ECKL+bXnNo7yjzmazPZmPe3
/ShbE0+CTt7LrjCaQAxWbeDzqfo1lQfgN1LulTm8MCXpQaJpv7v1VhIhQ7afjMYb
4thW/ypHPiYS2YJCAkAVlua9Oxzzh1qJoh8Df19iHtpd79Q77X/qf+1JvITlMu0U
gi7yEatmQcmYNws1mtTC1q2DXrO90c+NZ0LK/Alse6NRL/xiUdjug2iHeTf/idOR
Gg/5dSZbnnlj1E5zjSMDkzg6EHAFmHV4jYGSAFLEQgp4V3ZhMVoWZrvvSHgKV/Qh
FqrAK4INr1G2+/QTd09AIRzfy3/j6yD4A9iNaOsEf9Ua7Qh6RcALRCAZTWR5QtEf
dX+iSNJ4E85qXs0PqwkMDkoaxIJ+tmIRJY7y8oeylV8cfGAi8Soubt/i3SlR8IHC
uDMas/2OnwafK3N7ODeE1i7r7wkzQkSHaEz0TrF8XRnP25jAICCSLiMdAAjKfxVb
EvzsFSuAy3Jt6bU3hSLY9o4YVYKE+68ITMv9yNjvTsEiW+T+IbN34w==
-----END RSA PRIVATE KEY-----

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