diff options
Diffstat (limited to 'node_modules/xmlhttprequest-ssl')
16 files changed, 1277 insertions, 0 deletions
diff --git a/node_modules/xmlhttprequest-ssl/LICENSE b/node_modules/xmlhttprequest-ssl/LICENSE new file mode 100644 index 0000000..1c63271 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/LICENSE @@ -0,0 +1,22 @@ + Copyright (c) 2010 passive.ly LLC + + 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. diff --git a/node_modules/xmlhttprequest-ssl/README.md b/node_modules/xmlhttprequest-ssl/README.md new file mode 100644 index 0000000..e5be153 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/README.md @@ -0,0 +1,63 @@ +# node-XMLHttpRequest # + +Fork of [node-XMLHttpRequest](https://github.com/driverdan/node-XMLHttpRequest) by [driverdan](http://driverdan.com). Forked and published to npm because a [pull request](https://github.com/rase-/node-XMLHttpRequest/commit/a6b6f296e0a8278165c2d0270d9840b54d5eeadd) is not being created and merged. Changes made by [rase-](https://github.com/rase-/node-XMLHttpRequest/tree/add/ssl-support) are needed for [engine.io-client](https://github.com/Automattic/engine.io-client). + +## Usage ## + +Here's how to include the module in your project and use as the browser-based +XHR object. + + var XMLHttpRequest = require("xmlhttprequest-ssl").XMLHttpRequest; + var xhr = new XMLHttpRequest(); + +Note: use the lowercase string "xmlhttprequest-ssl" in your require(). On +case-sensitive systems (eg Linux) using uppercase letters won't work. +# Original README # + +## Usage ## + +Here's how to include the module in your project and use as the browser-based +XHR object. + + var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; + var xhr = new XMLHttpRequest(); + +Note: use the lowercase string "xmlhttprequest" in your require(). On +case-sensitive systems (eg Linux) using uppercase letters won't work. + +## Versions ## + +Prior to 1.4.0 version numbers were arbitrary. From 1.4.0 on they conform to +the standard major.minor.bugfix. 1.x shouldn't necessarily be considered +stable just because it's above 0.x. + +Since the XMLHttpRequest API is stable this library's API is stable as +well. Major version numbers indicate significant core code changes. +Minor versions indicate minor core code changes or better conformity to +the W3C spec. + +## License ## + +MIT license. See LICENSE for full details. + +## Supports ## + +* Async and synchronous requests +* GET, POST, PUT, and DELETE requests +* All spec methods (open, send, abort, getRequestHeader, + getAllRequestHeaders, event methods) +* Requests to all domains + +## Known Issues / Missing Features ## + +For a list of open issues or to report your own visit the [github issues +page](https://github.com/driverdan/node-XMLHttpRequest/issues). + +* Local file access may have unexpected results for non-UTF8 files +* Synchronous requests don't set headers properly +* Synchronous requests freeze node while waiting for response (But that's what you want, right? Stick with async!). +* Some events are missing, such as abort +* getRequestHeader is case-sensitive +* Cookies aren't persisted between requests +* Missing XML support +* Missing basic auth diff --git a/node_modules/xmlhttprequest-ssl/autotest.watchr b/node_modules/xmlhttprequest-ssl/autotest.watchr new file mode 100644 index 0000000..5324db6 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/autotest.watchr @@ -0,0 +1,8 @@ +def run_all_tests + puts `clear` + puts `node tests/test-constants.js` + puts `node tests/test-headers.js` + puts `node tests/test-request.js` +end +watch('.*.js') { run_all_tests } +run_all_tests diff --git a/node_modules/xmlhttprequest-ssl/example/demo.js b/node_modules/xmlhttprequest-ssl/example/demo.js new file mode 100644 index 0000000..4f333de --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/example/demo.js @@ -0,0 +1,16 @@ +var sys = require('util'); +var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; + +var xhr = new XMLHttpRequest(); + +xhr.onreadystatechange = function() { + sys.puts("State: " + this.readyState); + + if (this.readyState == 4) { + sys.puts("Complete.\nBody length: " + this.responseText.length); + sys.puts("Body:\n" + this.responseText); + } +}; + +xhr.open("GET", "http://driverdan.com"); +xhr.send(); diff --git a/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js b/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js new file mode 100644 index 0000000..b9e069e --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js @@ -0,0 +1,652 @@ +/** + * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object. + * + * This can be used with JS designed for browsers to improve reuse of code and + * allow the use of existing libraries. + * + * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs. + * + * @author Dan DeFelippi <dan@driverdan.com> + * @contributor David Ellis <d.f.ellis@ieee.org> + * @license MIT + */ + +var fs = require('fs'); +var Url = require('url'); +var spawn = require('child_process').spawn; + +/** + * Module exports. + */ + +module.exports = XMLHttpRequest; + +// backwards-compat +XMLHttpRequest.XMLHttpRequest = XMLHttpRequest; + +/** + * `XMLHttpRequest` constructor. + * + * Supported options for the `opts` object are: + * + * - `agent`: An http.Agent instance; http.globalAgent may be used; if 'undefined', agent usage is disabled + * + * @param {Object} opts optional "options" object + */ + +function XMLHttpRequest(opts) { + "use strict"; + + /** + * Private variables + */ + var self = this; + var http = require('http'); + var https = require('https'); + + // Holds http.js objects + var request; + var response; + + // Request settings + var settings = {}; + + // Disable header blacklist. + // Not part of XHR specs. + var disableHeaderCheck = false; + + // Set some default headers + var defaultHeaders = { + "User-Agent": "node-XMLHttpRequest", + "Accept": "*/*" + }; + + var headers = Object.assign({}, defaultHeaders); + + // These headers are not user setable. + // The following are allowed but banned in the spec: + // * user-agent + var forbiddenRequestHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "content-transfer-encoding", + "cookie", + "cookie2", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "via" + ]; + + // These request methods are not allowed + var forbiddenRequestMethods = [ + "TRACE", + "TRACK", + "CONNECT" + ]; + + // Send flag + var sendFlag = false; + // Error flag, used when errors occur or abort is called + var errorFlag = false; + + // Event listeners + var listeners = {}; + + /** + * Constants + */ + + this.UNSENT = 0; + this.OPENED = 1; + this.HEADERS_RECEIVED = 2; + this.LOADING = 3; + this.DONE = 4; + + /** + * Public vars + */ + + // Current state + this.readyState = this.UNSENT; + + // default ready state change handler in case one is not set or is set late + this.onreadystatechange = null; + + // Result & response + this.responseText = ""; + this.responseXML = ""; + this.status = null; + this.statusText = null; + + /** + * Private methods + */ + + /** + * Check if the specified header is allowed. + * + * @param string header Header to validate + * @return boolean False if not allowed, otherwise true + */ + var isAllowedHttpHeader = function(header) { + return disableHeaderCheck || (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1); + }; + + /** + * Check if the specified method is allowed. + * + * @param string method Request method to validate + * @return boolean False if not allowed, otherwise true + */ + var isAllowedHttpMethod = function(method) { + return (method && forbiddenRequestMethods.indexOf(method) === -1); + }; + + /** + * Public methods + */ + + /** + * Open the connection. Currently supports local server requests. + * + * @param string method Connection method (eg GET, POST) + * @param string url URL for the connection. + * @param boolean async Asynchronous connection. Default is true. + * @param string user Username for basic authentication (optional) + * @param string password Password for basic authentication (optional) + */ + this.open = function(method, url, async, user, password) { + this.abort(); + errorFlag = false; + + // Check for valid request method + if (!isAllowedHttpMethod(method)) { + throw "SecurityError: Request method not allowed"; + } + + settings = { + "method": method, + "url": url.toString(), + "async": (typeof async !== "boolean" ? true : async), + "user": user || null, + "password": password || null + }; + + setState(this.OPENED); + }; + + /** + * Disables or enables isAllowedHttpHeader() check the request. Enabled by default. + * This does not conform to the W3C spec. + * + * @param boolean state Enable or disable header checking. + */ + this.setDisableHeaderCheck = function(state) { + disableHeaderCheck = state; + }; + + /** + * Sets a header for the request. + * + * @param string header Header name + * @param string value Header value + * @return boolean Header added + */ + this.setRequestHeader = function(header, value) { + if (this.readyState != this.OPENED) { + throw "INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN"; + return false; + } + if (!isAllowedHttpHeader(header)) { + console.warn('Refused to set unsafe header "' + header + '"'); + return false; + } + if (sendFlag) { + throw "INVALID_STATE_ERR: send flag is true"; + return false; + } + headers[header] = value; + return true; + }; + + /** + * Gets a header from the server response. + * + * @param string header Name of header to get. + * @return string Text of the header or null if it doesn't exist. + */ + this.getResponseHeader = function(header) { + if (typeof header === "string" + && this.readyState > this.OPENED + && response.headers[header.toLowerCase()] + && !errorFlag + ) { + return response.headers[header.toLowerCase()]; + } + + return null; + }; + + /** + * Gets all the response headers. + * + * @return string A string with all response headers separated by CR+LF + */ + this.getAllResponseHeaders = function() { + if (this.readyState < this.HEADERS_RECEIVED || errorFlag) { + return ""; + } + var result = ""; + + for (var i in response.headers) { + // Cookie headers are excluded + if (i !== "set-cookie" && i !== "set-cookie2") { + result += i + ": " + response.headers[i] + "\r\n"; + } + } + return result.substr(0, result.length - 2); + }; + + /** + * Gets a request header + * + * @param string name Name of header to get + * @return string Returns the request header or empty string if not set + */ + this.getRequestHeader = function(name) { + // @TODO Make this case insensitive + if (typeof name === "string" && headers[name]) { + return headers[name]; + } + + return ""; + }; + + /** + * Sends the request to the server. + * + * @param string data Optional data to send as request body. + */ + this.send = function(data) { + if (this.readyState != this.OPENED) { + throw "INVALID_STATE_ERR: connection must be opened before send() is called"; + } + + if (sendFlag) { + throw "INVALID_STATE_ERR: send has already been called"; + } + + var ssl = false, local = false; + var url = Url.parse(settings.url); + var host; + // Determine the server + switch (url.protocol) { + case 'https:': + ssl = true; + // SSL & non-SSL both need host, no break here. + case 'http:': + host = url.hostname; + break; + + case 'file:': + local = true; + break; + + case undefined: + case '': + host = "localhost"; + break; + + default: + throw "Protocol not supported."; + } + + // Load files off the local filesystem (file://) + if (local) { + if (settings.method !== "GET") { + throw "XMLHttpRequest: Only GET method is supported"; + } + + if (settings.async) { + fs.readFile(url.pathname, 'utf8', function(error, data) { + if (error) { + self.handleError(error); + } else { + self.status = 200; + self.responseText = data; + setState(self.DONE); + } + }); + } else { + try { + this.responseText = fs.readFileSync(url.pathname, 'utf8'); + this.status = 200; + setState(self.DONE); + } catch(e) { + this.handleError(e); + } + } + + return; + } + + // Default to port 80. If accessing localhost on another port be sure + // to use http://localhost:port/path + var port = url.port || (ssl ? 443 : 80); + // Add query string if one is used + var uri = url.pathname + (url.search ? url.search : ''); + + // Set the Host header or the server may reject the request + headers["Host"] = host; + if (!((ssl && port === 443) || port === 80)) { + headers["Host"] += ':' + url.port; + } + + // Set Basic Auth if necessary + if (settings.user) { + if (typeof settings.password == "undefined") { + settings.password = ""; + } + var authBuf = new Buffer(settings.user + ":" + settings.password); + headers["Authorization"] = "Basic " + authBuf.toString("base64"); + } + + // Set content length header + if (settings.method === "GET" || settings.method === "HEAD") { + data = null; + } else if (data) { + headers["Content-Length"] = Buffer.isBuffer(data) ? data.length : Buffer.byteLength(data); + + if (!headers["Content-Type"]) { + headers["Content-Type"] = "text/plain;charset=UTF-8"; + } + } else if (settings.method === "POST") { + // For a post with no data set Content-Length: 0. + // This is required by buggy servers that don't meet the specs. + headers["Content-Length"] = 0; + } + + var agent = false; + if (opts && opts.agent) { + agent = opts.agent; + } + var options = { + host: host, + port: port, + path: uri, + method: settings.method, + headers: headers, + agent: agent + }; + + if (ssl) { + options.pfx = opts.pfx; + options.key = opts.key; + options.passphrase = opts.passphrase; + options.cert = opts.cert; + options.ca = opts.ca; + options.ciphers = opts.ciphers; + options.rejectUnauthorized = opts.rejectUnauthorized; + } + + // Reset error flag + errorFlag = false; + + // Handle async requests + if (settings.async) { + // Use the proper protocol + var doRequest = ssl ? https.request : http.request; + + // Request is being sent, set send flag + sendFlag = true; + + // As per spec, this is called here for historical reasons. + self.dispatchEvent("readystatechange"); + + // Handler for the response + var responseHandler = function(resp) { + // Set response var to the response we got back + // This is so it remains accessable outside this scope + response = resp; + // Check for redirect + // @TODO Prevent looped redirects + if (response.statusCode === 302 || response.statusCode === 303 || response.statusCode === 307) { + // Change URL to the redirect location + settings.url = response.headers.location; + var url = Url.parse(settings.url); + // Set host var in case it's used later + host = url.hostname; + // Options for the new request + var newOptions = { + hostname: url.hostname, + port: url.port, + path: url.path, + method: response.statusCode === 303 ? 'GET' : settings.method, + headers: headers + }; + + if (ssl) { + newOptions.pfx = opts.pfx; + newOptions.key = opts.key; + newOptions.passphrase = opts.passphrase; + newOptions.cert = opts.cert; + newOptions.ca = opts.ca; + newOptions.ciphers = opts.ciphers; + newOptions.rejectUnauthorized = opts.rejectUnauthorized; + } + + // Issue the new request + request = doRequest(newOptions, responseHandler).on('error', errorHandler); + request.end(); + // @TODO Check if an XHR event needs to be fired here + return; + } + + if (response && response.setEncoding) { + response.setEncoding("utf8"); + } + + setState(self.HEADERS_RECEIVED); + self.status = response.statusCode; + + response.on('data', function(chunk) { + // Make sure there's some data + if (chunk) { + self.responseText += chunk; + } + // Don't emit state changes if the connection has been aborted. + if (sendFlag) { + setState(self.LOADING); + } + }); + + response.on('end', function() { + if (sendFlag) { + // The sendFlag needs to be set before setState is called. Otherwise if we are chaining callbacks + // there can be a timing issue (the callback is called and a new call is made before the flag is reset). + sendFlag = false; + // Discard the 'end' event if the connection has been aborted + setState(self.DONE); + } + }); + + response.on('error', function(error) { + self.handleError(error); + }); + } + + // Error handler for the request + var errorHandler = function(error) { + self.handleError(error); + } + + // Create the request + request = doRequest(options, responseHandler).on('error', errorHandler); + + // Node 0.4 and later won't accept empty data. Make sure it's needed. + if (data) { + request.write(data); + } + + request.end(); + + self.dispatchEvent("loadstart"); + } else { // Synchronous + // Create a temporary file for communication with the other Node process + var contentFile = ".node-xmlhttprequest-content-" + process.pid; + var syncFile = ".node-xmlhttprequest-sync-" + process.pid; + fs.writeFileSync(syncFile, "", "utf8"); + // The async request the other Node process executes + var execString = "var http = require('http'), https = require('https'), fs = require('fs');" + + "var doRequest = http" + (ssl ? "s" : "") + ".request;" + + "var options = " + JSON.stringify(options) + ";" + + "var responseText = '';" + + "var req = doRequest(options, function(response) {" + + "response.setEncoding('utf8');" + + "response.on('data', function(chunk) {" + + " responseText += chunk;" + + "});" + + "response.on('end', function() {" + + "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-STATUS:' + response.statusCode + ',' + responseText, 'utf8');" + + "fs.unlinkSync('" + syncFile + "');" + + "});" + + "response.on('error', function(error) {" + + "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');" + + "fs.unlinkSync('" + syncFile + "');" + + "});" + + "}).on('error', function(error) {" + + "fs.writeFileSync('" + contentFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');" + + "fs.unlinkSync('" + syncFile + "');" + + "});" + + (data ? "req.write('" + data.replace(/'/g, "\\'") + "');":"") + + "req.end();"; + // Start the other Node Process, executing this string + var syncProc = spawn(process.argv[0], ["-e", execString]); + var statusText; + while(fs.existsSync(syncFile)) { + // Wait while the sync file is empty + } + self.responseText = fs.readFileSync(contentFile, 'utf8'); + // Kill the child process once the file has data + syncProc.stdin.end(); + // Remove the temporary file + fs.unlinkSync(contentFile); + if (self.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) { + // If the file returned an error, handle it + var errorObj = self.responseText.replace(/^NODE-XMLHTTPREQUEST-ERROR:/, ""); + self.handleError(errorObj); + } else { + // If the file returned okay, parse its data and move to the DONE state + self.status = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:([0-9]*),.*/, "$1"); + self.responseText = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:[0-9]*,(.*)/, "$1"); + setState(self.DONE); + } + } + }; + + /** + * Called when an error is encountered to deal with it. + */ + this.handleError = function(error) { + this.status = 503; + this.statusText = error; + this.responseText = error.stack; + errorFlag = true; + setState(this.DONE); + }; + + /** + * Aborts a request. + */ + this.abort = function() { + if (request) { + request.abort(); + request = null; + } + + headers = Object.assign({}, defaultHeaders); + this.responseText = ""; + this.responseXML = ""; + + errorFlag = true; + + if (this.readyState !== this.UNSENT + && (this.readyState !== this.OPENED || sendFlag) + && this.readyState !== this.DONE) { + sendFlag = false; + setState(this.DONE); + } + this.readyState = this.UNSENT; + }; + + /** + * Adds an event listener. Preferred method of binding to events. + */ + this.addEventListener = function(event, callback) { + if (!(event in listeners)) { + listeners[event] = []; + } + // Currently allows duplicate callbacks. Should it? + listeners[event].push(callback); + }; + + /** + * Remove an event callback that has already been bound. + * Only works on the matching funciton, cannot be a copy. + */ + this.removeEventListener = function(event, callback) { + if (event in listeners) { + // Filter will return a new array with the callback removed + listeners[event] = listeners[event].filter(function(ev) { + return ev !== callback; + }); + } + }; + + /** + * Dispatch any events, including both "on" methods and events attached using addEventListener. + */ + this.dispatchEvent = function(event) { + if (typeof self["on" + event] === "function") { + self["on" + event](); + } + if (event in listeners) { + for (var i = 0, len = listeners[event].length; i < len; i++) { + listeners[event][i].call(self); + } + } + }; + + /** + * Changes readyState and calls onreadystatechange. + * + * @param int state New state + */ + var setState = function(state) { + if (self.readyState !== state) { + self.readyState = state; + + if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) { + self.dispatchEvent("readystatechange"); + } + + if (self.readyState === self.DONE && !errorFlag) { + self.dispatchEvent("load"); + // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie) + self.dispatchEvent("loadend"); + } + } + }; +}; diff --git a/node_modules/xmlhttprequest-ssl/package.json b/node_modules/xmlhttprequest-ssl/package.json new file mode 100644 index 0000000..8f05cb9 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/package.json @@ -0,0 +1,98 @@ +{ + "_args": [ + [ + { + "raw": "xmlhttprequest-ssl@~1.5.4", + "scope": null, + "escapedName": "xmlhttprequest-ssl", + "name": "xmlhttprequest-ssl", + "rawSpec": "~1.5.4", + "spec": ">=1.5.4 <1.6.0", + "type": "range" + }, + "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/engine.io-client" + ] + ], + "_from": "xmlhttprequest-ssl@>=1.5.4 <1.6.0", + "_id": "xmlhttprequest-ssl@1.5.4", + "_inCache": true, + "_location": "/xmlhttprequest-ssl", + "_nodeVersion": "7.10.0", + "_npmOperationalInternal": { + "host": "s3://npm-registry-packages", + "tmp": "tmp/xmlhttprequest-ssl-1.5.4.tgz_1506437590179_0.19159809849224985" + }, + "_npmUser": { + "name": "mjwwit", + "email": "mjwwit@gmail.com" + }, + "_npmVersion": "4.6.1", + "_phantomChildren": {}, + "_requested": { + "raw": "xmlhttprequest-ssl@~1.5.4", + "scope": null, + "escapedName": "xmlhttprequest-ssl", + "name": "xmlhttprequest-ssl", + "rawSpec": "~1.5.4", + "spec": ">=1.5.4 <1.6.0", + "type": "range" + }, + "_requiredBy": [ + "/engine.io-client" + ], + "_resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.4.tgz", + "_shasum": "04f560915724b389088715cc0ed7813e9677bf57", + "_shrinkwrap": null, + "_spec": "xmlhttprequest-ssl@~1.5.4", + "_where": "/mnt/e/Yaroslav/Documents/Webs/nodejs/checkers/node_modules/engine.io-client", + "author": { + "name": "Michael de Wit" + }, + "bugs": { + "url": "http://github.com/mjwwit/node-XMLHttpRequest/issues" + }, + "dependencies": {}, + "description": "XMLHttpRequest for Node", + "devDependencies": {}, + "directories": { + "lib": "./lib", + "example": "./example" + }, + "dist": { + "shasum": "04f560915724b389088715cc0ed7813e9677bf57", + "tarball": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.4.tgz" + }, + "engines": { + "node": ">=0.4.0" + }, + "gitHead": "b0fa1e0ddb900e28cf6cfbf8f6ade2babc4a12f9", + "homepage": "https://github.com/mjwwit/node-XMLHttpRequest#readme", + "keywords": [ + "xhr", + "ajax" + ], + "licenses": [ + { + "type": "MIT", + "url": "http://creativecommons.org/licenses/MIT/" + } + ], + "main": "./lib/XMLHttpRequest.js", + "maintainers": [ + { + "name": "mjwwit", + "email": "mjwwit@gmail.com" + } + ], + "name": "xmlhttprequest-ssl", + "optionalDependencies": {}, + "readme": "ERROR: No README data found!", + "repository": { + "type": "git", + "url": "git://github.com/mjwwit/node-XMLHttpRequest.git" + }, + "scripts": { + "test": "cd ./tests && node test-constants.js && node test-events.js && node test-exceptions.js && node test-headers.js && node test-redirect-302.js && node test-redirect-303.js && node test-redirect-307.js && node test-request-methods.js && node test-request-protocols.js" + }, + "version": "1.5.4" +} diff --git a/node_modules/xmlhttprequest-ssl/tests/test-constants.js b/node_modules/xmlhttprequest-ssl/tests/test-constants.js new file mode 100644 index 0000000..372e46c --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-constants.js @@ -0,0 +1,13 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest(); + +// Test constant values +assert.equal(0, xhr.UNSENT); +assert.equal(1, xhr.OPENED); +assert.equal(2, xhr.HEADERS_RECEIVED); +assert.equal(3, xhr.LOADING); +assert.equal(4, xhr.DONE); + +sys.puts("done"); diff --git a/node_modules/xmlhttprequest-ssl/tests/test-events.js b/node_modules/xmlhttprequest-ssl/tests/test-events.js new file mode 100644 index 0000000..c72f001 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-events.js @@ -0,0 +1,50 @@ +var sys = require("util") + , assert = require("assert") + , http = require("http") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr; + +// Test server +var server = http.createServer(function (req, res) { + var body = (req.method != "HEAD" ? "Hello World" : ""); + + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body) + }); + // HEAD has no body + if (req.method != "HEAD") { + res.write(body); + } + res.end(); + assert.equal(onreadystatechange, true); + assert.equal(readystatechange, true); + assert.equal(removed, true); + sys.puts("done"); + this.close(); +}).listen(8000); + +xhr = new XMLHttpRequest(); + +// Track event calls +var onreadystatechange = false; +var readystatechange = false; +var removed = true; +var removedEvent = function() { + removed = false; +}; + +xhr.onreadystatechange = function() { + onreadystatechange = true; +}; + +xhr.addEventListener("readystatechange", function() { + readystatechange = true; +}); + +// This isn't perfect, won't guarantee it was added in the first place +xhr.addEventListener("readystatechange", removedEvent); +xhr.removeEventListener("readystatechange", removedEvent); + +xhr.open("GET", "http://localhost:8000"); +xhr.send(); diff --git a/node_modules/xmlhttprequest-ssl/tests/test-exceptions.js b/node_modules/xmlhttprequest-ssl/tests/test-exceptions.js new file mode 100644 index 0000000..10eaea2 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-exceptions.js @@ -0,0 +1,59 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest(); + +// Test request methods that aren't allowed +try { + xhr.open("TRACK", "http://localhost:8000/"); + console.log("ERROR: TRACK should have thrown exception"); +} catch(e) {} +try { + xhr.open("TRACE", "http://localhost:8000/"); + console.log("ERROR: TRACE should have thrown exception"); +} catch(e) {} +try { + xhr.open("CONNECT", "http://localhost:8000/"); + console.log("ERROR: CONNECT should have thrown exception"); +} catch(e) {} +// Test valid request method +try { + xhr.open("GET", "http://localhost:8000/"); +} catch(e) { + console.log("ERROR: Invalid exception for GET", e); +} + +// Test forbidden headers +var forbiddenRequestHeaders = [ + "accept-charset", + "accept-encoding", + "access-control-request-headers", + "access-control-request-method", + "connection", + "content-length", + "content-transfer-encoding", + "cookie", + "cookie2", + "date", + "expect", + "host", + "keep-alive", + "origin", + "referer", + "te", + "trailer", + "transfer-encoding", + "upgrade", + "via" +]; + +for (var i in forbiddenRequestHeaders) { + if(xhr.setRequestHeader(forbiddenRequestHeaders[i], "Test") !== false) { + console.log("ERROR: " + forbiddenRequestHeaders[i] + " should have thrown exception"); + } +} + +// Try valid header +xhr.setRequestHeader("X-Foobar", "Test"); + +console.log("Done"); diff --git a/node_modules/xmlhttprequest-ssl/tests/test-headers.js b/node_modules/xmlhttprequest-ssl/tests/test-headers.js new file mode 100644 index 0000000..76454f1 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-headers.js @@ -0,0 +1,76 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest() + , http = require("http"); + +// Test server +var server = http.createServer(function (req, res) { + // Test setRequestHeader + assert.equal("Foobar", req.headers["x-test"]); + // Test non-conforming allowed header + assert.equal("node-XMLHttpRequest-test", req.headers["user-agent"]); + // Test header set with blacklist disabled + assert.equal("http://github.com", req.headers["referer"]); + + var body = "Hello World"; + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body), + // Set cookie headers to see if they're correctly suppressed + // Actual values don't matter + "Set-Cookie": "foo=bar", + "Set-Cookie2": "bar=baz", + "Date": "Thu, 30 Aug 2012 18:17:53 GMT", + "Connection": "close" + }); + res.write("Hello World"); + res.end(); + + this.close(); +}).listen(8000); + +xhr.onreadystatechange = function() { + if (this.readyState == 4) { + // Test getAllResponseHeaders() + var headers = "content-type: text/plain\r\ncontent-length: 11\r\ndate: Thu, 30 Aug 2012 18:17:53 GMT\r\nconnection: close"; + assert.equal(headers, this.getAllResponseHeaders()); + + // Test case insensitivity + assert.equal('text/plain', this.getResponseHeader('Content-Type')); + assert.equal('text/plain', this.getResponseHeader('Content-type')); + assert.equal('text/plain', this.getResponseHeader('content-Type')); + assert.equal('text/plain', this.getResponseHeader('content-type')); + + // Test aborted getAllResponseHeaders + this.abort(); + assert.equal("", this.getAllResponseHeaders()); + assert.equal(null, this.getResponseHeader("Connection")); + + sys.puts("done"); + } +}; + +assert.equal(null, xhr.getResponseHeader("Content-Type")); +try { + xhr.open("GET", "http://localhost:8000/"); + // Valid header + xhr.setRequestHeader("X-Test", "Foobar"); + // Invalid header + xhr.setRequestHeader("Content-Length", 0); + // Allowed header outside of specs + xhr.setRequestHeader("user-agent", "node-XMLHttpRequest-test"); + // Test getRequestHeader + assert.equal("Foobar", xhr.getRequestHeader("X-Test")); + // Test invalid header + assert.equal("", xhr.getRequestHeader("Content-Length")); + + // Test allowing all headers + xhr.setDisableHeaderCheck(true); + xhr.setRequestHeader("Referer", "http://github.com"); + assert.equal("http://github.com", xhr.getRequestHeader("Referer")); + + xhr.send(); +} catch(e) { + console.log("ERROR: Exception raised", e); +} diff --git a/node_modules/xmlhttprequest-ssl/tests/test-redirect-302.js b/node_modules/xmlhttprequest-ssl/tests/test-redirect-302.js new file mode 100644 index 0000000..d884f78 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-redirect-302.js @@ -0,0 +1,41 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest() + , http = require("http"); + +// Test server +var server = http.createServer(function (req, res) { + if (req.url === '/redirectingResource') { + res.writeHead(302, {'Location': 'http://localhost:8000/'}); + res.end(); + return; + } + + var body = "Hello World"; + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body), + "Date": "Thu, 30 Aug 2012 18:17:53 GMT", + "Connection": "close" + }); + res.write("Hello World"); + res.end(); + + this.close(); +}).listen(8000); + +xhr.onreadystatechange = function() { + if (this.readyState == 4) { + assert.equal(xhr.getRequestHeader('Location'), ''); + assert.equal(xhr.responseText, "Hello World"); + sys.puts("done"); + } +}; + +try { + xhr.open("GET", "http://localhost:8000/redirectingResource"); + xhr.send(); +} catch(e) { + console.log("ERROR: Exception raised", e); +} diff --git a/node_modules/xmlhttprequest-ssl/tests/test-redirect-303.js b/node_modules/xmlhttprequest-ssl/tests/test-redirect-303.js new file mode 100644 index 0000000..60d9343 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-redirect-303.js @@ -0,0 +1,41 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest() + , http = require("http"); + +// Test server +var server = http.createServer(function (req, res) { + if (req.url === '/redirectingResource') { + res.writeHead(303, {'Location': 'http://localhost:8000/'}); + res.end(); + return; + } + + var body = "Hello World"; + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body), + "Date": "Thu, 30 Aug 2012 18:17:53 GMT", + "Connection": "close" + }); + res.write("Hello World"); + res.end(); + + this.close(); +}).listen(8000); + +xhr.onreadystatechange = function() { + if (this.readyState == 4) { + assert.equal(xhr.getRequestHeader('Location'), ''); + assert.equal(xhr.responseText, "Hello World"); + sys.puts("done"); + } +}; + +try { + xhr.open("POST", "http://localhost:8000/redirectingResource"); + xhr.send(); +} catch(e) { + console.log("ERROR: Exception raised", e); +} diff --git a/node_modules/xmlhttprequest-ssl/tests/test-redirect-307.js b/node_modules/xmlhttprequest-ssl/tests/test-redirect-307.js new file mode 100644 index 0000000..3abc906 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-redirect-307.js @@ -0,0 +1,43 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr = new XMLHttpRequest() + , http = require("http"); + +// Test server +var server = http.createServer(function (req, res) { + if (req.url === '/redirectingResource') { + res.writeHead(307, {'Location': 'http://localhost:8000/'}); + res.end(); + return; + } + + assert.equal(req.method, 'POST'); + + var body = "Hello World"; + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body), + "Date": "Thu, 30 Aug 2012 18:17:53 GMT", + "Connection": "close" + }); + res.write("Hello World"); + res.end(); + + this.close(); +}).listen(8000); + +xhr.onreadystatechange = function() { + if (this.readyState == 4) { + assert.equal(xhr.getRequestHeader('Location'), ''); + assert.equal(xhr.responseText, "Hello World"); + sys.puts("done"); + } +}; + +try { + xhr.open("POST", "http://localhost:8000/redirectingResource"); + xhr.send(); +} catch(e) { + console.log("ERROR: Exception raised", e); +} diff --git a/node_modules/xmlhttprequest-ssl/tests/test-request-methods.js b/node_modules/xmlhttprequest-ssl/tests/test-request-methods.js new file mode 100644 index 0000000..fa1b1be --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-request-methods.js @@ -0,0 +1,62 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , http = require("http") + , xhr; + +// Test server +var server = http.createServer(function (req, res) { + // Check request method and URL + assert.equal(methods[curMethod], req.method); + assert.equal("/" + methods[curMethod], req.url); + + var body = (req.method != "HEAD" ? "Hello World" : ""); + + res.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": Buffer.byteLength(body) + }); + // HEAD has no body + if (req.method != "HEAD") { + res.write(body); + } + res.end(); + + if (curMethod == methods.length - 1) { + this.close(); + sys.puts("done"); + } +}).listen(8000); + +// Test standard methods +var methods = ["GET", "POST", "HEAD", "PUT", "DELETE"]; +var curMethod = 0; + +function start(method) { + // Reset each time + xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + if (method == "HEAD") { + assert.equal("", this.responseText); + } else { + assert.equal("Hello World", this.responseText); + } + + curMethod++; + + if (curMethod < methods.length) { + sys.puts("Testing " + methods[curMethod]); + start(methods[curMethod]); + } + } + }; + + var url = "http://localhost:8000/" + method; + xhr.open(method, url); + xhr.send(); +} + +sys.puts("Testing " + methods[curMethod]); +start(methods[curMethod]); diff --git a/node_modules/xmlhttprequest-ssl/tests/test-request-protocols.js b/node_modules/xmlhttprequest-ssl/tests/test-request-protocols.js new file mode 100644 index 0000000..543917d --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/test-request-protocols.js @@ -0,0 +1,32 @@ +var sys = require("util") + , assert = require("assert") + , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest + , xhr; + +xhr = new XMLHttpRequest(); + +xhr.onreadystatechange = function() { + if (this.readyState == 4) { + assert.equal("Hello World", this.responseText); + runSync(); + } +}; + +// Async +var url = "file://" + __dirname + "/testdata.txt"; +xhr.open("GET", url); +xhr.send(); + +// Sync +var runSync = function() { + xhr = new XMLHttpRequest(); + + xhr.onreadystatechange = function() { + if (this.readyState == 4) { + assert.equal("Hello World", this.responseText); + sys.puts("done"); + } + }; + xhr.open("GET", url, false); + xhr.send(); +} diff --git a/node_modules/xmlhttprequest-ssl/tests/testdata.txt b/node_modules/xmlhttprequest-ssl/tests/testdata.txt new file mode 100644 index 0000000..5e1c309 --- /dev/null +++ b/node_modules/xmlhttprequest-ssl/tests/testdata.txt @@ -0,0 +1 @@ +Hello World
\ No newline at end of file |