Repository: mattcg/socks5-https-client Branch: master Commit: 5234fe7c61a6 Files: 10 Total size: 8.0 KB Directory structure: gitextract_r4cc09dl/ ├── .gitignore ├── .travis.yml ├── Makefile ├── README.md ├── example/ │ ├── tor-request.js │ └── tor.js ├── index.js ├── lib/ │ └── Agent.js ├── package.json └── test/ └── index.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store node_modules ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - "8.1" - "6.11" script: make test ================================================ FILE: Makefile ================================================ test: index.js lib/*.js node_modules ./node_modules/.bin/mocha \ --reporter dot \ --check-leaks \ --ui tdd node_modules: package.json npm install touch $@ .PHONY: test ================================================ FILE: README.md ================================================ # SOCKS5 HTTPS Client # [![Build Status](https://travis-ci.org/mattcg/socks5-https-client.png?branch=master)](https://travis-ci.org/mattcg/socks5-https-client) SOCKS v5 HTTPS client implementation in JavaScript for Node.js. ```js var shttps = require('socks5-https-client'); shttps.get({ hostname: 'encrypted.google.com', path: '/', rejectUnauthorized: true // This is the default. }, function(res) { res.setEncoding('utf8'); res.on('readable', function() { console.log(res.read()); // Log response to console. }); }); ``` Specify 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. Username and password authentication is supported with the `socksUsername` and `socksPassword` options. You may also pass a URL as the first argument to `get` or `request`, which will be parsed using `url.parse`. ## Using with Tor ## Works great for making HTTPS requests through [Tor](https://www.torproject.org/). Make sure a Tor server is running locally and run `node example/tor https://check.torproject.org/` to test. ## Using with Request ## To use with [Request](https://github.com/mikeal/request), just pass a reference to the `Agent` constructor.. ```js var Agent = require('socks5-https-client/lib/Agent'); request({ url: 'https://encrypted.google.com/', strictSSL: true, agentClass: Agent, agentOptions: { socksHost: 'my-tor-proxy-host', // Defaults to 'localhost'. socksPort: 9050, // Defaults to 1080. // Optional credentials socksUsername: 'proxyuser', socksPassword: 'p@ssw0rd', } }, function(err, res) { console.log(err || res.body); }); ``` ## HTTP ## This client only provides support for making HTTPS requests. See [socks5-http-client](https://github.com/mattcg/socks5-http-client) for an HTTP implementation. ## License ## Copyright © 2013 [Matthew Caruana Galizia](http://twitter.com/mcaruanagalizia), licensed under an [MIT license](http://mattcg.mit-license.org/). ================================================ FILE: example/tor-request.js ================================================ 'use strict'; /*jshint node:true*/ var request = require('request'); var Agent = require('../lib/Agent'); request({ url: process.argv[2], agentClass: Agent, agentOptions: { socksPort: 9050 // Defaults to 1080. } }, function(err, res) { console.log(res.body); }); ================================================ FILE: example/tor.js ================================================ 'use strict'; /*jshint node:true*/ var url = require('url'); var shttps = require('../'); var options = url.parse(process.argv[2]); options.socksPort = 9050; // Tor default port. var req = shttps.get(options, function(res) { res.setEncoding('utf8'); res.on('readable', function() { var data = res.read(); // Check for the end of stream signal. if (null === data) { process.stdout.write('\n'); return; } process.stdout.write(data); }); }); req.on('error', function(e) { console.error('Problem with request: ' + e.message); }); // GET request, so end without sending any data. req.end(); ================================================ FILE: index.js ================================================ /** * @overview * @author Matthew Caruana Galizia * @license MIT * @copyright Copyright (c) 2013, Matthew Caruana Galizia */ 'use strict'; /*jshint node:true*/ var https = require('https'); var url = require('url'); var Agent = require('./lib/Agent'); exports.request = function(options, cb) { var agent, version; if (typeof options === 'string') { options = url.parse(options); } options.protocol = 'https:'; // Node v0.12.0 requires the port to be specified. if (!options.port && options.host) { options.port = options.host.split(':')[1]; } if (!options.port) { options.port = 443; } agent = new Agent(options); options.agent = agent; return https.request(options, cb); }; exports.Agent = Agent; exports.get = function(options, cb) { var req = exports.request(options, cb); req.end(); return req; }; ================================================ FILE: lib/Agent.js ================================================ /** * @overview * @author Matthew Caruana Galizia * @license MIT * @copyright Copyright (c) 2013, Matthew Caruana Galizia */ 'use strict'; /*jshint node:true*/ var tls = require('tls'); var https = require('https'); var inherits = require('util').inherits; var socksClient = require('socks5-client'); function createConnection(options) { var socksSocket, onProxied; socksSocket = socksClient.createConnection(options); onProxied = socksSocket.onProxied; socksSocket.onProxied = function() { options.socket = socksSocket.socket; if (options.hostname) { options.servername = options.hostname; } else if (options.host) { options.servername = options.host.split(':')[0]; } socksSocket.socket = tls.connect(options, function() { // Set the 'authorized flag for clients that check it. socksSocket.authorized = socksSocket.socket.authorized; onProxied.call(socksSocket); }); socksSocket.socket.on('error', function(err) { socksSocket.emit('error', err); }); }; return socksSocket; } function Agent(options) { https.Agent.call(this, options); this.socksHost = options.socksHost || 'localhost'; this.socksPort = options.socksPort || 1080; this.createConnection = createConnection; } inherits(Agent, https.Agent); module.exports = Agent; ================================================ FILE: package.json ================================================ { "name": "socks5-https-client", "description": "SOCKS v5 HTTPS client.", "version": "1.2.1", "main": "index.js", "homepage": "https://github.com/mattcg/socks5-https-client", "implements": ["CommonJS/Modules/1.0"], "author": { "name": "Matthew Caruana Galizia", "email": "mattcg@gmail.com" }, "keywords": [ "socks5", "socksv5", "socks", "v5", "https", "ssl", "tls", "tor", "client" ], "bugs": { "url": "https://github.com/mattcg/socks5-https-client/issues" }, "repository": { "type": "git", "url": "https://github.com/mattcg/socks5-https-client.git" }, "dependencies": { "socks5-client": "~1.2.3" }, "devDependencies": { "mocha": "~3.1.2", "node-socks": "~0.1.0", "request": "~2.72.0" }, "scripts": { "test": "make test" }, "engines": { "node": ">= 6.4.0" }, "license": "MIT" } ================================================ FILE: test/index.js ================================================ /** * @overview * @author Matthew Caruana Galizia * @copyright Copyright (c) 2013, Matthew Caruana Galizia * @license MIT * @preserve */ 'use strict'; /*jshint node:true*/ /*global test, suite, setup*/ var assert = require('assert'); var net = require('net'); var request = require('request'); var socks = require('node-socks/socks.js'); var https = require('../'); var Agent = require('../lib/Agent'); suite('socks5-https-client tests', function() { var server; this.timeout(5000); suiteSetup(function(done) { server = socks.createServer(function(socket, port, address, proxyReady) { var proxy; proxy = net.createConnection(port, address, proxyReady); proxy.on('data', function(data) { socket.write(data); }); socket.on('data', function(data) { proxy.write(data); }); proxy.on('close', function() { socket.end(); }); socket.on('close', function() { proxy.removeAllListeners('data'); proxy.end(); }); }); server.listen(1080, 'localhost', 511, function() { done(); }); server.on('error', function(err) { throw err; }); }); test('simple request', function(done) { var req; req = https.request('https://en.wikipedia.org/wiki/Main_Page', function(res, err) { var data = ''; assert.ifError(err); assert.equal(res.statusCode, 200); res.setEncoding('utf8'); res.on('readable', function() { data += res.read(); }); res.on('end', function() { assert(-1 !== data.indexOf('')); done(); }); }); req.on('error', function(err) { assert.fail(err); }); // GET request, so end without sending any data. req.end(); }); test('using request', function(done) { var req; request({ url: 'https://encrypted.google.com/', agentClass: Agent, strictSSL: true }, function(err, res, data) { assert.ifError(err); assert.equal(res.statusCode, 200); assert(-1 !== data.indexOf('')); done(); }); }); });