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

Case insensitive redirects #9755

Merged
merged 6 commits into from Sep 24, 2018
Merged

Case insensitive redirects #9755

merged 6 commits into from Sep 24, 2018

Conversation

jessehouwing
Copy link
Contributor

@jessehouwing jessehouwing commented Jul 26, 2018

While migrating from Blogger to Ghost I ran into the issue that Blogger is case-insensitive in a couple of places:

  • Tag urls
  • Post urls

I've integrated Google Search Console with my current blog and I'm seeing all kinds of people hitting 404's due to them using urls in all-lower-case.

I've updated my Blogger2Ghost.NET application to generate redirects like these

  {
    "from": "^\\/search\\/label\\/[Hh][Dd][Mm][Ii]$",
    "to": "/tag/windows-devices",
    "permanent": false
  }

But that's not really nice. This Pull request adds the ability to add case-insensitivity to the redirects.json format:

    { 
        "from": "^\\/case-insensitive",
        "caseInsensitive": true,
        "to": "/redirected-insensitive"
    },
    {
        "from": "^\\/Case-Sensitive",
        "caseInsensitive": false,
        "to": "/redirected-sensitive"
    },
    {
        "from": "^\\/Default-Sensitive",
        "to": "/redirected-default"
    }

The caseInsensitive is a boolean option, it's optional and the default is to keep the current behavior. By adding caseInsensitive=true the redirect will be initialized with the "i" RegExp option.

I've considered checking the start of the regex for (?i:) as well and settign the flag, which is the way for most regex flavors to set case insensitivity inline. But since that's not part of the JavaScript regexp standard, that may be confusing.


This change is Reviewable

@jessehouwing
Copy link
Contributor Author

Currently the redirect API doesn't return a 302, which is what I expect, but it does return 301 to the passed in URL (preserving case). I'm not sure why, this seems the standard behavior.

@kirrg001 kirrg001 self-assigned this Jul 26, 2018
@kirrg001
Copy link
Contributor

Thanks will review asap 👍

@jessehouwing
Copy link
Contributor Author

On windows there are some issues running tests and the eslint configuration.

  1. There are more _spec files than the windows commandline will grok, causing a "command to long" error half-way running the tests. No clue how to easily fix this.
  2. The repo doesn't enforce checkout as-is commit-as-is. So on Windows it defaults to windows line ends on a default git install. This causes so many lint errors it becomes impossible to use. Setting the repository default will help people on Windows. See: https://help.github.com/articles/dealing-with-line-endings/

@kirrg001
Copy link
Contributor

Hey!

I am not sure about adding a new option 🤔

If we would allow passing the options in the from field, we could parse it out and forward the regex options to RegExp?

e.g. "from": "^\/EXAMPLE/i",

@jessehouwing
Copy link
Contributor Author

jessehouwing commented Jul 30, 2018 via email

@jessehouwing
Copy link
Contributor Author

jessehouwing commented Jul 30, 2018

The latest version of my Blogger Importer now generates case insensitive links and can also generate lower-case links if needed.
jessehouwing/Blogger2Ghost@26fa340

@kirrg001
Copy link
Contributor

Or the JS synrax: from: "/^\\/ACTION\\/$/i"

👍

@jessehouwing
Copy link
Contributor Author

jessehouwing commented Jul 30, 2018 via email

@kirrg001 kirrg001 changed the title Case insensitive redirects [WIP] Case insensitive redirects Aug 3, 2018
@jessehouwing
Copy link
Contributor Author

Pushed the requested changes. It now uses the requested format. Dropped the parameter and updated the tests to reflect.

@kirrg001
Copy link
Contributor

kirrg001 commented Aug 6, 2018

Thanks @jessehouwing - will review asap.

.gitattributes Outdated
@@ -0,0 +1,2 @@
# enforce unix style line endings

This comment was marked as abuse.

@@ -27,6 +27,13 @@ _private.registerRoutes = function registerRoutes() {
* - you define /my-blog-post-1/ as from property
* - /my-blog-post-1 or /my-blog-post-1/ should work
*/

var options = '';

This comment was marked as abuse.

@jessehouwing
Copy link
Contributor Author

Rebased against master and incorporated comments.

@kirrg001 kirrg001 changed the title [WIP] Case insensitive redirects Case insensitive redirects Sep 17, 2018
Copy link
Member

@ErisDS ErisDS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

@@ -27,6 +27,13 @@ _private.registerRoutes = function registerRoutes() {
* - you define /my-blog-post-1/ as from property
* - /my-blog-post-1 or /my-blog-post-1/ should work
*/

let options = '';
if (redirect.from.match(/\/.*\/i/)) {

This comment was marked as abuse.

@jessehouwing
Copy link
Contributor Author

Not sure what you mean with the last comment... Are you suggesting to drop the first forward slash?

I didn't do that cause one may have a pattern that ends with /i and there would be no way to distinguish. That's why I did only the variant where both leading and trailing slash are present eg: /..../i

@kirrg001
Copy link
Contributor

Not sure what you mean with the last comment... Are you suggesting to drop the first forward slash?

No. I only was suggesting to match the url with "ends with" /i.

This PR needs a rebase again 😕

@jessehouwing
Copy link
Contributor Author

Right, just scanning for /i won't be enough, if we're following the /... /i format in javascript. The leading slash is part of the expression syntax. I could split up the check in a Startswith('/') and EndsWith('/i'), but regex seems the to be tool of trade in this class :D.

I did find a bug in the regex I used (it didn't use ^...$ to restrict this regex to the whole input.

I can rewrite it as: from.match(/^\//) && from.match(/\/i$/) if that's preferred.

@jessehouwing
Copy link
Contributor Author

Rebased.

Copy link
Contributor

@kirrg001 kirrg001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - thanks so much :)

@kirrg001 kirrg001 merged commit e3234bc into TryGhost:master Sep 24, 2018
allouis added a commit that referenced this pull request Sep 25, 2018
* master: (25 commits)
  Version bump to 2.1.4
  Updated Ghost-Admin to 2.1.4
  Version bump to 2.1.4-beta.1
  Updated Ghost-Admin to 2.1.4-beta.1
  Updated private-sites to not redirect to full urls
  Bumped ghost-ignition to version 2.9.6
  Upgrading Casper to 2.6.3
  Refactored url utility to generate multiple API version URLs (#9897)
  Added new endpoint to upload square profile images with dimension validation (#9862)
  Removed change frequency and priority fields from sitemap generator (#9771)
  🎨Added case insensitive support for redirects (#9755)
  Refactored direct usages of api controllers
  Normalised how we require models
  Refactored how we require shared middlewares from web/ (#9893)
  Removed duplicate 'id' for User permittedOptions
  Updated permittedOptions to correctly call super
  Updated base model to remove extraAllowedProperties
  Extended uncapitalise unit tests (#9891)
  Removed `res.isAdmin` from admin express app (#9889)
  Refactored `web/middleware` and `web/utils` to `web/shared` (#9892)
  ...
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

Successfully merging this pull request may close these issues.

None yet

3 participants