Azure CDN with Verizon - Rewriting URL to always load index.html
Asked Answered
K

3

8

Context


I've been struggling with the following problem for the last few days and due to the very nature of a CDN and the manual review of each new rule, it takes me each time up to 4h to deploy a new rule.

As described in the following topic, I currently have my Angular application deployed to a storage account which has a single blob container called cdn

enter image description here

Within the root of this blob container, the whole dist folder from my angular project has been copied via my CI setup.

enter image description here

The CDN profile has also been set up, to point at the origin-path called /cdn

enter image description here


Problem


Unfortunately there is currently an ongoing issue that you can't directly access a default file.

  1. What I would like is to redirect all incoming traffic from my Angular application to the index.html file. This in order to satisfy the routing for Angular.

    Input url with the expected output

  2. Furthermore I would like to let any request for static files (e.g images) through without any specific url rewritting.

I've seen various posts regarding this issue but none of the answer seem to cover my case or didn't in the deliver the expected result.

Currently I am using the rules engines feature of the Azure CDN from Verizon.

Regarding the patterns I used all the patterns mentioned in the following article, including which were mentioned in the comments.

I've also spent at least two days to find various other articles and stackoverflow articles but none of them worked for my case.

Furthermore I also created my own regex pattern but although they worked in my test environment, they would work once they were deployed to the CDN.

I usually ended up with one of the following results:

  • Top level domain https://myFancyWebsite.azureedge.net wouldn't rewrite the url to the index.html and I would receive a http error 404
  • Top level domain would redirect to index.html but would stop working once I added a url path https://myFancyWebsite.azureedge.net/login/callback - once again a http error 404 as soon as I started using /login/callback
  • Top level domain would rewrite the url to something like https://myFancyWebsite.azureedge.net/cdn/cdn/cdn/cdn/cdn/cdn/cdn/cdn/cdn/cdn .... in an http error 431

The offical documentation from Microsoft also didn't help in my case.

I am pretty sure I am not the first one who is deploying an Angular application to storage account and someone has run in the same issues as I have.

I am thankful for any information which points me in the right direction because at the moment I am definitely thinking about moving away from whole storage account deployment.


Update 1


With the following source pattern ((?:[^\?]*/)?)($|\?.*) which was also mentioned in the article over here, I am able to handle at least the top level domain rewrite to the index.html file.

Unfortunately, I still need an additional pattern to redirect from https://myFancyWebsite.azureedge.net/login/callback to https://myFancyWebsite.azureedge.net/index.html


Update 2


I am currently updating the regex pattern once or twice a day and once again it works on my test environment but stops working once I deploy it. I start to believe that Azure CDN is appending something to the URL after the top-level domain but I have no idea how to verify that.

https://regex101.com/r/KK0jCN/23


Update 3


We are writting the year 3025 and I still have no clue why for example the following pattern isn't handling the url rewritting of the top domain.

https://regex101.com/r/KK0jCN/25

Kelby answered 21/3, 2018 at 8:11 Comment(7)
why are you use cdn as a server?Josey
well .. in theory I really liked the concept of just publishing static files to a storage account ... but in practise, it's now definitely another story ... definitely not enough documented and to be honest I don't think it's quite ready to be used like that yet ..Kelby
yes, cdn use for content delivery only and use as static file. Don't use as a SPAJosey
an SPA is all about static files you know ... the logic on the server is usually just a few rewritting rules.Kelby
For Angular routing (including the exact use case you're asking - redirecting naked paths to the root index.html) and default document, see my answer here: #47072082Bloodthirsty
I've implemented this 1:1 but the rewrite didn't work. I've also seen simular answers in other SO topics but also no luck there. Just out of curiosity, what version of Angular are you using? I just triggered another deployment of the rule you just mentioned - just to double check.Kelby
I have to correct myself - it seems to work with your pattern. Please post this as an answer so I can award you the reputation. Am I able to split it somehow? I would like also to give some of it to Bruce Chen for his effort.Kelby
B
13
  • Add a new rule with condition If Always
  • You will need to add a new Feature for each endpoint.
  • For the Pattern, enter [^?.]*(\?.*)?$. This pattern catches URL paths with . in them, but doesn't care whether or not it's in the query string.
  • For the Path, enter origin_path/document.ext. This is the tricky part. The Path is relative to the origin root. For instance, if your CDN endpoint's origin path is /origin_path and you want to redirect to index.html, you would enter origin_path/index.html. This will always be the case if your CDN is backed by an Azure Storage Account and the origin points to a container.
  • Click Add to add your rule, wait N hours, and you're good to go.
Bloodthirsty answered 28/3, 2018 at 13:51 Comment(4)
I'm assuming the Pattern is for the Source pattern field while adding a new feature. What about the Destination Pattern? You're leaving that blank? Also, I'm assuming the Path field is the Origin Path in the Azure portal NOT in the Verizion Rules?Do
@JohnSmith The Destination pattern is the origin path which is set in your Azure portal settings + index.html. All of this is written in the Verizon rules engine. So if your origin path is "/cdn" then in the Destination pattern you would write, "cdn/index.html"Gorey
Also dont forget to add a public access to blobs and containers for azure storage account, otherwise cdn would complain blob not foundJanis
It works. Be patient just in case the rule has not yet finished being applied to the CDN.Gassaway
D
1

For your requirement, I tested this issue on my side. Per my test, you could try to leverage the following URL Rewrite rule:

Source pattern: (http[s]?://[^\?/#]+)(/(?!images)(?!scripts)[^\?#]*)?($|[\?#].*)

Destination pattern: $1/index.html$3

Note: For loading other files (.ico,.txt,.js,.css,etc) correctly, you need to move them into new virtual directories instead of the root of your blob container. For example, you could move image files into cdn\images and move JavaScript files into cdn\scripts, then the regular expression would ignore the related virtual folders.

Additionally, you could use Azure Web App to host your static website and choose the Free pricing tier or the Shared tier which would cost you $9.49 per month per instance. Details you could follow Pricing calculator.


UPDATE:

Based on Justin's answer, I checked this issue and found that for Blob storage origin type, the Source and Destination under URL Rewrite are talking about the request against the blob storage endpoint. So we need to set regular expression against the request path and query string for the blob endpoint.

Justin Gould has provided the answer for rewrite everything to cdn/index.html. Based on your scenario, I have tested my rule and it could work on my side.

enter image description here

TEST:

enter image description here

enter image description here

Duty answered 27/3, 2018 at 9:24 Comment(7)
I've swapped to Azure Web App yesterday and gave up on the CDN solution. Nevertheless, I will take your pattern and let you know, if it worked! Thanks for your answer. Did you test this on regex101 or on a live application with a rewriting rule?Kelby
I just tested it on regex101.com. All requests would rewrite to index.html along with the query string, while the request path starts with images,scripts, the rule does not take effort.Duty
Hey Bruce, thank you very much for your help. My regex also all worked on regex101.com but none of them worked, once deployed to the Azure CDN. Somehow they don't seem to be triggered and it's really a pain to troubleshoot this issue due to the lack of logs. Furthermore the deployment for each rule can take up to 4 hours.Kelby
I would set up Azure CDN on my side, and I would let you know the result.Duty
The big issue I've found is that the rewrite target is relative to the origin root. If your origin path is /container, the rewrite target is container/index.html for instance.Bloodthirsty
In the past I'd also tried various pattern with adding the the orgin-path to the destination part of the rewrite rule - still no success though.Kelby
Since you have ended this issue, I still try to achieve your scenario based on Justin's answer. You could follow my updated part for detailed test.Duty
I
-1

Just to add to this. If you're using Azure Verizon Premium CDN and your Azure endpoint is using an origin path. The origin path is a part of the rewrite. For example, lets say you're pointing to a versioned folder inside your $web blob.

Azure Endpoint Settings

So if in the above picture "Origin path" is 2.1.2 and your current static application is in $web/2.1.2/, then your rewrite for the CDN would be Source: /<your-verizon-origin>/<your-azure-endpoint>/(.*)\/[^?.]*(\?.*)?$ --> Destination: /<your-verizon-origin>/<your-azure-endpoint>/$1/index.html

Verizon Premium CDN Rule

Inelegancy answered 27/7, 2020 at 14:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.