nystudio107 / craft-retour

Retour allows you to intelligently redirect legacy URLs, so that you don't lose SEO value when rebuilding & restructuring a website
https://nystudio107.com/plugins/retour
Other
39 stars 26 forks source link

Infinite loop when combining regex and exact match redirects #271

Closed GustavTaxen closed 1 year ago

GustavTaxen commented 1 year ago

Describe the bug

We are moving our website for the second time. We had an original "generation 0" website which was moved to a "generation 1" website a couple of years ago (where some of the original gen-0 URLs changed). We are now moving to "generation 2" and I'm trying to set up redirects of gen-0 URLs to gen-2 URLs by combining "gen-0 to gen-1" rules with "gen-1 to gen-2" rules.

I created "Exact Match" redirects in Retour from gen-1 to gen-2, e.g.,

From: /courses/looping-essentials-for-bass-with-steve-lawson/introduction

To: /lessons/looping-essentials-for-bass-with-steve-lawson-introduction

This worked perfectly, as expected. I then added the gen-0 to gen-1 redirects as Regex matches, e.g.,

From: /courses/looping-essentials(.*)

To: /courses/looping-essentials-for-bass-with-steve-lawson$1

The redirects work fine for correct URLs. But when I test the redirects with a faulty URL, e.g.,

/courses/looping-essentials/incorrect

Craft enters an infinite redirect loop instead of giving me a 404. This happens regardless of which priority I choose for the RegEx redirect.

To reproduce

Steps to reproduce the behaviour:

  1. Add an exact match URL, e.g., /gen-1/my-slug to /gen-2/my-other-slug
  2. Add a RegEx URL, e.g., /gen-0/old-slug(.*) to /gen-1$1
  3. Direct the browser to a faulty gen-0 URL, e.g., /gen-0/old-slug/not-correct

Expected behaviour

404 Not Found

Actual result

ERR_TOO_MANY_REDIRECTS

Versions

khalwat commented 1 year ago

Are you saying this is a bug in the plugin in some form?

GustavTaxen commented 1 year ago

Yes, unless you can explain why it is correct behaviour that this should result in an infinite redirect loop.

khalwat commented 1 year ago

From looking at it, it appears to me that your Regex isn't correct, and the redirect loop would happen if you put this in a server-side redirect (via Apache or Nginx config).

When someone enters in:

/courses/looping-essentials/incorrect

The regex /courses/looping-essentials(.*) will match it, and rewrite it to:

/courses/looping-essentials-for-bass-with-steve-lawson/incorrect

...which also doesn't exist, so once again a 404 will be thrown, and the regex /courses/looping-essentials(.*) will match it again, and rewrite it to:

/courses/looping-essentials-for-bass-with-steve-lawson/incorrect

...and it will loop on forever.

Probably if you changed it to:

From: /courses/looping-essentials/(.*)

To: /courses/looping-essentials-for-bass-with-steve-lawson/$1

...it will fix your problem.