One issue that arose from my planned switch to serving images from Amazon S3 was: how to deal with HTTPS?
Hitherto, that’s been a non-issue. I used a relative path for images so the switch between HTTP and HTTPS happened automatically and painlessly. Now, of course, there is a potential problem. I have to use fully qualified paths for the images – and if an HTTPS page tries to serve images over HTTP, the browser will give the end user a warning about mixed content. So what to do?
The solution, of course, is to switch the images over to HTTPS along with the rest of the page. S3 supports HTTPS, so that’s fine – but there are still a couple of questions:
I’ll deal with the second one first. One of the nice things about Visual Studio 2012 is that it comes with IIS Express as the development server. That means you can use and test HTTPS/SSL during development. All you have to do is select the website in Solution Explorer and then change the property setting to enable SSL.
That’s it. Now, if you browse to the alternative URL you have HTTPS. You’ll get a warning message because there’s no certificate, but the functionality is all there.
So now we can write code to switch to HTTPS for images and test whether it actually worked.
I decided the easiest thing to do was have two configuration settings – one for standard images and one for HTTPS images. Here is the main configuration for the development setup (I left HTTP as relative, and just switched to a full path for HTTPS):
And here is the configuration transform for deployment to the live setup:
Now the question is – where to pick this up? In the current/old version, I set a ViewBag variable inside the base controller’s constructor. I can’t do that now because I need to find out whether the request uses HTTPS… and the context is not available inside the constructor. So it’s back to the drawing board. I don’t want to have to repeat the code, and I can’t use inheritance to get what I want… so it’s time for attribute based programming – in this case, with an action filter. As the View is about to execute I check if the Request is over HTTPS, and switch the path appropriately.
I’m checking that this is a ViewResult, so I can safely add this as a global filter without have to worry about methods that don’t return views:
So now when I switch over to HTTPS, my path switches appropriately, and I don’t get annoying messages about delivering mixed content:
For other related information, check out this course from Learning Tree: