[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\n\nnode_js:\n  - \"8.1\"\n  - \"6.11\"\n\nscript: make test\n"
  },
  {
    "path": "Makefile",
    "content": "test: index.js lib/*.js node_modules\n\t./node_modules/.bin/mocha \\\n\t\t--reporter dot \\\n\t\t--check-leaks \\\n\t\t--ui tdd\n\nnode_modules: package.json\n\tnpm install\n\ttouch $@\n\n.PHONY: test\n"
  },
  {
    "path": "README.md",
    "content": "# SOCKS5 HTTPS Client #\n\n[![Build Status](https://travis-ci.org/mattcg/socks5-https-client.png?branch=master)](https://travis-ci.org/mattcg/socks5-https-client)\n\nSOCKS v5 HTTPS client implementation in JavaScript for Node.js.\n\n```js\nvar shttps = require('socks5-https-client');\n\nshttps.get({\n\thostname: 'encrypted.google.com',\n\tpath: '/',\n\trejectUnauthorized: true // This is the default.\n}, function(res) {\n\tres.setEncoding('utf8');\n\tres.on('readable', function() {\n\t\tconsole.log(res.read()); // Log response to console.\n\t});\n});\n```\n\nSpecify the `socksHost` and `socksPort` options if your SOCKS server isn't running on `localhost:1080`. Tor runs its SOCKS server on port `9050` by default, for example.\n\nUsername and password authentication is supported with the `socksUsername` and `socksPassword` options.\n\nYou may also pass a URL as the first argument to `get` or `request`, which will be parsed using `url.parse`.\n\n## Using with Tor ##\n\nWorks great for making HTTPS requests through [Tor](https://www.torproject.org/).\n\nMake sure a Tor server is running locally and run `node example/tor https://check.torproject.org/` to test.\n\n## Using with Request ##\n\nTo use with [Request](https://github.com/mikeal/request), just pass a reference to the `Agent` constructor..\n\n```js\nvar Agent = require('socks5-https-client/lib/Agent');\n\nrequest({\n\turl: 'https://encrypted.google.com/',\n\tstrictSSL: true,\n\tagentClass: Agent,\n\tagentOptions: {\n\t\tsocksHost: 'my-tor-proxy-host', // Defaults to 'localhost'.\n\t\tsocksPort: 9050, // Defaults to 1080.\n\n\t\t// Optional credentials\n\t\tsocksUsername: 'proxyuser',\n\t\tsocksPassword: 'p@ssw0rd',\n\t}\n}, function(err, res) {\n\tconsole.log(err || res.body);\n});\n```\n\n## HTTP ##\n\nThis client only provides support for making HTTPS requests. See [socks5-http-client](https://github.com/mattcg/socks5-http-client) for an HTTP implementation.\n\n## License ##\n\nCopyright © 2013 [Matthew Caruana Galizia](http://twitter.com/mcaruanagalizia), licensed under an [MIT license](http://mattcg.mit-license.org/).\n"
  },
  {
    "path": "example/tor-request.js",
    "content": "'use strict';\n\n/*jshint node:true*/\n\nvar request = require('request');\n\nvar Agent = require('../lib/Agent');\n\nrequest({\n\turl: process.argv[2],\n\tagentClass: Agent,\n\tagentOptions: {\n\t\tsocksPort: 9050 // Defaults to 1080.\n\t}\n}, function(err, res) {\n\tconsole.log(res.body);\n});\n"
  },
  {
    "path": "example/tor.js",
    "content": "'use strict';\n\n/*jshint node:true*/\n\nvar url = require('url');\nvar shttps = require('../');\n\nvar options = url.parse(process.argv[2]);\n\noptions.socksPort = 9050; // Tor default port.\n\nvar req = shttps.get(options, function(res) {\n\tres.setEncoding('utf8');\n\n\tres.on('readable', function() {\n\t\tvar data = res.read();\n\n\t\t// Check for the end of stream signal.\n\t\tif (null === data) {\n\t\t\tprocess.stdout.write('\\n');\n\t\t\treturn;\n\t\t}\n\n\t\tprocess.stdout.write(data);\n\t});\n});\n\nreq.on('error', function(e) {\n\tconsole.error('Problem with request: ' + e.message);\n});\n\n// GET request, so end without sending any data.\nreq.end();\n"
  },
  {
    "path": "index.js",
    "content": "/**\n * @overview\n * @author Matthew Caruana Galizia <m@m.cg>\n * @license MIT\n * @copyright Copyright (c) 2013, Matthew Caruana Galizia\n */\n\n'use strict';\n\n/*jshint node:true*/\n\nvar https = require('https');\nvar url = require('url');\n\nvar Agent = require('./lib/Agent');\n\nexports.request = function(options, cb) {\n\tvar agent, version;\n\n\tif (typeof options === 'string') {\n\t\toptions = url.parse(options);\n\t}\n\n\toptions.protocol = 'https:';\n\n\t// Node v0.12.0 requires the port to be specified.\n\tif (!options.port && options.host) {\n\t\toptions.port = options.host.split(':')[1];\n\t}\n\n\tif (!options.port) {\n\t\toptions.port = 443;\n\t}\n\n\tagent = new Agent(options);\n\toptions.agent = agent;\n\n\treturn https.request(options, cb);\n};\n\nexports.Agent = Agent;\n\nexports.get = function(options, cb) {\n\tvar req = exports.request(options, cb);\n\n\treq.end();\n\n\treturn req;\n};\n"
  },
  {
    "path": "lib/Agent.js",
    "content": "/**\n * @overview\n * @author Matthew Caruana Galizia <m@m.cg>\n * @license MIT\n * @copyright Copyright (c) 2013, Matthew Caruana Galizia\n */\n\n'use strict';\n\n/*jshint node:true*/\n\nvar tls = require('tls');\nvar https = require('https');\nvar inherits = require('util').inherits;\n\nvar socksClient = require('socks5-client');\n\nfunction createConnection(options) {\n\tvar socksSocket, onProxied;\n\n\tsocksSocket = socksClient.createConnection(options);\n\n\tonProxied = socksSocket.onProxied;\n\tsocksSocket.onProxied = function() {\n\t\toptions.socket = socksSocket.socket;\n\n\t\tif (options.hostname) {\n\t\t\toptions.servername = options.hostname;\n\t\t} else if (options.host) {\n\t\t\toptions.servername = options.host.split(':')[0];\n\t\t}\n\n\t\tsocksSocket.socket = tls.connect(options, function() {\n\n\t\t\t// Set the 'authorized flag for clients that check it.\n\t\t\tsocksSocket.authorized = socksSocket.socket.authorized;\n\t\t\tonProxied.call(socksSocket);\n\t\t});\n\n\t\tsocksSocket.socket.on('error', function(err) {\n\t\t\tsocksSocket.emit('error', err);\n\t\t});\n\t};\n\n\treturn socksSocket;\n}\n\nfunction Agent(options) {\n\thttps.Agent.call(this, options);\n\n\tthis.socksHost = options.socksHost || 'localhost';\n\tthis.socksPort = options.socksPort || 1080;\n\n\tthis.createConnection = createConnection;\n}\n\ninherits(Agent, https.Agent);\n\nmodule.exports = Agent;\n"
  },
  {
    "path": "package.json",
    "content": "{\n\t\"name\": \"socks5-https-client\",\n\t\"description\": \"SOCKS v5 HTTPS client.\",\n\t\"version\": \"1.2.1\",\n\t\"main\": \"index.js\",\n\t\"homepage\": \"https://github.com/mattcg/socks5-https-client\",\n\t\"implements\": [\"CommonJS/Modules/1.0\"],\n\t\"author\": {\n\t\t\"name\": \"Matthew Caruana Galizia\",\n\t\t\"email\": \"mattcg@gmail.com\"\n\t},\n\t\"keywords\": [\n\t\t\"socks5\", \"socksv5\", \"socks\", \"v5\", \"https\", \"ssl\", \"tls\", \"tor\", \"client\"\n\t],\n\t\"bugs\": {\n\t\t\"url\": \"https://github.com/mattcg/socks5-https-client/issues\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"https://github.com/mattcg/socks5-https-client.git\"\n\t},\n\t\"dependencies\": {\n\t\t\"socks5-client\": \"~1.2.3\"\n\t},\n\t\"devDependencies\": {\n\t\t\"mocha\": \"~3.1.2\",\n\t\t\"node-socks\": \"~0.1.0\",\n\t\t\"request\": \"~2.72.0\"\n\t},\n\t\"scripts\": {\n\t\t\"test\": \"make test\"\n\t},\n\t\"engines\": {\n\t\t\"node\": \">= 6.4.0\"\n\t},\n\t\"license\": \"MIT\"\n}\n"
  },
  {
    "path": "test/index.js",
    "content": "/**\n * @overview\n * @author Matthew Caruana Galizia <m@m.cg>\n * @copyright Copyright (c) 2013, Matthew Caruana Galizia\n * @license MIT\n * @preserve\n */\n\n'use strict';\n\n/*jshint node:true*/\n/*global test, suite, setup*/\n\nvar assert = require('assert');\nvar net = require('net');\nvar request = require('request');\nvar socks = require('node-socks/socks.js');\nvar https = require('../');\nvar Agent = require('../lib/Agent');\n\nsuite('socks5-https-client tests', function() {\n\tvar server;\n\n\tthis.timeout(5000);\n\n\tsuiteSetup(function(done) {\n\t\tserver = socks.createServer(function(socket, port, address, proxyReady) {\n\t\t\tvar proxy;\n\n\t\t\tproxy = net.createConnection(port, address, proxyReady);\n\n\t\t\tproxy.on('data', function(data) {\n\t\t\t\tsocket.write(data);\n\t\t\t});\n\n\t\t\tsocket.on('data', function(data) {\n\t\t\t\tproxy.write(data);\n\t\t\t});\n\n\t\t\tproxy.on('close', function() {\n\t\t\t\tsocket.end();\n\t\t\t});\n\n\t\t\tsocket.on('close', function() {\n\t\t\t\tproxy.removeAllListeners('data');\n\t\t\t\tproxy.end();\n\t\t\t});\n\t\t});\n\n\t\tserver.listen(1080, 'localhost', 511, function() {\n\t\t\tdone();\n\t\t});\n\n\t\tserver.on('error', function(err) {\n\t\t\tthrow err;\n\t\t});\n\t});\n\n\ttest('simple request', function(done) {\n\t\tvar req;\n\n\t\treq = https.request('https://en.wikipedia.org/wiki/Main_Page', function(res, err) {\n\t\t\tvar data = '';\n\n\t\t\tassert.ifError(err);\n\t\t\tassert.equal(res.statusCode, 200);\n\n\t\t\tres.setEncoding('utf8');\n\t\t\tres.on('readable', function() {\n\t\t\t\tdata += res.read();\n\t\t\t});\n\n\t\t\tres.on('end', function() {\n\t\t\t\tassert(-1 !== data.indexOf('<html'));\n\t\t\t\tassert(-1 !== data.indexOf('</html>'));\n\n\t\t\t\tdone();\n\t\t\t});\n\t\t});\n\n\t\treq.on('error', function(err) {\n\t\t\tassert.fail(err);\n\t\t});\n\n\t\t// GET request, so end without sending any data.\n\t\treq.end();\n\t});\n\n\ttest('using request', function(done) {\n\t\tvar req;\n\n\t\trequest({\n\t\t\turl: 'https://encrypted.google.com/',\n\t\t\tagentClass: Agent,\n\t\t\tstrictSSL: true\n\t\t}, function(err, res, data) {\n\t\t\tassert.ifError(err);\n\t\t\tassert.equal(res.statusCode, 200);\n\n\t\t\tassert(-1 !== data.indexOf('<html'));\n\t\t\tassert(-1 !== data.indexOf('</html>'));\n\n\t\t\tdone();\n\t\t});\n\t});\n});\n"
  }
]