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

fix: MERC-9364 Use CDN Original images for webdav - cache control #298

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

christensenep
Copy link

@christensenep christensenep commented Dec 29, 2023

What? Why?

Use CDN Original images for webdav - cache control. Take 2. See bigcommerce/paper#343

If a developer/merchant uses the cdn handlebars helper to inject images from webdav into the theme using e.g.({{cdn "webdav:/img/image.jpg"}}), there is no cache-control header when the image is fetched on the storefront.

Similar to our Image Manager, we should be using the cdn original images (Similar to Jinsoo's PR here MERC-7127)

This PR differs from the previous as it only does this for file suffixes that image manager supports (jpg/jpeg/png/gif). This avoids the issue where the url is changed for e.g. a pdf, and thus creates a broken link.

How was it tested?

Tested locally and in integration, and with unit tests. Have verified that images (png/gif/jpeg/jpg) uploaded to the content directory via webdav can be accessed at their cache-controlled url using the cdn helper (/images/stencil/original/content/<whatever>), while all other file extensions still return the /content/<whatever> path when using the helper.

Behold, the results of outputting some of these urls directly to the DOM:
Screenshot 2024-01-11 at 4 40 25 PM

cc @bigcommerce/storefront-team

@christensenep christensenep changed the title MERC-9364 Use CDN Original images for webdav - cache control fix: MERC-9364 Use CDN Original images for webdav - cache control Dec 29, 2023
Comment on lines 59 to 62
const imgRegex = /(jpg|jpeg|gif|png)$/i;
const isImage = imgRegex.test(path);
const prefix = isImage ? 'images/stencil/original/content' : 'content'
return [cdnUrl, prefix, path].join('/');
Copy link

Choose a reason for hiding this comment

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

I feel like a logic as below is safer as it doesn't assume the image extension. What is your thought?

if (path.length >= colonIndex + 5 && path[colonIndex+5] == '/') {
  const assetType = path.slice(colonIndex + 1, colonIndex + 5);
  let prefix = 'content'
  if (assetType == 'img/') {
    prefix = 'images/stencil/original/content';
  }
  return [cdnUrl, prefix, path].join('/');
} else {
   return [cdnUrl, 'content', path].join('/');
}

Copy link
Author

Choose a reason for hiding this comment

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

I'm not aware that imagers need to be in the img path like that, if they are then I would agree. But just looking at my stores image manager images, they are not.

Copy link
Author

Choose a reason for hiding this comment

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

If we can indeed rely on webdav images always being in that path then yeah that's definitely way better. (And perhaps most importantly, rely on ONLY images being there)

Copy link

Choose a reason for hiding this comment

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

There might be more types we might be missing. But we could make sure we cover all the supported in this https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Image_types

Copy link
Author

@christensenep christensenep Dec 29, 2023

Choose a reason for hiding this comment

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

I was erring on the side of being conservative just given the history here, but yeah I may be overcompensating. Curious as to the opinion of storefront.

Also realized I need to regex to match the . otherwise it'll match a file just named myjpg

@christensenep christensenep requested a review from a team January 11, 2024 19:28
@christensenep
Copy link
Author

♻️ I have tested this with gifs, jpeg/jpgs and pngs, and verified that the new urls are valid and have cache control headers. I have also verified that other file extensions such as pdfs and, importantly, bmps do not change the url from its current form and are thus still valid. I also verified that bmps do not have the images/stencil/content form of the url available, so I believe this is the correct and exhaustive of extensions we should be doing this for.

@christensenep
Copy link
Author

@bigcommerce/team-merchandising @bigcommerce/team-storefront

@@ -56,7 +56,10 @@ module.exports = globals => {
}

if (protocol === 'webdav:') {
return [cdnUrl, 'content', path].join('/');
const imgRegex = /.(jpg|jpeg|gif|png)$/i;
Copy link
Contributor

Choose a reason for hiding this comment

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

do we have somewhere documented the list of supported extensions?

Copy link
Author

Choose a reason for hiding this comment

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

@@ -194,19 +194,40 @@ describe('cdn helper', function () {
], done);
});

it('should return a webDav asset if webdav protocol specified', function (done) {
it('should return an original cdn img asset if webdav protocol specified but file type indicates it is an image', function (done) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just wondering if we can create functional tests for such cases?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants