UNPKG

unblocker

Version:

Web proxy for evading internet censorship & general-purpose library for rewriting remote websites.

101 lines (80 loc) 2.85 kB
"use strict"; var URL = require("url"), http = require("http"), https = require("https"), _ = require("lodash"), contentTypes = require("./content-types.js"), debug = require("debug")("unblocker:proxy"); function proxy(config) { /** * Makes the outgoing request and relays it to the client, modifying it along the way if necessary */ function proxyRequest(data, next) { debug("proxying %s %s", data.clientRequest.method, data.url); var middlewareHandledRequest = _.some( config.requestMiddleware, function (middleware) { middleware(data); return data.clientResponse.headersSent; // if true, then _.some will stop processing middleware here because we can no longer } ); if (!middlewareHandledRequest) { var uri = URL.parse(data.url); var options = { host: uri.hostname, port: uri.port, path: uri.path, method: data.clientRequest.method, headers: data.headers, }; //set the agent for the request. if (uri.protocol == "http:" && config.httpAgent) { options.agent = config.httpAgent; } if (uri.protocol == "https:" && config.httpsAgent) { options.agent = config.httpsAgent; } // what protocol to use for outgoing connections. var proto = uri.protocol == "https:" ? https : http; debug("sending remote request: ", options); data.remoteRequest = proto.request(options, function (remoteResponse) { data.remoteResponse = remoteResponse; data.remoteResponse.on("error", next); proxyResponse(data); }); data.remoteRequest.on("error", next); // pass along POST data & let the remote server know when we're done sending data data.stream.pipe(data.remoteRequest); } } function proxyResponse(data) { debug( "proxying %s response for %s", data.remoteResponse.statusCode, data.url ); // make a copy of the headers to fiddle with data.headers = _.cloneDeep(data.remoteResponse.headers); debug("remote response headers", data.headers); // create a stream object for middleware to pipe from and overwrite data.stream = data.remoteResponse; data.contentType = contentTypes.getType(data); var middlewareHandledResponse = _.some( config.responseMiddleware, function (middleware) { middleware(data); return data.clientResponse.headersSent; // if true, then _.some will stop processing middleware here } ); if (!middlewareHandledResponse) { // fire off out (possibly modified) headers data.clientResponse.writeHead( data.remoteResponse.statusCode, data.headers ); data.stream.pipe(data.clientResponse); } } return proxyRequest; } module.exports = proxy;