tomas / needle

Nimble, streamable HTTP client for Node.js. With proxy, iconv, cookie, deflate & multipart support.

Home Page:https://www.npmjs.com/package/needle

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

https through cntlm http proxy Error: connect ETIMEDOUT

chrisgh1 opened this issue · comments

Little background first, I'm using node version 14.15.1, I'm trying to make a POST REST call to youtubes api using https. the request comes from needle and goes to the cntlm proxy to add ntlm authentication and is then sent to the enterprise proxy which uses AD authentication (ntlm) and then out to youtube.

Using needle with tunnel npm I'm getting the following error. I believe I have to use the tunnel package because the cntlm proxy only understands http and not https. So I'm using https over http.

I get the following error:

Error: connect ETIMEDOUT 172.217.10.106:443
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1146:16) {
  errno: -4039,
  code: 'ETIMEDOUT',
  syscall: 'connect',
  address: '172.217.10.106',
  port: 443
}

here is a code sample, I have removed the private information.

const http = require('http');
const url = require('url');
const needle = require('needle');
const tunnel = require('tunnel');
const got = require('got');

needle.defaults({ open_timeout: 0,
  compressed: true, // sets 'Accept-Encoding' to 'gzip, deflate, br'
});

function handleRequest(request, response){
	var url_parts = url.parse(request.url);
	switch(url_parts.pathname){
	case "/youtube_api":
		response.writeHead(200, {"Content-Type": "application/javascript"});
		youtubeAPI(request, response);
	break;
	default:
		response.end("Error Path not recignized: " + url_parts.pathname);
	}
}

function youtubeAPI(request, response){
	console.log("youtubeAPI called");

	var data = {
        "snippet": {
            "title": "Test api broadcast",
            "scheduledStartTime": "2020-11-18T21:15:00+0000"
        }, "contentDetails": {
            "enableClosedCaptions": true,
            "enableContentEncryption": true,
            "enableDvr": true,
            "enableEmbed": true,
            "recordFromStart": true,
            "startWithSlate": true
        }, "status": {
            "privacyStatus": "unlisted"
        }
    }

	needle('post', 'https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet%2CcontentDetails%2Cstatus&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', { 
				agent: {
					https: tunnel.httpsOverHttp({
						proxy: {
							port: 3128
						}
					})
				},
				headers: {
					'Content-Type': "application/json",
					'Authorization': "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				},
				json: data
			})
		.then(function(resp) {
			console.log(resp);
			response.end(resp.body);
		})
		.catch(function(err) {
			console.log(err);
		});

	/*
    //working using got npm
        got.post('https://www.googleapis.com/youtube/v3/liveBroadcasts?part=snippet%2CcontentDetails%2Cstatus&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxx', {
            agent: {
                https: tunnel.httpsOverHttp({
                    proxy: {
                        port: 3128
                    }
                })
            },
            headers: {
                'Content-Type': "application/json",
                'Authorization': "Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
            },
            json: data
        })
        .then(function(resp) {
            console.log(resp);
            response.end(resp.body);
        })
        .catch(function(err) {
            console.log(err);
        });
    */
}

var server = http.createServer(handleRequest);

server.listen(8080, function(){
	console.log("Server listening on: http://localhost:8080");
});

The commented out section is a test that was successful using the npm package got. So I think I'm ok on how I have the environment setup but I'm unable to figure out why needle isn't able to complete the request.

Thanks