express

4.18.04.19.0
lib/response.js
lib/response.js
+19−1
Index: package/lib/response.js
===================================================================
--- package/lib/response.js
+++ package/lib/response.js
@@ -33,8 +33,9 @@
 var extname = path.extname;
 var mime = send.mime;
 var resolve = path.resolve;
 var vary = require('vary');
+var urlParse = require('url').parse;
 
 /**
  * Response prototype.
  * @public
@@ -910,10 +911,27 @@
   if (url === 'back') {
     loc = this.req.get('Referrer') || '/';
   }
 
+  var lowerLoc = loc.toLowerCase();
+  var encodedUrl = encodeUrl(loc);
+  if (lowerLoc.indexOf('https://') === 0 || lowerLoc.indexOf('http://') === 0) {
+    try {
+      var parsedUrl = urlParse(loc);
+      var parsedEncodedUrl = urlParse(encodedUrl);
+      // Because this can encode the host, check that we did not change the host
+      if (parsedUrl.host !== parsedEncodedUrl.host) {
+        // If the host changes after encodeUrl, return the original url
+        return this.set('Location', loc);
+      }
+    } catch (e) {
+      // If parse fails, return the original url
+      return this.set('Location', loc);
+    }
+  }
+
   // set location
-  return this.set('Location', encodeUrl(loc));
+  return this.set('Location', encodedUrl);
 };
 
 /**
  * Redirect to the given `url` with optional response `status`