needle
needle copied to clipboard
Proposal: Supporting User-Defined "Follow If" Conditions
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.