test/res.location.js JAVASCRIPT 305 lines View on github.com → Search inside
1'use strict'23var express = require('../')4  , request = require('supertest')5  , assert = require('node:assert')6  , url = require('node:url');78describe('res', function(){9  describe('.location(url)', function(){10    it('should set the header', function(done){11      var app = express();1213      app.use(function(req, res){14        res.location('http://google.com/').end();15      });1617      request(app)18      .get('/')19      .expect('Location', 'http://google.com/')20      .expect(200, done)21    })2223    it('should preserve trailing slashes when not present', function(done){24      var app = express();2526      app.use(function(req, res){27        res.location('http://google.com').end();28      });2930      request(app)31      .get('/')32      .expect('Location', 'http://google.com')33      .expect(200, done)34    })3536    it('should encode "url"', function (done) {37      var app = express()3839      app.use(function (req, res) {40        res.location('https://google.com?q=\u2603 §10').end()41      })4243      request(app)44      .get('/')45      .expect('Location', 'https://google.com?q=%E2%98%83%20%C2%A710')46      .expect(200, done)47    })4849    it('should encode data uri', function (done) {50      var app = express()51      app.use(function (req, res) {52        res.location('data:text/javascript,export default () => { }').end();53      });5455      request(app)56        .get('/')57        .expect('Location', 'data:text/javascript,export%20default%20()%20=%3E%20%7B%20%7D')58        .expect(200, done)59    })6061    it('should consistently handle non-string input: boolean', function (done) {62      var app = express()63      app.use(function (req, res) {64        res.location(true).end();65      });6667      request(app)68        .get('/')69        .expect('Location', 'true')70        .expect(200, done)71    });7273    it('should consistently handle non-string inputs: object', function (done) {74      var app = express()75      app.use(function (req, res) {76        res.location({}).end();77      });7879      request(app)80        .get('/')81        .expect('Location', '[object%20Object]')82        .expect(200, done)83    });8485    it('should consistently handle non-string inputs: array', function (done) {86      var app = express()87      app.use(function (req, res) {88        res.location([]).end();89      });9091      request(app)92        .get('/')93        .expect('Location', '')94        .expect(200, done)95    });9697    it('should consistently handle empty string input', function (done) {98      var app = express()99      app.use(function (req, res) {100        res.location('').end();101      });102103      request(app)104        .get('/')105        .expect('Location', '')106        .expect(200, done)107    });108109110    if (typeof URL !== 'undefined') {111      it('should accept an instance of URL', function (done) {112        var app = express();113114        app.use(function(req, res){115          res.location(new URL('http://google.com/')).end();116        });117118        request(app)119          .get('/')120          .expect('Location', 'http://google.com/')121          .expect(200, done);122      });123    }124  })125126  describe('location header encoding', function() {127    function createRedirectServerForDomain (domain) {128      var app = express();129      app.use(function (req, res) {130        var host = url.parse(req.query.q, false, true).host;131        // This is here to show a basic check one might do which132        // would pass but then the location header would still be bad133        if (host !== domain) {134          res.status(400).end('Bad host: ' + host + ' !== ' + domain);135        }136        res.location(req.query.q).end();137      });138      return app;139    }140141    function testRequestedRedirect (app, inputUrl, expected, expectedHost, done) {142      return request(app)143        // Encode uri because old supertest does not and is required144        // to test older node versions. New supertest doesn't re-encode145        // so this works in both.146        .get('/?q=' + encodeURIComponent(inputUrl))147        .expect('') // No body.148        .expect(200)149        .expect('Location', expected)150        .end(function (err, res) {151          if (err) {152            console.log('headers:', res.headers)153            console.error('error', res.error, err);154            return done(err, res);155          }156157          // Parse the hosts from the input URL and the Location header158          var inputHost = url.parse(inputUrl, false, true).host;159          var locationHost = url.parse(res.headers['location'], false, true).host;160161          assert.strictEqual(locationHost, expectedHost);162163          // Assert that the hosts are the same164          if (inputHost !== locationHost) {165            return done(new Error('Hosts do not match: ' + inputHost + " !== " +  locationHost));166          }167168          return done(null, res);169        });170    }171172    it('should not touch already-encoded sequences in "url"', function (done) {173      var app = createRedirectServerForDomain('google.com');174      testRequestedRedirect(175        app,176        'https://google.com?q=%A710',177        'https://google.com?q=%A710',178        'google.com',179        done180      );181    });182183    it('should consistently handle relative urls', function (done) {184      var app = createRedirectServerForDomain(null);185      testRequestedRedirect(186        app,187        '/foo/bar',188        '/foo/bar',189        null,190        done191      );192    });193194    it('should not encode urls in such a way that they can bypass redirect allow lists', function (done) {195      var app = createRedirectServerForDomain('google.com');196      testRequestedRedirect(197        app,198        'http://google.com\\@apple.com',199        'http://google.com\\@apple.com',200        'google.com',201        done202      );203    });204205    it('should not be case sensitive', function (done) {206      var app = createRedirectServerForDomain('google.com');207      testRequestedRedirect(208        app,209        'HTTP://google.com\\@apple.com',210        'HTTP://google.com\\@apple.com',211        'google.com',212        done213      );214    });215216    it('should work with https', function (done) {217      var app = createRedirectServerForDomain('google.com');218      testRequestedRedirect(219        app,220        'https://google.com\\@apple.com',221        'https://google.com\\@apple.com',222        'google.com',223        done224      );225    });226227    it('should correctly encode schemaless paths', function (done) {228      var app = createRedirectServerForDomain('google.com');229      testRequestedRedirect(230        app,231        '//google.com\\@apple.com/',232        '//google.com\\@apple.com/',233        'google.com',234        done235      );236    });237238    it('should keep backslashes in the path', function (done) {239      var app = createRedirectServerForDomain('google.com');240      testRequestedRedirect(241        app,242        'https://google.com/foo\\bar\\baz',243        'https://google.com/foo\\bar\\baz',244        'google.com',245        done246      );247    });248249    it('should escape header splitting for old node versions', function (done) {250      var app = createRedirectServerForDomain('google.com');251      testRequestedRedirect(252        app,253        'http://google.com\\@apple.com/%0d%0afoo:%20bar',254        'http://google.com\\@apple.com/%0d%0afoo:%20bar',255        'google.com',256        done257      );258    });259260    it('should encode unicode correctly', function (done) {261      var app = createRedirectServerForDomain(null);262      testRequestedRedirect(263        app,264        '/%e2%98%83',265        '/%e2%98%83',266        null,267        done268      );269    });270271    it('should encode unicode correctly even with a bad host', function (done) {272      var app = createRedirectServerForDomain('google.com');273      testRequestedRedirect(274        app,275        'http://google.com\\@apple.com/%e2%98%83',276        'http://google.com\\@apple.com/%e2%98%83',277        'google.com',278        done279      );280    });281282    it('should work correctly despite using deprecated url.parse', function (done) {283      var app = createRedirectServerForDomain('google.com');284      testRequestedRedirect(285        app,286        'https://google.com\'.bb.com/1.html',287        'https://google.com\'.bb.com/1.html',288        'google.com',289        done290      );291    });292293    it('should encode file uri path', function (done) {294      var app = createRedirectServerForDomain('');295      testRequestedRedirect(296        app,297        'file:///etc\\passwd',298        'file:///etc\\passwd',299        '',300        done301      );302    });303  });304})

Code quality findings 33

Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var express = require('../')
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express()
Use strict equality (===) to prevent type coercion bugs
info correctness loose-equality
if (typeof URL !== 'undefined') {
Be cautious with typeof; it has limitations (e.g., typeof null === 'object')
info correctness typeof-pitfall
if (typeof URL !== 'undefined') {
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = express();
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var host = url.parse(req.query.q, false, true).host;
Use strict equality (===) to prevent type coercion bugs
info correctness loose-equality
if (host !== domain) {
Use strict equality (===) to prevent type coercion bugs
info correctness loose-equality
res.status(400).end('Bad host: ' + host + ' !== ' + domain);
Remove debugging statements or use a logging library
info correctness console-log
console.log('headers:', res.headers)
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var inputHost = url.parse(inputUrl, false, true).host;
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var locationHost = url.parse(res.headers['location'], false, true).host;
Use strict equality (===) to prevent type coercion bugs
info correctness loose-equality
if (inputHost !== locationHost) {
Use strict equality (===) to prevent type coercion bugs
info correctness loose-equality
return done(new Error('Hosts do not match: ' + inputHost + " !== " + locationHost));
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain(null);
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain(null);
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('google.com');
Use let or const to avoid scope issues and hoisting
info correctness var-declaration
var app = createRedirectServerForDomain('');

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.