Closed pablosbrain closed 8 years ago
This is the same issue I reported earlier - http is not "required" in. If you want to fix it yourself simple add
var http = require("http");
at the top of the file, otherwise create a PR to fix it.
Will give it a try when i'm back in the office after the weekend. I must have missed your earlier report when looking around. Thank you for the quick response!
Getting "TypeError('Request path contains unescaped characters.');"
In the proxy.js file where it is putting together the connection like so...
path : opts.host + ':' + opts.port,
I am getting this in the output.
"path": "[object Object]:undefined",
@pablosbrain, I've just pushed the latest patch release (v0.3.0
) which should be available through npm soon. We had a PR sometime ago that (I believe) fixed this issue.
Could you please see if the latest version fixes your issue, and let me know the results?
Thanks!
Thanks for the update. I downloaded the 0.3.0 zip. Modified the start of line 13 section this.createConnection = function (opts, callback) { to have this for logging.
this.createConnection = function (opts, callback) {
// do a CONNECT request
console.log("opts passed in:", JSON.stringify(opts));
console.log("opts.host passed in:", JSON.stringify(opts.host));
console.log("opts.port passed in:", JSON.stringify(opts.port));
var reqopts = {
host : options.proxyHost,
port : options.proxyPort,
method : 'CONNECT',
path : opts.host + ':' + opts.port,
headers : {
host: opts.host
}
};
console.log("createConnection reqopts", JSON.stringify(reqopts));
var req = http.request(reqopts);
...
opts.port ends up "undefined" and opts.host isn't a string. I console.logged the opts.host object to get this:
{ "_defaultAgent": { "domain": null, "_events": {}, "_eventsCount": 1, "defaultPort": 443, "protocol": "https:", "options": { "path": null }, "requests": {}, "sockets": {}, "freeSockets": {}, "keepAliveMsecs": 1000, "keepAlive": false, "maxSockets": null, "maxFreeSockets": 256, "maxCachedSessions": 100, "_sessionCache": { "map": {}, "list": [] } }, "path": "/ListVoices", "host": "tts.eu-west-1.ivonacloud.com", "buffer": true, "service": "tts", "method": "POST", "region": "eu-west-1", "proxy": { "host": "proxy.internal.com", "port": 80 }, "headers": { "content-type": "application/json", "Host": "tts.eu-west-1.ivonacloud.com", "Content-Length": 11, "X-Amz-Date": "20160516T150827Z", "Authorization": "AWS4-HMAC-SHA256 Credential=accesskeyhere/20160516/eu-west-1/tts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=eb0683e1c627f833cfc7ce6e15071f239756cc471a4e17c9740708f64d416fe6" }, "body": "{\"Body\":{}}", "agent": { "domain": null, "_events": {}, "_eventsCount": 1, "defaultPort": 443, "protocol": "https:", "options": { "proxyPort": 80, "proxyHost": "proxy.internal.com", "path": null }, "requests": {}, "sockets": { "[object Object]:undefined": [] }, "freeSockets": {}, "keepAliveMsecs": 1000, "keepAlive": false, "maxSockets": null, "maxFreeSockets": 256, "maxCachedSessions": 100, "_sessionCache": { "map": {}, "list": [] }, "proxyHost": "proxy.internal.com", "proxyPort": 80 }, "port": 443 }
Still getting
_http_client.js:53 throw new TypeError('Request path contains unescaped characters.'); ^
And the request object outputs to that below. Will keep digging. Not sure what may be causing the non escaped character error.
requestParams: { path: '/ListVoices',
host: 'tts.us-east-1.ivonacloud.com',
buffer: true,
service: 'tts',
method: 'POST',
region: 'us-east-1',
proxy: { host: 'proxy.internal.com', port: 80 },
headers:
{ 'content-type': 'application/json',
Host: 'tts.us-east-1.ivonacloud.com',
'Content-Length': 11,
'X-Amz-Date': '20160517T193249Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=IVONAACCESSKEY/20160517/us-east-1/tts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=d25467b95934fae2e3e86586a2774a225646869c831d2481408d8268599306bd' },
body: '{"Body":{}}' }
agentdata: { proxyHost: 'proxy.internal.com', proxyPort: 80 }
requestParams: { path: '/ListVoices',
host: 'tts.us-east-1.ivonacloud.com',
buffer: true,
service: 'tts',
method: 'POST',
region: 'us-east-1',
proxy: { host: 'proxy.internal.com', port: 80 },
headers:
{ 'content-type': 'application/json',
Host: 'tts.us-east-1.ivonacloud.com',
'Content-Length': 11,
'X-Amz-Date': '20160517T193249Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=IVONAACCESSKEY/20160517/us-east-1/tts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=d25467b95934fae2e3e86586a2774a225646869c831d2481408d8268599306bd' },
body: '{"Body":{}}',
agent:
HttpsProxyAgent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { proxyPort: 80, proxyHost: 'proxy.internal.com', path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] },
proxyHost: 'proxy.internal.com',
proxyPort: 80,
createConnection: [Function] } }
Starting in proxy.js on line 13... v0.3.0
this.createConnection = function (opts, callback) {
// do a CONNECT request
var req = http.request({
host : options.proxyHost,
port : options.proxyPort,
method : 'CONNECT',
path : opts.host + ':' + opts.port,
headers : {
host: opts.host
}
});
I'm getting the following when logging the data out. options.proxyHost: proxy.internal.com options.proxyPort: 80 opts.port: undefined opts.host:
{ _defaultAgent:
Agent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] } },
path: '/ListVoices',
host: 'tts.us-east-1.ivonacloud.com',
buffer: true,
service: 'tts',
method: 'POST',
region: 'us-east-1',
proxy: { host: 'proxy.internal.com', port: 80 },
headers:
{ 'content-type': 'application/json',
Host: 'tts.us-east-1.ivonacloud.com',
'Content-Length': 11,
'X-Amz-Date': '20160517T194127Z',
Authorization: 'AWS4-HMAC-SHA256 Credential=IVONAACCESSKEY/20160517/us-east-1/tts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date, Signature=be771b146c52a3697dc4c12fcafed74728e8d86d90c65c773037eeb1a675de25' },
body: '{"Body":{}}',
agent:
HttpsProxyAgent {
domain: null,
_events: { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: { proxyPort: 80, proxyHost: 'proxy.internal.com', path: null },
requests: {},
sockets: { '[object Object]:undefined': [] },
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: { map: {}, list: [] },
proxyHost: 'proxy.internal.com',
proxyPort: 80,
createConnection: [Function] },
port: 443 }
based on that object output are the following supposed to be this? opts.port: 443 opts.host: 'tts.us-east-1.ivonacloud.com',
If so.. would changing it to be the below be close or am i following the wrong path for that.
path : opts.host.Agent.host + ':' + opts.port.port,
Now getting:
opts.host.host: tts.us-east-1.ivonacloud.com opts.host.port: 443
With this:
this.createConnection = function (opts, callback) {
// do a CONNECT request
var reqdata = {
host : options.proxyHost,
port : options.proxyPort,
method : 'CONNECT',
path : opts.host.host + ':' + opts.host.port,
headers : {
host: opts.host
}
};
console.log("opts.host.host:\t", opts.host.host);
console.log("opts.host.port:\t", opts.host.port);
console.log("reqdata:\t", reqdata);
var req = http.request(reqdata);
Now the error is:
_http_agent.js:162
options.servername = hostHeader.replace(/:.*$/, '');
^
TypeError: hostHeader.replace is not a function
at Agent.createSocket (_http_agent.js:162:41)
at Agent.addRequest (_http_agent.js:141:23)
at new ClientRequest (_http_client.js:137:16)
at Object.exports.request (http.js:31:10)
at HttpsProxyAgent.createConnection (C:\Users\user\Desktop\ivonatts\node_modules\ivona-node\src\proxy.js:31:24)
at HttpsProxyAgent.createSocket (C:\Users\user\Desktop\ivonatts\node_modules\ivona-node\src\proxy.js:88:10)
at HttpsProxyAgent.addRequest (C:\Users\user\Desktop\ivonatts\node_modules\ivona-node\src\proxy.js:61:14)
at new ClientRequest (_http_client.js:137:16)
at Object.exports.request (http.js:31:10)
at Object.exports.request (https.js:181:15)
Corrected this:
headers : {
host: opts.host
}
to this:
headers : {
host: opts.host.host
}
And this...
req.on('connect', function (res, socket, head) {
var cts = Tls.connect({
host: opts.host,
socket: socket
}, function () {
callback(false, cts);
});
});
To:
req.on('connect', function (res, socket, head) {
var cts = Tls.connect({
host: opts.host.host,
socket: socket
}, function () {
callback(false, cts);
});
});
And tada it finally works. I'll post once more with a working modified proxy.js file.
Here is my corrected proxy.js file
var util = require('util'),
http = require('http'),
https = require('https'),
Tls = require('tls');
// HttpsProxyAgent for handling proxying
function HttpsProxyAgent(options) {
https.Agent.call(this, options);
this.proxyHost = options.proxyHost;
this.proxyPort = options.proxyPort;
this.createConnection = function (opts, callback) {
// do a CONNECT request
var reqdata = {
host : options.proxyHost,
port : options.proxyPort,
method : 'CONNECT',
path : opts.host.host + ':' + opts.host.port,
headers : {
host: opts.host.host
}
};
//console.log("opts.host:\t", opts.host);
//console.log("opts.port:\t", opts.port);
//console.log("opts.host.host:\t", opts.host.host);
//console.log("opts.host.port:\t", opts.host.port);
console.log("reqdata:\t", reqdata);
var req = http.request(reqdata);
req.on('connect', function (res, socket, head) {
var cts = Tls.connect({
host: opts.host.host,
socket: socket
}, function () {
callback(false, cts);
});
});
req.on('error', function (err) {
callback(err, null);
});
req.end();
};
}
util.inherits(HttpsProxyAgent, https.Agent);
// Almost verbatim copy of http.Agent.addRequest
HttpsProxyAgent.prototype.addRequest = function (req, host, port, localAddress) {
var name = host + ':' + port;
if (localAddress) name += ':' + localAddress;
if (!this.sockets[name]) this.sockets[name] = [];
if (this.sockets[name].length < this.maxSockets) {
// if we are under maxSockets create a new one.
this.createSocket(name, host, port, localAddress, req, function (socket) {
req.onSocket(socket);
});
} else {
// we are over limit so we'll add it to the queue.
if (!this.requests[name])
this.requests[name] = [];
this.requests[name].push(req);
}
};
// Almost verbatim copy of http.Agent.createSocket
HttpsProxyAgent.prototype.createSocket = function (name, host, port, localAddress, req, callback) {
var self = this;
var options = util._extend({}, self.options);
options.port = port;
options.host = host;
options.localAddress = localAddress;
options.servername = host;
if (req) {
var hostHeader = req.getHeader('host');
if (hostHeader)
options.servername = hostHeader.replace(/:.*$/, '');
}
self.createConnection(options, function (err, s) {
if (err) {
err.message += ' while connecting to HTTP(S) proxy server ' + self.proxyHost + ':' + self.proxyPort;
if (req)
req.emit('error', err);
else
throw err;
return;
}
if (!self.sockets[name]) self.sockets[name] = [];
self.sockets[name].push(s);
var onFree = function () {
self.emit('free', s, host, port, localAddress);
};
var onClose = function (err) {
// this is the only place where sockets get removed from the Agent.
// if you want to remove a socket from the pool, just close it.
// all socket errors end in a close event anyway.
self.removeSocket(s, name, host, port, localAddress);
};
var onRemove = function () {
// we need this function for cases like HTTP 'upgrade'
// (defined by WebSockets) where we need to remove a socket from the pool
// because it'll be locked up indefinitely
self.removeSocket(s, name, host, port, localAddress);
s.removeListener('close', onClose);
s.removeListener('free', onFree);
s.removeListener('agentRemove', onRemove);
};
s.on('free', onFree);
s.on('close', onClose);
s.on('agentRemove', onRemove);
callback(s);
});
};
module.exports = HttpsProxyAgent;
Will do! I'm very excited to spend time tomorrow working with this now!
@pablosbrain, great to hear!
Thank you!
{ [NetworkingError: connect ECONNREFUSED] message: 'connect ECONNREFUSED', code: 'NetworkingError', errno: 'ECONNREFUSED', syscall: 'connect', region: 'ap-south-1', hostname: 'asset-mmp-example.s3.ap-south-1.amazonaws.com', retryable: true, time: Fri Jun 02 2017 12:56:09 GMT-0700 (Pacific Daylight Time) }
Using Node v5.5.0 64bit I am getting the following error.
Here is my config.
Hopefully it may be an easy fix. The lib works great outside a firewall. Just having issues getting through a corporate proxy.