I have a bearer token and try to get a user's timeline from behind a proxy with the following code.
var parsedUrl = url.parse( 'https://api.twitter.com/1.1/statuses/user_timeline.json:443/?count=2&screen_name=twitterapi', true, true );
var options = {
'host': parsedUrl.host,
'path': parsedUrl.path,
'method': 'GET',
'headers': {
'Host': parsedUrl.host,
'Authorization': 'Bearer ' + settings.accessToken
}
};
var adapter = https;
if(settings.proxy)
{
options.host = settings.proxy;
options.port = settings.proxyPort;
options.path = parsedUrl.path;
options.headers['Proxy-Connection'] = 'Keep-Alive';
adapter = http;
}
var body = '';
var req = adapter.request(options, function(res) {
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
try
{
var result = JSON.parse( body );
}
catch(ex)
{
//...
}
});
});
req.end();
This request always return a 400 with no body or error message. If try the acces with cUrl it works like a charm. I retrieve the bearer token in the same way. Why does Twitter respond with a 400?
curl --get 'https://api.twitter.com/1.1/statuses/user_timeline.json' --data 'count=2&screen_name=twitterapi' --header 'Authorization: Bearer <token>' --verbose --proxy http://proxy.example.com:8080
What does cUrl differently?
EDIT: The status code is NOT 404 but 400! Sorry.
EDIT2: When I leave the Authorization header out I still get 400 even though I expect a authorization failed message. Is any special enconding needed?
EDIT3: Now the status code is 401. Something smelly goes on :(
Here is the trick: You have to tunnel the HTTPS connection on the HTTP request using CONNECT to get through the proxy. The initial way is wrong.
var http = require('http');
var https = require('https');
var connectReq = http.request({ // establishing a tunnel
host: 'localhost',
port: 3128,
method: 'CONNECT',
path: 'github.com:443',
}).on('connect', function(res, socket, head) {
// should check res.statusCode here
var req = https.get({
host: 'github.com',
socket: socket, // using a tunnel
agent: false // cannot use a default agent
}, function(res) {
res.setEncoding('utf8');
res.on('data', console.log);
});
}).end();
See following node.js bug/issue for details: HTTPS request not working with proxy