poppastring / dasblog-core

The original DasBlog reimagined with ASP.NET Core
MIT License
469 stars 193 forks source link

Adding CDN support for binary content. Configurable from site.config. #678

Closed noopman closed 1 year ago

noopman commented 1 year ago

This approach adds code to dasblog-core along exactly the same vein as the present code base.

However it feels slightly overworked, as the actual business logic change, other than one more site.config setting, ultimately is one line of code.

The alternate approach would be to inline the code change in the constructor of the FileSystemBinaryManager and set the CDN domain in the binaryRoot field. Happy to do either.

As I see it this extends an easy CDN option for those that wish to host their blog with a CDN. I will also add this in detail to the wiki documentation.

poppastring commented 1 year ago

@noopman Thanks for the PR! I do not use a CDN myself, so I am really not very well positioned to comment on the solution. My only opinion is that I would be eager for this to work with as many CDNs as possible, specifically is this the most common way to push assets to the CDN?

@shanselman Curious what you think, do you use a CDN for your site? How do your assets get pushed to the CDN?

noopman commented 1 year ago

If you look at an image link in the latest @shanselman blog post. The image in the post is located here https://hanselmanblogcontent.azureedge.net/Windows-Live-Writer/f76e92f681b3_FC6E/image_cb60bf43-6d0a-41f9-9ff5-246f288adedf.png. This referencing the CDN host. The same image (the origin) can be found on Scott's blog here: https://www.hanselman.com/blog/content/binary/Windows-Live-Writer/f76e92f681b3_FC6E/image_cb60bf43-6d0a-41f9-9ff5-246f288adedf.png.

A side note is that Scott is exposing the CDN base domain and has no custom domain name deployed.

If I were to venture a guess then Scott has configured his CDN instance to host content from the domain and path https://www.hanselman.com/blog/content/binary/. This is completely fine! My implementation of CDN replacement supports this. Scott would configure the new setting in site.config like this: <CdnRoot>https://www.hanselman.com/blog/content/binary/</CdnRoot>.

If someone were to set up their blog today, instead they might do this:

<Root>https://www.example.com/blog/</CdnRoot>.

<CdnRoot>https://cdn.example.com/blog/</CdnRoot>.

All binaries will of course, as always, be hosted on the blog application instance, and when you use for example Open Live Writer or any other client to author a blog, the server will return the CDN hosted Uris for the binaries.

We should test a couple of more times first to validate that I am capturing all scenarios, before we merge this. I think I am, but a validation would be appreciated!

noopman commented 1 year ago

Oh, sorry, I did not fully answer the question. The only difference is that, rather than returning the app/content/binary based Uris, we are configuring a CDN host, and the returned Uris point to the CDN location. This means the blog posts stored in the dayentry xml files will refer to the CDN locations. Again, all files are still always sourced (the origin) from the blog application. No difference there. The CDN finds the origin files there when someone requests a CDN reference. Makes sense?

shanselman commented 1 year ago

As long as its compatible with my setup (ideally I can just swap out the URL and path then I love it.

On Sun, Jan 8, 2023 at 1:43 AM Magnus Mårtensson @.***> wrote:

Oh, sorry, I did not fully answer the question. The only difference is that, rather than returning the app/content/binary based Uris, we are configuring a CDN host, and the returned Uris point to the CDN location. This means the blog posts stored in the dayentry xml files will refer to the CDN locations. Again, all files are still always sourced (the origin) from the blog application. No difference there. The CDN finds the origin files there when someone requests a CDN reference. Makes sense?

— Reply to this email directly, view it on GitHub https://github.com/poppastring/dasblog-core/pull/678#issuecomment-1374779234, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAAWTHQXHOIBERXYVS55Y3WRKD3PANCNFSM6AAAAAATUAFM3I . You are receiving this because you were mentioned.Message ID: @.***>

poppastring commented 1 year ago

One last question @noopman Is changing a CDN location a thing? Do we need to support moving? Would that be fairly easy by updating the config then updating the blog post?

noopman commented 1 year ago

When you use a CDN your binaries are uploaded to dasblog-core and hosted on the blog application instance, same as always.

Then you set up a CDN endpoint to point to the web application and distribute local access to your binaries around the globe.

This gives you another endpoint to your files.

If you have https://example.com as your domain, your dasblog-core images would by default be hosted at https://example.com/content/binary/. When you set up a CDN endpoint to point to your domain for example have the endpoint https://cdn.example.com, or in Scott's case - without a custom domain; https://hanselmanblogcontent.azureedge.net/.

The CDN uses "DNS magic" to allow a client to request a binary from the CDN domain, and be served this file from lots of different origins around the world. However, the CDN itself requests these files from the origin - the dasblog-core server.

Now, if a person has used dasblog-core and has lots of old posts and binaries, all the blog posts (in the .xml files) have urls that reference the original domain. It is possible to run a script that opens each xml file and does a search and replace on the references to files under /content/binary to give them a new CDN-based host name. That can certainly be shown as an example of migration. If @shanselman is interested in rolling out a new CDN endpoint for his blog we can use his blog and blog posts as an example!

The advantage of having a CDN is obviously that your binary content may be served to clients geographically much closer to the client - thus faster. And the advantage of using a custom domain name is that your binary content, though physically stored at the origin on the web server, is sourced from your own domain (cdn.example.com), and not from a different service domain (hanselmanblogcontent.azureedge.net).

The easiest of course is that I modify my code slightly to allow the dasblog-core user to specify exactly what part of the binary urls am I replacing with exactly what other part?

For example.com the answer is example.com is replaced by cdn.example.com. For Scott the answer is hanselman.com/content/binary is replaced by hanselmanblogcontent.azureedge.net. It depends on how you set up your CDN endpoint.

My conclusion is that this must be explicit so that it allows for various setups.

noopman commented 1 year ago

I am now pretty confident that my code works! @shanselman you should be able to deploy this branch and test it.

Once deployed you have the ability to configure CDN. If there is no configuration in place, nothing changes at all. If there is a configuration similar to that below, then the code in this branch will replace the <root>/<binaryDir> default configuration with that which matches your CDN setup.

image

I have tested in various ways with and without CDN configuration, and trying to configure it incorrectly. I notice that I needed to restart the application for changes to apply. It works very well for me in my testing.

Are you willing to test @shanselman if the same works for you?