https through cntlm http proxy Error: connect ETIMEDOUT

Open
#337 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Needs clarification
Activity status
Stale
Tech stack
javascript, node.js

Research direction

Start at the needle('post', ...) call and compare its tunnel.httpsOverHttp agent configuration with the commented, working got.post example. Reproduce the request through the CNTLM or HTTP proxy and trace the connection path; done means identifying why Needle times out while Got succeeds and documenting or correcting the differing behavior.

Written by the indexing model from the issue text.

Description

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

Dominant language
JavaScript
Stars
1.6k
Forks
237
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from tomas/needle

All issues in tomas/needle

Similar issues

More JavaScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.