It has become increasingly important to have your site secured via some kind of certificate. Even your Google ranking is affected by it.

The main problem with SSL/TLS certificates is the fact most of them cost money. Now, I don’t have any problem with paying some money for something like a certificate, but it will cost quite a lot if I want to set this up for all of my sites & domains. In theory it’s possible to create a self-signed certificate and publish your site with it, but that’s not a very good idea as there’s no one who trusts your self-signed certificate besides yourself.

Luckily Mozilla is helping us, poor content-creators, out with their service called Let’s Encrypt. Let’s Encrypt is a rather new Certificate Authority which is offering a free, open and automated service to create certificates. Their Getting Started guide contains some details on how to set this up for your website or hosting provider.

This is all fun and games, but when hosting your site(s) in the Azure App Service ecosystem you can’t do much with the steps defined in the Getting Started guide. At least, I couldn’t make any sense off it.

There’s a developer who has been so kind to create a so called Site extension for an Azure App Service called Azure Let’s Encrypt. It comes in two flavors for both x86 and x64 systems. Depending on which platform you have deployed your site to, you need to activate one corresponding this platform.

image

In order to access these site extensions you’ll have to log in to the Kudu environment of your site (https://yourAzureSite.scm.azurewebsites.net/SiteExtensions/#gallery).

Once it’s installed you can launch the extension and will navigate to the configuration area of this extension. This screen will show you a number of fields for which most of them have to be filled with correct data.

image

This form can look quite impressive if you are not familiar with these things. I’m not very familiar with these terms also, but Nik Molnar has a nice post with some details on the matter.

He mentions you should first create two new application settings within the Azure Portal for the App Service you want to enable SSL. The name/key of these settings are AzureWebJobsStorage and AzureWebJobsDashboard. Both should contain a connectionstring to your Azure Storage account, which will look something like the following DefaultEndpointsProtocol=https;AccountName=[storage account name];AccountKey=[storage account key]. The storage account is necessary for the WebJobs, which will be created by the site extension in order to refresh the SSL certificate.

Next up is the hardest part, creating a Server Principal and retrieving a Client Id and Client Secret from it. In this context, a Server Principal can be seen as some kind of authentication server.
If you already have a Server Principal, you can skip the step of creating one. I still had to add one to my subscription. The following script will create one for you.

$uri = 'http://mysubdomain.mydomain.nl'
$password = 'SomeStrongPassword'

$app = New-AzureRmADApplication -DisplayName 'MySNP' -HomePage $uri -IdentifierUris $uri -Password $password

Needles to say, your PowerShell context needs to be logged in into your Azure subscription before you are able to run this command.

You are now ready to add your application to the server principal with the following commands.

New-AzureRmADServicePrincipal -ApplicationId $app.ApplicationId

New-AzureRmRoleAssignment -RoleDefinitionName Contributor -ServicePrincipalName $app.ApplicationId

These commands will add the application and make sure it has the Contributor role, so it will have enough permissions to install and configure certificates.
Make sure you write down the $app.ApplicationId which will be used as the Client Id in the site extension later on.

Now that we have all the information to configure the Let’s Encrypt site extension, we are ready to install it on our App Service. In order to make this even easier, please configure the following Application Settings in your App Service.

KeyValue

letsencrypt:Tenant

Your AAD domain
(yoursubscription.onmicrosoft.com)

letsencrypt:SubscriptionId

Your Azure Subscription Id
Can be found on the Overview page of an App Service

letsencrypt:ClientId

The $app.ApplicationId we saved from before

letsencrypt:ClientSecret

The $password value used in the earlier script

letsencrypt:ResourceGroupName

The resource group name your App Service is created on

After installing the site extension, navigate to the configuration page. If all is set up correctly, the fields will all be prefilled with the correct information.

image

Check the settings and adjust them if necessary. When you are sure everything is set up correct, proceed to the next page.

This next page isn’t very interesting at this time, so we can continue to the final page of the wizard.

image

Nothing very special over here, just make sure to fill out your e-mail address so you are able to receive notifications from Let’s Encrypt when necessary.

Also good to note, don’t check the Use Staging option. By checking this box the extension will use the test API of Let’s Encrypt and will not create a certificate for you.

Press the big blue button and your site will be available with the certificate after a few moments. The extension uses the challenge-response system of Let’s Encrypt to create a certificate for you. This means it will create a couple of directories in the wwwroot folder of your App Service. This folder structure will look like .well-known\acme-challenge.

image

If this succeeds, Let’s Encrypt is able to create your certificate.

The challenge-response system folders are hard-coded in the extension. If you run your site in subfolder, like public, website, build, etc. you have to specify this via a special variable. You can add the letsencrypt:WebRootPath key in the application settings and specify the site folder in the value, for example site\wwwroot\public. This is very important to remember. I had forgotten about this on one of my sites and couldn’t figure out why the creation of the SSL certificate didn’t work.

Now that you know how to secure your sites with a free certificate, go set this up right away!

Including a lot of files in your website can impact the performance of your site. Your browser needs to request all those files from the webserver(s) and download them individually. Luckily this fetching is pretty fast and your browser can do multiple requests at once. However, there is a maximum to the number of requests a browser can make, so if you include 100 external files, will probably be (relatively) slow.
I’ve tested this by creating a new MVC 3 web application, copying the Site.css file 12 times and include all of them in the head-element of the page. Below you can see the FireBug and YSlow reports for this test page.

image
image
I’ve pressed the Refresh-button several times and came to the conclusion each individual file has a loading time between 5ms and 25ms.
Even though 13x25ms still is pretty fast, you probably understand it’s better to minimize the number of requests, because each request has some overhead and some have to wait for the other to be completed.

To minimize the number of files which need to be included in a website, devigners often create one huge CSS file and one huge JavaScript file which contains everything needed for the website to work. This way the browser only needs to make 3 requests to load the page, the HTML, the CSS and the JavaScript. An additional request will be made for the JavaScript framework you are using (if any) and some more additional requests will be made to fetch the images of the page you are loading.
To test if including 1 big file really is faster, I’ve tested it again with FireBug and YSlow. For this test, I’ve concatenated the contents of theSite.css file 13 times in the SiteFull.css file, so the total styling file size will be the same as with 13 independent files.

image

image

As you can see in these results, loading a single CSS-file will only take about 2ms to 19ms. Now let’s say my development computer was super-fast while testing with the SiteFull.css file, even if fetching the file would take up twice as much time, it would still be faster as 13x25ms or even 13x5ms.

The conclusion to this test is: Bundling all styling in 1 huge file will give much faster loading times as separating them in several smaller files.

This conclusion is widely spread and most devigners already know about it, so it would be obsolete for me to point it out again. The thing which bothered me about this approach is the usage of mobile devices and/or having low bandwidth.
Putting all styling for your complete website is a waste of bandwidth if the user will only check out 1 or 2 pages. This user probably doesn’t need most of the style sheet, yet he has downloaded it. Loading the full set of styling on your device is probably useful when caching it locally (or on a proxy server), but if you don’t need it, why load it anyway?

Because I wanted to test if loading style sheets (and maybe JavaScript files) can be done smarter, I’ve created a possible solution for this. I’ve introduced a new HttpHandler, called CSSXHandler. This CSSXHandler will handle all requests which have the cssx-extension.
The implementation is fairly simple. You make a request to let’s say the homepage.cssx file. The handler will pick up this request, load the necessary CSS files in memory and output the necessary contents for this request.
The initial implementation for this handler looks like this.

public void ProcessRequest(HttpContext context)
{
    var currentStylesheet = DetermineRequestedStylesheet(context);

    switch (currentStylesheet.ToLower())
    {
        case "homepage":
            GenerateHomepageStylesheet(context);
            break;
    }
}

private string DetermineRequestedStylesheet(HttpContext context)
{
    int locationOfLastSlash = context.Request.RawUrl.LastIndexOf("/");
    int locationOfExtension = context.Request.RawUrl.LastIndexOf(".cssx");
    int numberOfCharactersBetweenSlashAndExtension = locationOfExtension - locationOfLastSlash;
            
    return context.Request.RawUrl.Substring(locationOfLastSlash + 1, numberOfCharactersBetweenSlashAndExtension - 1);
}

private void GenerateHomepageStylesheet(HttpContext context)
{
    var fullCssFileStream = new System.IO.StreamReader(context.Server.MapPath("~/Content/SiteFull.css"));
    string fullCssFileBody = fullCssFileStream.ReadToEnd();

    fullCssFileStream.Close();
    context.Response.ClearHeaders();
    context.Response.AddHeader("Pragma", "no-cache");
    context.Response.AddHeader("Content-Type", "text/css");
    context.Response.Write(fullCssFileBody);
}

As you can see, I’m loading the SiteFull.css file and read the contents in a string and output it in a whole. This isn’t production ready code and needs improvement if you want to use it, but it’ll give you an idea how to set it up.

Because I wanted to test the performance penalty of this CSSXHandler compared to loading the single SiteFull.css file in the head, I’ve tested loading the page using this handler (with the homepage.cssx in the head).

image

image

I was pretty surprised by the results. Loading the homepage.cssx file was between 2ms and 9ms, never slower. Compared to loading the SiteFull.css file, which had a maximum loading time of 19ms, that’s almost 50% faster (max). I didn’t believe this at first, but after pressing the refresh button a couple of times more, I couldn’t get it past the 9ms.
Some time ago I’ve read somewhere that when having routing in place, the ASP.NET ISAPI filter(s) first handle static files and they are processed ‘correctly’ afterwards. Too bad I can’t find a decent source for it at the moment. But I figured this is probably the reason for the relative slow loading of the CSS file.

In the above scenario, the full contents of the CSS file are still returned to the browser. The reason for me to write this handler was to minimize the output, so only the necessary styling is returned. To accomplish this, I’ve altered the CSSXHandler a bit. Now it looks like this:

public void ProcessRequest(HttpContext context)
{
    var currentStylesheet = DetermineRequestedStylesheet(context);

    switch (currentStylesheet.ToLower())
    {
        case "homepage":
            GenerateHomepageStylesheetWithOnlyStuffForTheHomePage(context, currentStylesheet);
            break;
    }
}

private string DetermineRequestedStylesheet(HttpContext context)
{
    int locationOfLastSlash = context.Request.RawUrl.LastIndexOf("/");
    int locationOfExtension = context.Request.RawUrl.LastIndexOf(".cssx");
    int numberOfCharactersBetweenSlashAndExtension = locationOfExtension - locationOfLastSlash;
            
    return context.Request.RawUrl.Substring(locationOfLastSlash + 1, numberOfCharactersBetweenSlashAndExtension - 1);
}

private void GenerateHomepageStylesheetWithOnlyStuffForTheHomePage(HttpContext context, string currentStyleSheet)
{
    var fullCssFileStream = new System.IO.StreamReader(context.Server.MapPath("~/Content/SiteFullCSSX.css"));
    string fullCssFileBody = fullCssFileStream.ReadToEnd();
    fullCssFileStream.Close();

    context.Response.ClearHeaders();
    context.Response.AddHeader("Pragma", "no-cache");
    context.Response.AddHeader("Content-Type", "text/css");

    // Start of a region in the CSS file: /* REGION homepage */
    // End of a region in the CSS file: /* ENDREGION */
    string patternForMatchingRegionForCurrentStyleSheet = @"\/\* REGION "+ currentStyleSheet + @" \*\/(.*?)\/\* ENDREGION \*\/";
    var matchingRegion = new Regex(patternForMatchingRegionForCurrentStyleSheet, RegexOptions.Singleline);

    var matches = matchingRegion.Matches(fullCssFileBody);
    foreach (Match match in matches)
    {
        context.Response.Write(match.Groups[1].Value);
    }
}

To be able to output only the styling which is necessary for the homepage, there needs to be something in place which tells us what this is. For this I’ve chosen to implement regions in the style sheet, like below.

/* REGION homepage */

/* All necessary styling for the homepage */

/* ENDREGION */

All styling necessary for the homepage needs to be implemented in these blocks (there can be multiple blocks in the CSS file(s).
The regular expression will search for these blocks and output the contents of it. By implementing this technique you will only output the styling which is needed for the specific page.
Of course I’ve tested this implementation also, below are the FireBug and YSlow reports.

image

image

The performance is fairly similar to outputting the complete SiteFull.css file via the handler, so there isn’t much of a penalty for using the regular expression. However, if you look closely, the file size is much smaller!

The above test scenario only contained 1 match for the regular expression. I wanted to see what the performance was when I added a lot more matches in the big file and also tried out a different notation to support multiple style sheets with the same block.

/* REGION homepage, about, portfolio, blog */
/* ENDREGION */

Using this and having several other matches in the file resulted in the following statistics.

image

image

The result still is fairly similar to the first CSSX test (between 2ms and 9ms). This means you can generate a really dynamic CSS file, load it via the CSSX handler and get a really fast and small style sheet in your page.

All of these tests are performed on my local machine. The specified code isn’t meant for production environments, as it would need some adjustments. Also, I’ve only refreshed the pages about 10 times on my local development machine. If you want to use this in a production environment, consider the consequences before you do. Caching is a lot harder, you don’t have 1 single file in the cache, but multiple. Also, I don’t know if a proxy or browser would cache a file with the cssx extension. It would be wise to load-test this solution first.

At least I proved it’s possible to generate really dynamic style sheets which load fast and have the smallest possible filesize. If you want to try this handler out yourself, or have improvements, I’ve placed the solution on BitBucket as a public repository.
Would love to hear what you think about this and if it’s usable in the real world? I hope to try it out soon on a new website of mine.

Tijdens het werk zat ik weer eens in een CSS bestand wat wijzigingen aan te brengen. Hier stuitte ik ineens op een regel met

@media screen
{
css stuff
}

Zoiets had ik nog nooit gezien en vroeg me dan ook af wat dit betekende. De ontwikkelaar in kwestie wist ook niet meer precies wat dit deed, dus heb ik even gezocht naar dit soort statements.

Blijkbaar kun je in CSS aangeven welk type 'scherm' welke stijl moet hebben. Zo kun je bijvoorbeeld voor een projector, beeldscherm, printer en pocket pc hetzelfde CSS-bestand gebruiken, maar met andere waarden. Dit is wel enorm gaaf.
Door bijvoorbeeld dit te gebruiken:

p { color: green; }
@media screen, projection, tv {
#foo { position: absolute; }
}
@media print {
#navi { display: none; }
}
@media handheld {
#foo { position: static; }
}

Heb je de p-tag voor een handheld, printer, scherm, beamer en televisie anders gedefinieerd.
Je moet wel uitkijken dat je geen idioot moeilijke en onoverzichtelijke code aan het maken bent, maar dit biedt toch potenties.
Volledige uitleg is op deze website te vinden:
http://www.howtocreate.co.uk/tutorials/css/mediatypes/

Behalve de leuke media-types kun je ook nog gebruik maken van een *, # en .-teken.
Het .-teken was bij mij al bekend. Dit heeft volgens mij betrekking op de namen van de klassen.
Het #-teken ken ik sinds vandaag ook. Deze wordt gebruikt om de stijl van een bepaald ID in je HTML te definieren. Dit kan ook handig zijn, als een speciaal ID iets meer moet opvallen als de rest. Zo kun je weer weer grote if-statements besparen in je code.
Het *-teken is ook wel handig. Dit wordt gebruikt om alle elementen van een bepaald type eenzelfde stijl te geven. Als je dit dus opgeeft voor een body-tag, krijgen alle body's de stijl die bij het *-teken is gebruikt, ongeacht de klasse die ze hebben.
Ook kan het bijvoorbeeld zo worden gebruikt

* {
margin:0;
padding:0
}

Een mooiere uitleg met ander voorbeeld is hier te vinden: http://www.dustindiaz.com/css-asterisk-the-universal-rule/

Toch weer een leerzame dag geweest.