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

Redirect loop #207

Open
webjay opened this issue Nov 9, 2020 · 7 comments
Open

Redirect loop #207

webjay opened this issue Nov 9, 2020 · 7 comments

Comments

@webjay
Copy link

webjay commented Nov 9, 2020

I have been using your great plugin for a while.

I can't say when it happened, but dynamic paths, via gatsby-plugin-create-client-paths, has started going into a redirect loop, if the page is reloaded in the browser. Navigating to the page from another page doesn't cause a redirect loop.

If I in S3 change KeyPrefixEquals from availability/ to availability/* and ReplaceKeyWith from availability
to availability/, the redirect loop doesn't happen.

This works:

    {
        "Condition": {
            "KeyPrefixEquals": "availability/*"
        },
        "Redirect": {
            "HostName": "test.example.com",
            "HttpRedirectCode": "302",
            "Protocol": "https",
            "ReplaceKeyWith": "availability/"
        }
    },

@YoshiWalsh
Copy link
Collaborator

Could you please provide either an MRE/reprex, or what your gatsby-plugin-s3 and gatsby-plugin-create-client-paths configs look like?

@webjay
Copy link
Author

webjay commented Nov 11, 2020

sure, here you go:

    {
      resolve: 'gatsby-plugin-create-client-paths',
      options: {
        prefixes: [
          '/participant/*',
          '/trainer/*',
          '/availability/*',
        ],
      },
    },
    {
      resolve: 'gatsby-plugin-s3',
      options: {
        bucketName,
        region: 'eu-central-1',
        protocol: 'https',
        hostname,
      },
    },

and one more thing, would you recommend changing error code 403 to 404 as attached?
Screenshot 2020-11-09 at 10 48 44

@YoshiWalsh
Copy link
Collaborator

If you are getting 403 errors, that suggests your Origin is not configured correctly in CloudFront. Please see this recipe, especially particularly the two "CloudFront setup" paragraphs.

When CloudFront is correctly set up to use the S3 Static Website Hosting endpoint you shouldn't need any error behaviour in CloudFront. Instead, leverage the error document functionality if S3 Static Website Hosting.

@MattFanto
Copy link

Same issue for me here when I refresh a client-paths I get a redirect loop. I tried with the workaround suggested by @webjay and it's working.

The configuration is almost identical

        {
            resolve: `gatsby-plugin-create-client-paths`,
            options: {
                prefixes: [`/app/*`, `/invite/*`]
            },
        },
        {
            resolve: `gatsby-plugin-s3`,
            options: {
                bucketName: 'example-frontend-origin',
                protocol: "https",
                hostname: "www.example.com",
            },
        },

On CloudFront, I'm using the bucket website endpoint as suggested in the recipe, if I navigate to the bucket website endpoint everything is working (file are public) but the same redirect issue happens

@webjay did you by any chance found a solution for that?

@MattFanto
Copy link

MattFanto commented Dec 28, 2020

I just realized that the workaround is working because wildcards are not supported and 404.index page is returned which basically handles the redirection to the correct page

I made an experiment with the following configuration where:

  1. for invite client paths I applied the workaround with the wildcard
  2. for app client paths instead I applied "HttpErrorCodeReturnedEquals": "404" condition to match client routes
[
    {
        "Condition": {
            "HttpErrorCodeReturnedEquals": "404",
            "KeyPrefixEquals": "app/"
        },
        "Redirect": {
            "HostName": "www.example.com",
            "HttpRedirectCode": "302",
            "Protocol": "https",
            "ReplaceKeyWith": "app"
        }
    },
    {
        "Condition": {
            "KeyPrefixEquals": "invite/*"
        },
        "Redirect": {
            "HostName": "www.example.com",
            "HttpRedirectCode": "302",
            "Protocol": "https",
            "ReplaceKeyWith": "invite"
        }
    }
]

As you can see here seems to be working fine now:

image

@JoshuaWalsh Do you see any potential issue with this approach, I can create a PR, in any case, I will fork it to avoid manual steps

@YoshiWalsh
Copy link
Collaborator

The potential issue I can see here is an SEO one. Relying on 404 means that search engines will not list clientside routes (maybe desirable) and that links to clientside routes would be classified as broken, which could penalise the page the link is found on. (Probably bad)

You could use a CloudFront error behaviour to rewrite 404 to 200, but this means that actual broken links will now return as 200, which is also bad. (For one thing, it means broken link scanning tools will no longer work)

Doing a 302 redirect for client routes is also far from ideal, as discussed in #77.

I can't think of any way to solve this elegantly other than to use Lambda@Edge.

@MattFanto
Copy link

MattFanto commented Dec 29, 2020

I think my example was a bit confusing my current, please ignore invite it was just a counterexample.
If we look at /app client paths with the following redirect rule the client never sees a 404 error:

    {
        "Condition": {
            "HttpErrorCodeReturnedEquals": "404",
            "KeyPrefixEquals": "app/"
        },
        "Redirect": {
            "HostName": "www.example.com",
            "HttpRedirectCode": "302",
            "Protocol": "https",
            "ReplaceKeyWith": "app"
        }
    },

For non-existing URL returning 200 may not be desirable but I think this can't be avoided even with the actual gatsby-plugin-s3 configuration, probably you would have the same behaviour on Netlify.

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

3 participants