Archive for April, 2012

Extending, Currying and Monkey Patching. part 1

April 29, 2012

Extending

The JavaScript Function.prototype.call and Function.prototype.apply methods allow us to extend an object with additional functionality.
The first argument to Function.prototype.call and Function.prototype.apply is the object on which the function is to be:
temporarily added to, invoked, then removed again.
The first argument is bound to this for the current scope (within the current function body).
Be wary of what this is bound to. I talk a little more about this below.
If you have no arguments to pass to the applied method, call or apply will achieve the same result.

The way I remember how the call and apply functions work, is like the following:

BINARYMIST.extensions.minutes.remaining applied to (BINARYMIST.coffee)
Method on the left is applied to the object on the right.

First we create our single global object (line 01) that will be used as a namespace
On line 05 we declare the extensions object and augment it to our single BINARYMIST object.
You can see on line 07, this is how we create extension methods in JavaScript.
If we replaced the apply method from line 34 with call,  the outcome would be exactly the same.
You’ll also notice on line 34 and 35, that the remaining method of BINARYMIST.extensions.minutes returns a minutes property.
Once BINARYMIST.extensions.minutes.remaining is applied to BINARYMIST.coffee, return this.minutes now returns a function that returns privateMinutes.

javascript binding callback

You can copy past the below code:

var BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {/*if BINARYMIST is falsy, create a new object and pass it*/}));

BINARYMIST.extensions = (function () {
   var localExtensions = {}; // private
   localExtensions.minutes = {
      minutes: 0,
      remaining: function () {
         // this is bound to the object that "remaining" is a member of at runtime, because "remaining" is a property of the object "localExtensions.minutes".
         // If "remaining" was not the property of an object, it would be invoked as a function rather than a method. "this" would be bound to the global object.
         return this.minutes;
      }
   };

   return localExtensions;
}());

var BINARYMIST = (function (binMist) {
   var privateMinutes = 5;
   binMist.coffee = {
      type: "ShortBlack",
      member: function () {
         return privateMinutes;
      }
   };
   return binMist;
}(BINARYMIST || {}));
// Function.call, Function.apply are interchangeable if your only using a single parameter.
// The first argument of call or apply can also be a primitive value, null or undefined.
// Either way it will be bound to the this object.
// A word of warning here:
// When a function is not the property of an object, then it is invoked as a function.
// The this object is then bound to the global object (One of the poor design decisions in JavaScript).
var deliveryTime = BINARYMIST.extensions.minutes.remaining.apply(BINARYMIST.coffee);
alert("Your coffee will be ready in " + deliveryTime() + " minutes");

In continuing with the code comment immediately above:
If the first parameter to apply or call is null, then the this is bound to the global object upon invocation.
When you invoke a function that is not a method, this is exactly what happens.

You may have noticed, I’m using the module pattern in the above example.
This pattern is effective for getting our objects nicely nested into a single namespace (or more correctly an object ) that sits in the global object.
This stops us from littering the global space with every object we create.
You can also see from the following image, what’s private and what’s public.
So we can easily define accessibility.

JavaScript global scope abatement

What are the differences between apply and call then?

call

You can think of Function.prototype.call as being syntax sugar on top of Function.prototype.apply.
If you only have a single parameter after the first, your better off to use Function.prototype.call as it’s more efficient than creating an array for a single value.

The difference is in the parameters after the first invocation context argument.
With call, an arbitrary number of arguments can be passed.
Following the first argument, each argument will be passed to the extension method. In our case remaining (line 09 above).
So we could make the following changes to the above code.
You’ll notice on line 8 below once applied to BINARYMIST.coffee, no longer returns a function, because we explicitly set this.minutes to a number… 3.
Now in the below example on line 16, if we fail to pass an argument to BINARYMIST.extensions.minutes.remaining, by default our coffee will be ready in 10 minutes.

BINARYMIST.extensions = (function () {
   var localExtensions = {}; //private
   localExtensions.minutes = {
      minutes: 0,
      remaining: function (numberOfMinutes) {

         var defaultMinutes = 10;
         this.minutes = numberOfMinutes || defaultMinutes;

         return this.minutes;
      }
   };
   return localExtensions;
}());

var deliveryTime = BINARYMIST.extensions.minutes.remaining.call(BINARYMIST.coffee, 3);
alert("Your coffee will be ready in " + deliveryTime + " minutes");

Better still, lets pass a couple of arguments..
While we’re at it, lets tidy things up a bit.
Lets put the code we use to test the extensions on our coffee into an immediately invoked function expression,
also known as an anonymous closure.
You can see this on line 36.

On line 15 we assign localSpent the second argument we passed in (minutesSpent),
but only if we’re sure it’s a number,
else we assign the undefined value.

var BINARYMIST = (function (binMist) {
   return binMist;
} (BINARYMIST || {/*if BINARYMIST is falsy, create a new object and pass it*/}));

BINARYMIST.extensions = (function () {
   var localExtensions = {}; // private
   localExtensions.minutes = {
      minutes: 0,
      remaining: function (numberOfMinutes) {
         var defaultMinutes = 10;

         // check our numbers are actually numbers.
         var isNumber = function isNumber(num) { return typeof num === 'number' && isFinite(num);}
         var localRemaining = isNumber(numberOfMinutes) ? numberOfMinutes : defaultMinutes;
         var localSpent = isNumber(arguments[1]) ? arguments[1] : undefined;

         this.minutes = {remaining: localRemaining, spent: localSpent}
         return this.minutes;
      }
   };
   return localExtensions;
}());

// lets add some coffee
var BINARYMIST = (function (binMist) {
   var privateMinutes = 5;
   binMist.coffee = {
      type: "ShortBlack",
      minutes: function () {
         return privateMinutes;
      }
   };
   return binMist;
}(BINARYMIST || {}));

(function () {
   var minutesRemaining = 3;
   var minutesSpent = 7;
   var deliveryTime = BINARYMIST.extensions.minutes.remaining.call(BINARYMIST.coffee, minutesRemaining, minutesSpent);
   var minutesSinceOrder = deliveryTime.spent || 'a number of';
   alert("You placed your order " + minutesSinceOrder + " minutes ago. Your coffee will be ready in " + deliveryTime.remaining + " minutes.");
}());

On line 39 we pass in a couple of arguments.
Now to show another cool feature of JavaScript,
because I hate to miss a good opportunity.
All functions come with an arguments array.
This parameter is populated with all the arguments that were supplied to the function on invocation.
This includes any arguments that were not assigned to parameters.
As you can see below, arguments holds both values we passed in.

JavaScript argument's array

Now if we only pass in the first argument to the specified parameter, when line 41 is executed, we get…

apply

The difference with Function.apply is that it only takes 2 arguments.
The second being an array of arbitrary length.
Function.apply works with array-like objects as well as true arrays.


// show a new BINARYMIST.extension.minutes that takes an array

var minutesRemaining = 3;
var minutesSpent = 7;
var minutes = [minutesRemaining, minutesSpent];
var deliveryTime = BINARYMIST.Extensions.minutes.remaining.call(BINARYMIST.coffee, minutes);

Bind

In response to Mike Wilcox’s comments on the JavaScript Linked-in group
I’ve added some info on Function.prototype.bind introduced in Ecma 262 (I think).

This function is very similar to Function.prototype.call.
In fact the only difference I can see is that bind essentially returns a reference to the function that applies the function we want to apply to a target function.
Essentially this allows us to re-use an applied function, rather than create one each time we want to execute.
bind has the same function signature (has the same parameters) as Function.prototype.call.
This following example was taken from Mike West’s post here with some small changes and comments added.

This is tested and works as you would expect.

var first_multiply;
var second_multiply;

var first_object = {
   num: 42
};

var second_object = {
   num: 24
};

function multiply(mult) {
   return this.num * mult;
}

Function.prototype.bind = function (obj) {
   // When a function is not the property of an object, then it is invoked as a function:
   // Now because bind is a property of Function.prototype
   // and multiply inherits the bind property (which is a function of course) because multiply's prototype is Function's prototype.
   // this is bound to the bind properties object... which in this case is multiply.
   var method = this
   var temp = function () {
      return method.apply(obj, arguments);
   };
   // temp holds a reference to our bind functionality
   return temp;
}

first_multiply = multiply.bind(first_object);
document.writeln(first_multiply(5) + ''); // returns 42 * 5

second_multiply = multiply.bind(second_object);
document.writeln(second_multiply(5) + ''); // returns 24 * 5
Advertisements

Supporting multiple sites with a single SSL Certificate

April 9, 2012

There are a couple of ways I’m aware of you can support multiple web sites with a single SSL certificate using the same port.

  1. Wild card certificate
    Useful for when your collection of sites are on the same domain.
    For example:
    mysane.site.com, myinsane.site.com, mycrazy.site.com
  2. Unified Communications Certificate (UCC) / Subject Alternative Name (SAN) / MultiDomain
    Useful for when your collection of sites are on different domains.
    For example:
    mysanesite.com, myinsanesite.com, mycrazysite.com

You can choose to purchase a SSL cert,
you can use convergence (check out Moxie Marlinspikes talk on the subject),
or you can create a self signed one.

If you chose to create a self signed certificate

IIS 7.x

Click on the root machine node in the left tree view of IIS (7.x) manager.
Then double click the “Server Certificates” icon in the Features View.

Server Certificates

This will show you all the certificates currently registered on the server.
You will be able to see in the Actions pane,
that you can Import or create your own certificate.
To create the self signed wild card certificate,
chose “Create Self-Signed Certificate…”.
Give it the friendly name *.site.com
Ok.
The certificate will be registered on you machine.

Server Certificates

Now for each site you want to use the certificate for,
right click -> Edit Bindings… -> Add.
Select the Type to be https,
and select the certificate you just created from the SSL certificate drop down menu.
Ok -> Close.
Repeat these steps for the rest of the sites you want to share the certificate.

Using the appcmd utility

We now add the https binding and host information to our sites that need to share the wild card certificate.

Run a command prompt as administrator and

cd to %WINDIR%\system32\inetsrv

The format of the command looks like the following:

appcmd set site /site.name:"<your website name>" /+bindings.[protocol='https',bindingInformation='*:443:<your ssl domain>']

For our above three sites we wanted to use the same certificate,
mysane.site.com, myinsane.site.com, mycrazy.site.com
They may be named respectively:
mysane, myinsane, mycrazy
So for example,
we’d run the following commands:

appcmd set site /site.name:"mysane" /+bindings.[protocol='https',bindingInformation='*:443:mysane.site.com']

You should get feedback similar to the following:

SITE object "mysane.site.com" changed

if all goes well

appcmd set site /site.name:"myinsane" /+bindings.[protocol='https',bindingInformation='*:443:myinsane.site.com']

You should get feedback similar to the following:

SITE object "myinsane.site.com" changed

if all goes well

appcmd set site /site.name:"mycrazy" /+bindings.[protocol='https',bindingInformation='*:443:mycrazy.site.com']

You should get feedback similar to the following:

SITE object "mycrazy.site.com" changed

if all goes well

Although I normally keep it simple and name my sites the same as the URL (your ssl domain) I want to use.

IIS 6

Now this is a bit more work than with IIS 7.

If it’s not already installed, you’ll need the SelfSSL tool.
You can get this from the SSL Diagnostics Kit or the IIS 6.0 Resource Kit which contains lots of other stuff.
Once installed, run IIS.

Create the self signed wildcard certificate

You’ll need to generate the certificate for one existing IIS site.
For the first site take note of the site idendifier.
You can see this in the right pane when you select Web Sites from the server node in the IIS manager.
Open a command prompt, you’ll need to run the SelfSSL app.
Actually I think the easiest way to run this is Start menu -> All Programs -> IIS Resources -> SelfSSL -> SelfSSL.
The command string looks like this:

selfssl /n:cn=<your wild card domain> /s:<first website identifier> /P:<port you want to use> /v:<number of days to expiration>

So for example, we’d run the following command:

selfssl /n:cn=*.site.com /s:1 /P:443 /v:365

Options for SelfSSL

selfssl /?

some of them are:

/N: – This specifies the common name of the certificate. The computer name is used if there is no common name specified.
/K: – This specifies the key length of the certificate. The default is length 1024.
/V: – This specifies the amount of time the certificate will be valid for, calculated in days. The default setting is seven days.
/S: – This specifies the Identifier of the site, which we obtained earlier. The default will always be 1, which is the Default Web Site in IIS.

Assign the certificate to the sites that need it

Have a look at the site properties in IIS Manager -> Directory Security tab -> Server Certificate button.
This will start the IIS wizard.
Click Next -> Assign an existing certificate -> Next.
You should see the wild card certificate you created.
Select it, click next, and make sure you assign it the same port that was assigned to the first site.

Configure the SecureBindings

In order for IIS to use the host headers with SSL and secure the certificate as we did with appcmd,
you’ll need to run the following command for each of the sites that require it.
My adsutil is found in C:\Inetpub\AdminScripts\
It’s probably not in your path, so you’ll have to run it from location.
cscript adsutil.vbs set /w3svc/<website identifier>/SecureBindings ":443:<your ssl domain>"
So for example, we’d run the following command:
cscript adsutil.vbs set /w3svc/1/SecureBindings ":443:mysane.site.com"
That should be it.

Now if you need to remove a certificate from your store

Run mmc.exe
File menu -> Add/Remove Snap-in… -> Add… -> select Certificates -> Add -> select Computer account -> Next -> select Local computer -> Close -> Ok.
Select the Certificates node, expand Personal, Certificates.
Now in the right window pane, you can manage the certificates.
Delete, Renew etc.