Blame view
node_modules/nodemailer/lib/http-proxy.js
3.79 KB
f7563de62
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
'use strict'; /** * Minimal HTTP/S proxy client */ var net = require('net'); var tls = require('tls'); var urllib = require('url'); module.exports = proxyConnect; /** * Establishes proxied connection to destinationPort * * proxyConnect("http://localhost:3128/", 80, "google.com", function(err, socket){ * socket.write("GET / HTTP/1.0\r \r "); * }); * * @param {String} proxyUrl proxy configuration, etg "http://proxy.host:3128/" * @param {Number} destinationPort Port to open in destination host * @param {String} destinationHost Destination hostname * @param {Function} callback Callback to run with the rocket object once connection is established */ function proxyConnect(proxyUrl, destinationPort, destinationHost, callback) { var proxy = urllib.parse(proxyUrl); // create a socket connection to the proxy server var options; var connect; var socket; options = { host: proxy.hostname, port: Number(proxy.port) ? Number(proxy.port) : (proxy.protocol === 'https:' ? 443 : 80) }; if (proxy.protocol === 'https:') { // we can use untrusted proxies as long as we verify actual SMTP certificates options.rejectUnauthorized = false; connect = tls.connect.bind(tls); } else { connect = net.connect.bind(net); } // Error harness for initial connection. Once connection is established, the responsibility // to handle errors is passed to whoever uses this socket var finished = false; var tempSocketErr = function (err) { if (finished) { return; } finished = true; try { socket.destroy(); } catch (E) { // ignore } callback(err); }; socket = connect(options, function () { if (finished) { return; } var reqHeaders = { Host: destinationHost + ':' + destinationPort, Connection: 'close' }; if (proxy.auth) { reqHeaders['Proxy-Authorization'] = 'Basic ' + new Buffer(proxy.auth).toString('base64'); } socket.write( // HTTP method 'CONNECT ' + destinationHost + ':' + destinationPort + ' HTTP/1.1\r ' + // HTTP request headers Object.keys(reqHeaders).map(function (key) { return key + ': ' + reqHeaders[key]; }).join('\r ') + // End request '\r \r '); var headers = ''; var onSocketData = function (chunk) { var match; var remainder; if (finished) { return; } headers += chunk.toString('binary'); if ((match = headers.match(/\r \r /))) { socket.removeListener('data', onSocketData); remainder = headers.substr(match.index + match[0].length); headers = headers.substr(0, match.index); if (remainder) { socket.unshift(new Buffer(remainder, 'binary')); } // proxy connection is now established finished = true; socket.removeListener('error', tempSocketErr); // check response code match = headers.match(/^HTTP\/\d+\.\d+ (\d+)/i); if (!match || (match[1] || '').charAt(0) !== '2') { try { socket.destroy(); } catch (E) { // ignore } return callback(new Error('Invalid response from proxy' + (match && ': ' + match[1] || ''))); } return callback(null, socket); } }; socket.on('data', onSocketData); }); socket.once('error', tempSocketErr); } |