Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Supporting User-Defined "Follow If" Conditions #407

Open
jonathansampson opened this issue Jun 14, 2022 · 0 comments
Open

Proposal: Supporting User-Defined "Follow If" Conditions #407

jonathansampson opened this issue Jun 14, 2022 · 0 comments

Comments

@jonathansampson
Copy link

I needed a bit more control over the follow-if logic today, so I created a small patch to enable the declaration of numerous user-defined conditions:

const options = {
    follow_max: 5,
    follow_if_all: [
        // Only follow if the new endpoint is HTTP or HTTPS
        ( redirect, original ) => /^https?:/.test( redirect )
    ]
};

I'm okay with a redirect from HTTP to HTTPS, or the other way around, but I encountered a URL today that aimed to redirect from HTTPS to MAILTO. This would throw from within http.request, causing all sorts of problems for me.

I'd love to hear everybody's thoughts about this proposal.

Here is the diff that solved my problem:

diff --git a/node_modules/needle/lib/needle.js b/node_modules/needle/lib/needle.js
index a8a1627..509bb37 100644
--- a/node_modules/needle/lib/needle.js
+++ b/node_modules/needle/lib/needle.js
@@ -105,7 +105,10 @@ var defaults = {
   follow_keep_method      : false,
   follow_if_same_host     : false,
   follow_if_same_protocol : false,
-  follow_if_same_location : false
+  follow_if_same_location : false,
+
+  // custom
+  follow_if_all: []
 }
 
 var aliased = {
@@ -258,7 +261,7 @@ Needle.prototype.setup = function(uri, options) {
 
   function check_value(expected, key) {
     var value = get_option(key),
-        type  = typeof value;
+        type  = Array.isArray( value ) ? 'array' : typeof value;
 
     if (type != 'undefined' && type != expected)
       throw new TypeError(type + ' received for ' + key + ', but expected a ' + expected);
@@ -290,6 +293,10 @@ Needle.prototype.setup = function(uri, options) {
     config[key] = check_value('number', key);
   })
 
+  keys_by_type(Array).forEach(function(key) {
+    config[key] = check_value('array', key);
+  })
+
   // populate http_opts with given TLS options
   tls_options.split(' ').forEach(function(key) {
     if (typeof options[key] != 'undefined') {
@@ -511,6 +518,10 @@ Needle.prototype.should_follow = function(location, config, original) {
   if (config.follow_if_same_protocol && !matches('protocol'))
     return false; // procotol does not match, so not following
 
+  if ( config.follow_if_all && !config.follow_if_all.every( o => o( location ) ) ) {
+    return false; // One of the user-provided conditions were not met
+  }
+
   return true;
 }
 

This issue body was partially generated by patch-package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant