[6a3a178] | 1 | var helpers = require('./helpers'),
|
---|
| 2 | should = require('should'),
|
---|
| 3 | sinon = require('sinon'),
|
---|
| 4 | needle = require('./../');
|
---|
| 5 |
|
---|
| 6 | var ports = {
|
---|
| 7 | http : 8888,
|
---|
| 8 | https : 9999
|
---|
| 9 | }
|
---|
| 10 |
|
---|
| 11 | var protocols = {
|
---|
| 12 | http : require('http'),
|
---|
| 13 | https : require('https')
|
---|
| 14 | }
|
---|
| 15 |
|
---|
| 16 | var code = 301;
|
---|
| 17 | var location; // var to set the response location
|
---|
| 18 |
|
---|
| 19 | function response_code() {
|
---|
| 20 | return code;
|
---|
| 21 | }
|
---|
| 22 |
|
---|
| 23 | function response_headers() {
|
---|
| 24 | return { 'Content-Type': 'text/plain', 'Location': location }
|
---|
| 25 | }
|
---|
| 26 |
|
---|
| 27 | describe('redirects', function() {
|
---|
| 28 |
|
---|
| 29 | var spies = {},
|
---|
| 30 | servers = {};
|
---|
| 31 |
|
---|
| 32 | var current_protocol;
|
---|
| 33 | var hostname = require('os').hostname();
|
---|
| 34 |
|
---|
| 35 | // open two servers, one that responds to a redirect
|
---|
| 36 | before(function(done) {
|
---|
| 37 |
|
---|
| 38 | var conf = {
|
---|
| 39 | port : ports.http,
|
---|
| 40 | code : response_code,
|
---|
| 41 | headers : response_headers
|
---|
| 42 | }
|
---|
| 43 |
|
---|
| 44 | servers.http = helpers.server(conf, function() {
|
---|
| 45 | conf.port = ports.https;
|
---|
| 46 | conf.protocol = 'https';
|
---|
| 47 | servers.https = helpers.server(conf, done);
|
---|
| 48 | });
|
---|
| 49 | })
|
---|
| 50 |
|
---|
| 51 | after(function(done) {
|
---|
| 52 | servers.http.close(function() {
|
---|
| 53 | servers.https.close(done);
|
---|
| 54 | });
|
---|
| 55 | })
|
---|
| 56 |
|
---|
| 57 | var prots = {'http': 'https'};
|
---|
| 58 | Object.keys(prots).forEach(function(protocol) {
|
---|
| 59 |
|
---|
| 60 | current_protocol = protocol;
|
---|
| 61 | var other_protocol = protocol == 'http' ? 'https' : 'http';
|
---|
| 62 |
|
---|
| 63 | var opts, // each test will modify this
|
---|
| 64 | host = '127.0.0.1',
|
---|
| 65 | url = protocol + '://' + host + ':' + ports[protocol] + '/hello';
|
---|
| 66 |
|
---|
| 67 | function send_request(opts, cb) {
|
---|
| 68 | opts.rejectUnauthorized = false;
|
---|
| 69 | // console.log(' -- sending request ' + url + ' -- redirect to ' + location);
|
---|
| 70 | needle.post(url, { foo: 'bar' }, opts, cb);
|
---|
| 71 | }
|
---|
| 72 |
|
---|
| 73 | function not_followed(done) {
|
---|
| 74 | send_request(opts, function(err, resp) {
|
---|
| 75 | resp.statusCode.should.eql(301);
|
---|
| 76 | if (current_protocol == 'http') {
|
---|
| 77 | spies.http.callCount.should.eql(1); // only original request
|
---|
| 78 | spies.https.callCount.should.eql(0);
|
---|
| 79 | } else {
|
---|
| 80 | spies.http.callCount.should.eql(0);
|
---|
| 81 | spies.https.callCount.should.eql(1); // only original request
|
---|
| 82 | }
|
---|
| 83 | done();
|
---|
| 84 | })
|
---|
| 85 | }
|
---|
| 86 |
|
---|
| 87 | function followed_same_protocol(done) {
|
---|
| 88 | send_request(opts, function(err, resp) {
|
---|
| 89 | // the original request plus the redirect one
|
---|
| 90 | spies[current_protocol].callCount.should.eql(2);
|
---|
| 91 | done();
|
---|
| 92 | })
|
---|
| 93 |
|
---|
| 94 | }
|
---|
| 95 |
|
---|
| 96 | function followed_other_protocol(done) {
|
---|
| 97 | send_request(opts, function(err, resp) {
|
---|
| 98 | // on new-ish node versions, https.request calls http.request internally,
|
---|
| 99 | // so we need to amount for that additional call.
|
---|
| 100 | // update: this doesn't happen on node > 10.x
|
---|
| 101 |
|
---|
| 102 | var node_major_ver = process.version.split('.')[0].replace('v', '');
|
---|
| 103 | var http_calls = protocols.http.Agent.defaultMaxSockets == Infinity && parseInt(node_major_ver) < 10 ? 2 : 1;
|
---|
| 104 |
|
---|
| 105 | spies.http.callCount.should.eql(http_calls); // the one(s) from http.request
|
---|
| 106 | spies.https.callCount.should.eql(1); // the one from https.request (redirect)
|
---|
| 107 | done();
|
---|
| 108 | })
|
---|
| 109 | }
|
---|
| 110 |
|
---|
| 111 | // set a spy on [protocol].request
|
---|
| 112 | // so we can see how many times a request was made
|
---|
| 113 | before(function() {
|
---|
| 114 | spies.http = sinon.spy(protocols.http, 'request');
|
---|
| 115 | spies.https = sinon.spy(protocols.https, 'request');
|
---|
| 116 | })
|
---|
| 117 |
|
---|
| 118 | // and make sure it is restored after each test
|
---|
| 119 | afterEach(function() {
|
---|
| 120 | spies.http.reset();
|
---|
| 121 | spies.https.reset();
|
---|
| 122 | })
|
---|
| 123 |
|
---|
| 124 | after(function() {
|
---|
| 125 | spies.http.restore();
|
---|
| 126 | spies.https.restore();
|
---|
| 127 | })
|
---|
| 128 |
|
---|
| 129 | describe('when overriding defaults', function() {
|
---|
| 130 |
|
---|
| 131 | before(function() {
|
---|
| 132 | needle.defaults({ follow_max: 10 });
|
---|
| 133 | opts = {};
|
---|
| 134 | })
|
---|
| 135 |
|
---|
| 136 | after(function() {
|
---|
| 137 | // reset values to previous
|
---|
| 138 | needle.defaults({ follow_max: 0 });
|
---|
| 139 | })
|
---|
| 140 |
|
---|
| 141 | describe('and redirected to the same path on same host and protocol', function() {
|
---|
| 142 | before(function() {
|
---|
| 143 | location = url;
|
---|
| 144 | })
|
---|
| 145 | it('does not follow redirect', not_followed);
|
---|
| 146 | })
|
---|
| 147 |
|
---|
| 148 | describe('and redirected to the same path on same host and different protocol', function() {
|
---|
| 149 | before(function() {
|
---|
| 150 | location = url.replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
|
---|
| 151 | })
|
---|
| 152 |
|
---|
| 153 | it('follows redirect', followed_other_protocol);
|
---|
| 154 | })
|
---|
| 155 |
|
---|
| 156 | describe('and redirected to a different path on same host, same protocol', function() {
|
---|
| 157 | before(function() {
|
---|
| 158 | location = url.replace('/hello', '/goodbye');
|
---|
| 159 | })
|
---|
| 160 | it('follows redirect', followed_same_protocol);
|
---|
| 161 | })
|
---|
| 162 |
|
---|
| 163 | describe('and redirected to a different path on same host, different protocol', function() {
|
---|
| 164 | before(function() {
|
---|
| 165 | location = url.replace('/hello', '/goodbye').replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
|
---|
| 166 | })
|
---|
| 167 | it('follows redirect', followed_other_protocol);
|
---|
| 168 | })
|
---|
| 169 |
|
---|
| 170 | describe('and redirected to same path on another host, same protocol', function() {
|
---|
| 171 | before(function() {
|
---|
| 172 | location = url.replace(host, hostname);
|
---|
| 173 | })
|
---|
| 174 | it('follows redirect', followed_same_protocol);
|
---|
| 175 | })
|
---|
| 176 |
|
---|
| 177 | describe('and redirected to same path on another host, different protocol', function() {
|
---|
| 178 | before(function() {
|
---|
| 179 | location = url.replace(host, hostname).replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
|
---|
| 180 | })
|
---|
| 181 | it('follows redirect', followed_other_protocol);
|
---|
| 182 | })
|
---|
| 183 |
|
---|
| 184 | })
|
---|
| 185 |
|
---|
| 186 | // false and null have the same result
|
---|
| 187 | var values = [false, null];
|
---|
| 188 | values.forEach(function(value) {
|
---|
| 189 |
|
---|
| 190 | describe('when follow is ' + value, function() {
|
---|
| 191 |
|
---|
| 192 | before(function() {
|
---|
| 193 | opts = { follow: value };
|
---|
| 194 | })
|
---|
| 195 |
|
---|
| 196 |
|
---|
| 197 |
|
---|
| 198 | describe('and redirected to the same path on same host and protocol', function() {
|
---|
| 199 | before(function() {
|
---|
| 200 | location = url;
|
---|
| 201 | })
|
---|
| 202 |
|
---|
| 203 | it('throws an error', function() {
|
---|
| 204 | (function() {
|
---|
| 205 | send_request(opts, function() { });
|
---|
| 206 | }).should.throw;
|
---|
| 207 | })
|
---|
| 208 |
|
---|
| 209 | })
|
---|
| 210 |
|
---|
| 211 | })
|
---|
| 212 |
|
---|
| 213 | })
|
---|
| 214 |
|
---|
| 215 | describe('when follow is true', function() {
|
---|
| 216 |
|
---|
| 217 | before(function() {
|
---|
| 218 | opts = { follow: true };
|
---|
| 219 | })
|
---|
| 220 |
|
---|
| 221 | describe('and redirected to the same path on same host and protocol', function() {
|
---|
| 222 | before(function() { location = url })
|
---|
| 223 |
|
---|
| 224 | it('throws an error', function() {
|
---|
| 225 | (function() {
|
---|
| 226 | send_request(opts, function() { });
|
---|
| 227 | }).should.throw;
|
---|
| 228 | })
|
---|
| 229 |
|
---|
| 230 | })
|
---|
| 231 |
|
---|
| 232 | })
|
---|
| 233 |
|
---|
| 234 | describe('when follow is > 0', function() {
|
---|
| 235 |
|
---|
| 236 | before(function() {
|
---|
| 237 | needle.defaults({ follow: 10 });
|
---|
| 238 | })
|
---|
| 239 |
|
---|
| 240 | after(function() {
|
---|
| 241 | needle.defaults({ follow: 0 });
|
---|
| 242 | })
|
---|
| 243 |
|
---|
| 244 | describe('when keep_method is false', function() {
|
---|
| 245 |
|
---|
| 246 | before(function() {
|
---|
| 247 | opts = { follow_keep_method: false };
|
---|
| 248 | })
|
---|
| 249 |
|
---|
| 250 | // defaults to follow host and protocol
|
---|
| 251 | describe('and redirected to the same path on same host and different protocol', function() {
|
---|
| 252 |
|
---|
| 253 | before(function() {
|
---|
| 254 | location = url.replace(protocol, other_protocol);
|
---|
| 255 | })
|
---|
| 256 |
|
---|
| 257 | it('follows redirect', followed_other_protocol);
|
---|
| 258 |
|
---|
| 259 | it('sends a GET request with no data', function(done) {
|
---|
| 260 | send_request(opts, function(err, resp) {
|
---|
| 261 | spies.http.args[0][0].method.should.eql('GET');
|
---|
| 262 | // spy.args[0][3].should.eql(null);
|
---|
| 263 | done();
|
---|
| 264 | })
|
---|
| 265 | })
|
---|
| 266 |
|
---|
| 267 | })
|
---|
| 268 |
|
---|
| 269 | })
|
---|
| 270 |
|
---|
| 271 | describe('and set_referer is true', function() {
|
---|
| 272 |
|
---|
| 273 | before(function() {
|
---|
| 274 | opts = { follow_set_referer: true };
|
---|
| 275 | })
|
---|
| 276 |
|
---|
| 277 | // defaults to follow host and protocol
|
---|
| 278 | describe('and redirected to the same path on same host and different protocol', function() {
|
---|
| 279 |
|
---|
| 280 | before(function() {
|
---|
| 281 | location = url.replace(protocol, other_protocol);
|
---|
| 282 | })
|
---|
| 283 |
|
---|
| 284 | it('follows redirect', followed_other_protocol);
|
---|
| 285 |
|
---|
| 286 | it('sets Referer header when following redirect', function(done) {
|
---|
| 287 | send_request(opts, function(err, resp) {
|
---|
| 288 | spies.http.args[0][0].headers['referer'].should.eql("http://" + host + ":8888/hello");
|
---|
| 289 | // spies.http.args[0][3].should.eql({ foo: 'bar'});
|
---|
| 290 | done();
|
---|
| 291 | })
|
---|
| 292 | })
|
---|
| 293 |
|
---|
| 294 | })
|
---|
| 295 |
|
---|
| 296 | })
|
---|
| 297 |
|
---|
| 298 | describe('and keep_method is true', function() {
|
---|
| 299 |
|
---|
| 300 | before(function() {
|
---|
| 301 | opts = { follow_keep_method: true };
|
---|
| 302 | })
|
---|
| 303 |
|
---|
| 304 | // defaults to follow host and protocol
|
---|
| 305 | describe('and redirected to the same path on same host and different protocol', function() {
|
---|
| 306 |
|
---|
| 307 | before(function() {
|
---|
| 308 | location = url.replace(protocol, other_protocol);
|
---|
| 309 | })
|
---|
| 310 |
|
---|
| 311 | it('follows redirect', followed_other_protocol);
|
---|
| 312 |
|
---|
| 313 | it('sends a POST request with the original data', function(done) {
|
---|
| 314 | send_request(opts, function(err, resp) {
|
---|
| 315 | spies.http.args[0][0].method.should.eql('post');
|
---|
| 316 | // spies.http.args[0][3].should.eql({ foo: 'bar'});
|
---|
| 317 | done();
|
---|
| 318 | })
|
---|
| 319 | })
|
---|
| 320 |
|
---|
| 321 | })
|
---|
| 322 |
|
---|
| 323 | })
|
---|
| 324 |
|
---|
| 325 | describe('and if_same_host is false', function() {
|
---|
| 326 |
|
---|
| 327 | before(function() {
|
---|
| 328 | opts = { follow_if_same_host: false };
|
---|
| 329 | })
|
---|
| 330 |
|
---|
| 331 | // by default it will follow other protocols
|
---|
| 332 | describe('and redirected to same path on another domain, same protocol', function() {
|
---|
| 333 | before(function() {
|
---|
| 334 | location = url.replace(host, hostname);
|
---|
| 335 | })
|
---|
| 336 | it('follows redirect', followed_same_protocol);
|
---|
| 337 | })
|
---|
| 338 |
|
---|
| 339 | })
|
---|
| 340 |
|
---|
| 341 | describe('and if_same_host is true', function() {
|
---|
| 342 |
|
---|
| 343 | before(function() {
|
---|
| 344 | opts = { follow_if_same_host: true };
|
---|
| 345 | })
|
---|
| 346 |
|
---|
| 347 | // by default it will follow other protocols
|
---|
| 348 | describe('and redirected to same path on another domain, same protocol', function() {
|
---|
| 349 | before(function() {
|
---|
| 350 | location = url.replace(host, hostname);
|
---|
| 351 | })
|
---|
| 352 |
|
---|
| 353 | it('does not follow redirect', not_followed);
|
---|
| 354 | })
|
---|
| 355 |
|
---|
| 356 | })
|
---|
| 357 |
|
---|
| 358 | describe('and if_same_protocol is false', function() {
|
---|
| 359 |
|
---|
| 360 | before(function() {
|
---|
| 361 | opts = { follow_if_same_protocol: false };
|
---|
| 362 | })
|
---|
| 363 |
|
---|
| 364 | // by default it will follow other hosts
|
---|
| 365 | describe('and redirected to same path on another domain, different protocol', function() {
|
---|
| 366 | before(function() {
|
---|
| 367 | location = url.replace(host, hostname).replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
|
---|
| 368 | })
|
---|
| 369 | it('follows redirect', followed_other_protocol);
|
---|
| 370 | })
|
---|
| 371 |
|
---|
| 372 | })
|
---|
| 373 |
|
---|
| 374 | describe('and if_same_protocol is true', function() {
|
---|
| 375 |
|
---|
| 376 | before(function() {
|
---|
| 377 | opts = { follow_if_same_protocol: true };
|
---|
| 378 | })
|
---|
| 379 |
|
---|
| 380 | // by default it will follow other hosts
|
---|
| 381 | describe('and redirected to same path on another domain, different protocol', function() {
|
---|
| 382 | before(function() {
|
---|
| 383 | location = url.replace(host, hostname).replace(protocol, other_protocol).replace(ports[protocol], ports[other_protocol]);
|
---|
| 384 | })
|
---|
| 385 | it('does not follow redirect', not_followed);
|
---|
| 386 | })
|
---|
| 387 |
|
---|
| 388 | })
|
---|
| 389 |
|
---|
| 390 | })
|
---|
| 391 |
|
---|
| 392 | })
|
---|
| 393 |
|
---|
| 394 | });
|
---|