Thursday, July 26, 2007
Well, that's just the exception to the rule, that only proves the rule. (My Father, when wrong)

A while ago, I complained about how measuring the wrong thing will just make things worse, in particular, how measuring things in software almost never works.
Recently, I read the earth-shattering news that "Transformers" beat the all-time record for first-week revenue by a non-sequel.
"Transformers" beat the all-time record for first-week revenue by a non-sequel.
"Transformers" beat the all-time record for first-week revenue by a non-sequel.
Hmm. Is it, like, good?
Does it mean Transformers is the best thing since (user-generated) sliced bread?
Is it just a sucky flick?
I don't know.
Now, the interesting thing is: how did this ever become the news? Why don't they say "Transformers is the best movie ever", or "John Torturo as a 'section 7' agent is as brilliant as cold fusion"?
And another puzzle, for the advanced reader - why don't you hear about top grossing movies over a year or ten years' period? It's always "first weekend" or "first week".
Here's why:
Movie makers are in it for the money, just like the rest of us. And over the last decade or so, there's this one major obstacle in their little money making business. It's called piracy. It's easier to get an illegal copy of a movie than to get some water from the fridge.
In fact, I'm kind of thirsty now. But I'm not going to get that water. I'm too busy downloading Spiderman 4.
Oh, it's not out yet? No problem. They got it on bittorrent already.
So basically, most money you're going to make on a movie is in the first week or so. After that, everyone has already downloaded it from the internet for free.
Of course, the money people run the movie, not the...hmm...movie people. That's because the money people give the movie people money to buy food, and the movie people, well, they don't give the money people any money.
Now we have money people who run the movie and they want to make some money and they have to do it all in the first week. So they're going to measure, you guessed it, first week revenue.

Why do we care?
Here's the problem - to increase that measurement, which is first week revenue, it is not necessary to make a better movie. You just do better marketing, and more hype, and whatever. Because people who see the movie in the theater during the week don't really get a chance to hear from their friends if it's good or bad. They go because the trailer is really cool, and the ads are everywhere. And so, the quality may or may not suffer. We don't know. Because that's not what we measure.
Here you have an external force (illegal movie copying) creating a random measurement (first week revenue) and potentially driving final product quality down.

And please, don't measure bugs-per-developer either.

I've seen Transformers, by the way. It rocks. Hence my father's quote.

Friday, July 27, 2007 6:26:49 AM (Jerusalem Daylight Time, UTC+03:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, July 21, 2007

Some things I learned about software while watching Die Hard 4.0 and Transformers:

1. A hacker is most of the times a hot chick.
2. A hacker never uses normal operating systems. They have a bizzare OS, that is specifically optimized for their single need - displaying a map of USA with red dots on it.
3. When a computer is hacked into, the screen flickers.
4. Evil hackers, even if hot chicks, will always be proficient at martial arts as well.
5. You can hack a computer system by directing weird sounds at it.
6. Visualization is king - code breaking and pattern recognition are achieved using quick manipulations of 3D images.

Sunday, July 22, 2007 5:22:46 AM (Jerusalem Daylight Time, UTC+03:00)  #    Disclaimer  |  Comments [3]  | 
 Friday, July 20, 2007

Web 2.0. Web two o. Web two o. Web two o. Web two o. Web two o. Web two o. Web two o. Web two o.
I am actually typing this, no copy-paste.
Tim, what have you done to us?
Web two o. Web two o. Web two o.
Donna Martin graduates. Donna Martin graduates. Donna Martin graduates.
Can we please just get it over with?
Web two o. Web two o. Two, zero, o.
Two.
Full stop.
O.
Please. Enough.
Web two o. Web to you. Web to me. Web to us.
Toys'R'Us. Don't call us, we'll call you.
Have a nice weekend everybody, besos.

Friday, July 20, 2007 7:54:02 AM (Jerusalem Daylight Time, UTC+03:00)  #    Disclaimer  |  Comments [2]  | 
 Tuesday, May 01, 2007

Here is a major security vulnerability in applications that use the ASP.NET forms authentication mechanism.

Forms authentication exposes a configuration property called enableCrossAppRedirects. It's default value is false.

However, a simple test showed that this property does not have the desired effect, and it is possible for an attacker to redirect a user to a malicious website from your legitimate login page.

Assuming your login page is at http://www.myapp.com/login.aspx, and login.aspx uses the FormsAuthentication.RedirectFromLoginPage method, the following request will redirect the user to another domain after passing authentication by your application:

http://www.myapp.com/login.aspx?ReturnUrl=http%3a%2f%2fgoogle.com%5c

Although this is not an issue on it's own, it can potentially lead to serious security threats to your users in the form of information stealing attacks.

Another annoyance, is what the MSDN has to say about this. The RedirectFromLoginPage method page in MSDN has a specific note on the potential risks of setting enableCrossAppRedirects to true:

Security Note

Setting the EnableCrossAppRedirects property to true to allow cross-application redirects is a potential security threat. When cross-application redirects are allowed, your site is vulnerable to malicious Web sites that use your login page to convince your Web site users that they are using a secure page on your site. To improve security when using cross-application redirects, you should override the RedirectFromLoginPage method to allow redirects only to approved Web sites.

Well, like we saw, you don't have to set the property to true. It works the same way when set to false.

But by far the most frustrating is

... You should override the RedirectFromLoginPage method to allow redirects only to approved Web sites.

Hmm. Right.

Too bad that the FormsAuthentication class is sealed.

And that RedirectFromLoginPage is static.

Real Solution

The only workaround, in case you really want to disable cross-domain redirects, is to check the ReturnUrl query string parameter in your code, before calling RedirectFromLoginPage.

Tuesday, May 01, 2007 7:13:43 AM (Jerusalem Daylight Time, UTC+03:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, April 14, 2007

Summary:

This one is not short. Better sit down.

I am going to discuss a common problem with web controls that are heavy on client-side javascript code and AJAX requests, and suggest a solution I came up with.

Right.

An Example Control

We'll be working with a sample control. Our control will be a stock ticker control that presents a current price for a stock and periodically gets price updates from the server.

Here's an example of such a thing, taken from Yahoo! Finance:

Stock Ticker from Yahoo! Finance

You can see, that it displays the current stock price, a change in percent from some base price (opening price) and an arrow indicating the change trend.

It also highlights in green values that were recently changed (like the google stock in the screenshot).

(The coding examples are pretty sloppy. It's just an example, remember.)

The basic implementation allows setting the ticker to be displayed and renders a simple HTML table:

public class StockTicker : WebControl

{

public string Ticker

{

get

{

String s = (String)ViewState["Ticker"];

return ((s == null) ? String.Empty : s);

}

set

{

ViewState["Ticker"] = value;

}

}

Code Snippet

private int GetStockValue()

{

Random r = new Random();

return r.Next(1, 100);

}

}

We have a method GetStockValue that returns the current stock price. In our sample implementation it just returns a random value between 1 and 100. In real life it will probably access a database or use a webservice.

Lets test the control by placing it on a web form and running the application:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="SampleApp01._Default" %>

<%@ Register Assembly="SampleApp01" Namespace="SampleApp01" TagPrefix="cc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

<title>Untitled Page</title>

</head>

<body>

<form id="form1" runat="server">

<div>

<cc1:StockTicker ID="StockTicker1" runat="server" Ticker="CSCO" />

</div>

</form>

</body>

</html>

We get a result similar to this:

First Version of Ticker Control

Adding Dynamic AJAX Updates

Now, lets add to our control the ability to receive dynamic price updates from the server using AJAX requests.

I will use the Prototype javascript library to simplify some client-side code.

Let's add a javascript file to the project (I named it StockTicker.js) and add the following code:

function requestPriceUpdateFromServer()

{

var request = new Ajax.Request(

"StockTicker.ashx",

{method:'get',parameters:'', onComplete:showResponse}

);

}

function showResponse(request)

{

$('priceCell').innerText = request.responseText;

}

function periodicallyUpdatePrice()

{

var periodicExecutor = new PeriodicalExecuter(requestPriceUpdateFromServer,3);

}

periodicallyUpdatePrice();

We are sending an AJAX request to to the URL StockTicker.ashx every 3 seconds. You can see that using the Prototype library it's literally a few lines of javascript.

Now let's add an HttpHandler to respond to the requests with the updated price of the stock:

public class StockTickerHandler : IHttpHandler

{

public void ProcessRequest(HttpContext context)

{

context.Response.ContentType = "text/plain";

context.Response.Expires = -1;

context.Response.Write(StockDataProvider.GetStockValue("CSCO"));

}

public bool IsReusable

{

get

{

return false;

}

}

}

The request handler is very simple. You can see that I've refactored the stock data provider into a seperate class StockDataProvider as it is used in both the http handler and the control server code. Also, out of sheer laziness I have hard-coded the CSCO ticker into the parameter. In real life this should be passed from the client as a parameter of the AJAX request. If you run the example now, you will see that the price gets updated every 3 seconds, without re-sumbitting the page.

Some Bells and Wistles

Now let's add some logic to our control. First, after the price of the stock is changed, we will color green or red according to the change in the price (up or down). To achieve this, we modify the showResponse javascript function:

function showResponse(request)

{

var newPrice = request.responseText;

var oldPrice = $('priceCell').innerText;

$('priceCell').innerText = newPrice;

if(newPrice>oldPrice)

$('priceCell').bgColor = 'green';

else if(newPrice<oldPrice)

$('priceCell').bgColor = 'red';

}

The second addition will be to show the change in percent relative to the previous price.

We will modify in three places, first, communication between client and server:

1. Pass the current price from client.

2. Respond with the new price and the change in percentage from the server.

Second - calculate the precent of change on the server.

Thirs - display the change on client, after getting a response from the client.

Here's the modified code on client side:

function requestPriceUpdateFromServer()

{

var data = $('priceCell').innerText;

var currentPrice = data.split('(')[0];

var request = new Ajax.Request(

"StockTicker.ashx",

{method:'get',parameters:'price='+currentPrice, onComplete:showResponse}

);

}

function showResponse(request)

{

var data = request.responseText.split('|');

var newPrice = data[0];

var oldPrice = $('priceCell').innerText;

var change = data[1];

$('priceCell').innerText = newPrice + '(' + change + '%)';

if(newPrice>oldPrice)

$('priceCell').bgColor = 'green';

else if(newPrice<oldPrice)

$('priceCell').bgColor = 'red';

}

And in the http handler:

public void ProcessRequest(HttpContext context)

{

context.Response.ContentType = "text/plain";

context.Response.Expires = -1;

int oldPrice = Convert.ToInt32(context.Request.Params["price"]);

int newPrice = StockDataProvider.GetStockValue("CSCO");

double change = ((double)newPrice / oldPrice - 1) * 100;

context.Response.Write(newPrice + "|" + change);

}

Now that we have a working and functional control, we can take a look at some problems with my implementation.

What's Wrong

I think the current implementation is fairly representative of how many modern working web controls are implemented. A major issue with this kind of implementation is the presence of logic on the client side and the mixing-and-matching of logic between server code and client code.

Let me expand on this issue. Here are some specific problems that we are lead to by this approach:

1. Logic in javascript is bad on it's own right:

a) javascript is harder to develop and to debug - it is a more error-prone language than, for example, c#. It has weaker development tool support.

b) A lot of javascript logic code can lead to performance issues because it's executed on a potentially weaker, client-side, machine.

c) All javascript code is visible to the user, what is in many cases problematic because of security and intellectual property issues.

2. Usually, the logic in your code will be scattered (just like in our example control) across server and client. This leads to:

a) Code that is very hard to understand and debug - there is no single place to look.

b) It's a horror to modify - notice how we had to modify many places when we wanted to show the change in percentage of the stock price.

At this point it's important to understand that I'm not bashing javascript code or the language as a whole. The language is extremely powerful and I like it personally. The browser support for javascript is actually what allows us to write truly powerful, usable and feature-rich applications on the web. So I do not, for a second, call to abandon it's use.

What is bad, is how logic gets tangled up inside javascript.

Les Arcs Chairlift

A Better Approach

I have a suggestion for a better approach, that will keep the benefits of having controls that are rich on the client side but still have all the logic in one place, on the server.

The solution outline is this: we extract all the decision making from javascript and move it to the server while keeping the performing of actions on the client side. The server will decide what to do, and call (we'll see how in a second) the specific javascript actions that are needed.

First, let's map out all the things that are "logic" inside javascript in our current implementation: (logical decisions in bold)

1. Immediately at the beginning of the page's "life on the client", javascript starts a periodic request to the server for price updates. This fact is a logic decision.

2. It sets the interval of updates to 3 seconds.

3. When requesting update from server, it sends to the server the current price.

4. It knows the structure of the response from the server, parsing it into (a)price and (b)change in percent, then injects these values in specific locations in the display.

5. It checks the kind of change (up or down) and colors the display accordingly.

Note how I am religious about this. We have to seperate every tiny bit of logic from the rest of the code.

Now, let's take a look at a better implementation where all the above logic parts are performed by the server.

Here's an implementation that removes the first three issues. The javascript:

function requestPriceUpdateFromServer()

{

var request = new Ajax.Request(

"StockTicker.ashx",

{method:'get',parameters:postBackParams, onComplete:showResponse}

);

}

function showResponse(request)

{

var data = request.responseText.split('|');

var newPrice = data[0];

var oldPrice = $('priceCell').innerText;

var change = data[1];

$('priceCell').innerText = newPrice + '(' + change + '%)';

if(newPrice>oldPrice)

$('priceCell').bgColor = 'green';

else if(newPrice<oldPrice)

$('priceCell').bgColor = 'red';

postBackParams = 'price=' + newPrice;

}

function periodicallyUpdatePrice()

{

var periodicExecutor = new PeriodicalExecuter(requestPriceUpdateFromServer,interval);

}

You see that now, periodicallyUpdatePrice is not called right away from inside the javascript file itself. It also uses a variable for the interval of the periodic update requests. The call and the variable will be created by server-side code.

Also, requestPriceUpdateFromServer now uses a variable to hold the parameters to be sent to the server. It is also created by the server.

(showResponse still has knowledge of how this parameter is built, we'll remedy that in a sec.)

Now, let's take a look at the server:

private int value = -1;

private int GetStockValue()

{

if(value==-1)

value = StockDataProvider.GetStockValue(Ticker);

return value;

}

protected override void OnInit(EventArgs e)

{

base.OnInit(e);

Page.ClientScript.RegisterClientScriptInclude("prototype", "prototype.js");

Page.ClientScript.RegisterClientScriptInclude("tickerScript", "StockTicker.js");

string periodicUpdateScript = @"var interval = "+ periodicUpdateInterval + @"

Event.observe(window, 'load', periodicallyUpdatePrice, false);";

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "periodic update", periodicUpdateScript, true);

Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "postback params", "var postBackParams='price='+" + GetStockValue().ToString() + ";", true);

}

So far I only modified the web control code, not the HTTP handler.

GetStockValue is now used twice, so it caches it's value.

OnInit is where the interesting changes are made. It emits code that defines a javascript variable for the periodic request interval and also the initial call to periodicallyUpdatePrice (which will be done in the onload event handler in javascript).

It also creates the variable that holds the update request parameters, assigning to it it's initial value.

Now let's move to fixing the remaining issues. As a first step, I will refactor the javascript code into seperate actions, without shifting responsibilities to the server: (showing changed functions only)

function showResponse(request)

{

var data = request.responseText.split('|');

var newPrice = data[0];

var oldPrice = $('priceCell').innerText;

var change = data[1];

displayNewValues(newPrice, change);

colorCellBasedOnChange(oldPrice, newPrice);

updatePostBackParams('price='+newPrice);

}

function displayNewValues(newPrice, change)

{

$('priceCell').innerText = newPrice + '(' + change + '%)';

}

function updatePostBackParams(newValue)

{

postBackParams = newValue;

}

function colorCellBasedOnChange(oldPrice, newPrice)

{

if(newPrice>oldPrice)

colorCell('green');

else if(newPrice<oldPrice)

colorCell('red');

}

function colorCell(color)

{

$('priceCell').bgColor = color;

}

Now it's all set for a one-move, guilliotine-like shift of logic to the server.

Here are the changes to the HTTP handler:

public void ProcessRequest(HttpContext context)

{

context.Response.ContentType = "text/plain";

context.Response.Expires = -1;

int oldPrice = Convert.ToInt32(context.Request.Params["price"]);

int newPrice = StockDataProvider.GetStockValue("CSCO");

double change = ((double)newPrice / oldPrice - 1) * 100;

string color = (change>0)?"'green'":"'red'";

string response = "displayNewValues("+newPrice.ToString()+","+change.ToString()+");"+@"

colorCell(" + color + ");" + @"

updatePostBackParams('price='+" + newPrice + ");";

context.Response.Write(response);

}

The server decides on the logic that will be performed on client-side, and sends it to the client as a snippet of javascript to be injected.

All the client has to do is run the returned code:

function showResponse(request)

{

eval(request.responseText);

}

Notice that because it's extremely uncomfortable to "embed" javascript inside a server language like c#, I made a point out of making the actions on the javascript all seperate and easy to call.

Also, you can see, that the details of performing client-side work are still all on client side. The only thing that moved to the server is the decision what and how should be done (specifically function calls and parameters).

Conclusion

Even though the presented implementation is still not polished, it shows how you can develop a client-heavy control or page, while keeping all logic in one place, where it's easy to develop and maintain.

Here's another analogy: the javascript part of your controls should be treated much like SQL embedded in the code. You can have logic in your SQL statements, but it's considered a well-known bad practice, for the same reasons I described here for javascript. The better approach is to have your SQL perform just the data access actions while the application code (which is in your chosen language) ties it all together and makes the logic decisions.

Sunday, April 15, 2007 2:34:18 AM (Jerusalem Daylight Time, UTC+03:00)  #    Disclaimer  |  Comments [2]  | 
 Sunday, March 18, 2007

If you use dasBlog, the endpoint for Blogger API is:

http://<your address>/Blogger.aspx

Sunday, March 18, 2007 11:02:05 PM (Jerusalem Standard Time, UTC+02:00)  #    Disclaimer  |  Comments [1]  | 
 Thursday, March 15, 2007

Here's another short trick for the NMock mock objects framework:

To mock an indexer use the syntax (for the getter):

Stub.On(...).Method("get_Item").Will(Return.Value(..));

And for the setter:

Stub.On(...).Method("get_Item").Will(Return.Value(..));

*Update*

Via Paul Pierce's post I found a better way:

Stub.On(...).Get[...].Will(Return.Value(..));

Friday, March 16, 2007 12:20:14 AM (Jerusalem Standard Time, UTC+02:00)  #    Disclaimer  |  Comments [0]  | 

If you are using the NMock mock objects framework, you are probably familiar with the following syntax:

Stub.On(...).Method(...).Will(Return.Value(...));

This will cause your mock object to return a specific value from some invoked method.

Now, for something less not documented:

To mock a method that sets value of an out parameter, use:

Stub.On(...).Method(...).Will(new SetNamedParameterAction([parameter name], [value]));

You can also use the SetIndexedParameterAction class.

This is not in the documentation, so using Reflector on the NMock2.dll helped find this.

Thursday, March 15, 2007 8:09:03 PM (Jerusalem Standard Time, UTC+02:00)  #    Disclaimer  |  Comments [3]  | 
 Tuesday, March 13, 2007

This is the second part in an article series about setting up SSL in an ASP.NET application.

You can read the first part here. Go ahead, read it now.

Okay.

Now, that we've created an SSL certificate for testing and development purposes, we are ready to make the required configuration in IIS.

Setting Up IIS to Work with SSL

First thing we have to do is configure the web site to use the certificate we created:

  1. From the IIS MMC snap-in, select your web site, right-click "properties" and under "directory security" click "Server Certificate...".
  2. Click "Assign an existing certificate". You should be able to see the self-signed certificate you created. Select it and finish the wizard.

At this state IIS is able to respond to SSL HTTP requests with this certificate.

To test that everything is okay, try to navigate to an existing URL in your application, with https in the beginning of the URL.

Forcing SSL for an application

If your application requires SSL encryption for all traffic you want to force the application to only handle SSL requests.

You can do this on the application level (so that other applications on the same web site in IIS will not require SSL) or on the web site level.

Here's how:

  1. In IIS MMC, right click the application virtual directory or the web site.
  2. Select "Directory Security" tab and click "Edit...".
  3. Check "Require secure channel" and "Require 128-bit encryption".

Now, any request to a URL that starts with http and not https - will receive a 403.4 error from the web server.

Supporting Debugging in Visual Studio

Now that you've setup the web server on your machine to require SSL traffic, you need to update the application URL in Visual Studio in order to be able to run the application from Visual Studio:

  1. Right click the project in Solution Explorer and select "Properties".
  2. Under the "Web" tab change the value of "Project Url" to start with https.

Auto-Redirecting non-SSL Traffic

Perhaps some of your users will try to navigate to your application via a non SSL URL (most users assume a web page URL starts with http).

You can silently redirect your users to the correct SSL address using the following technique:

Users trying to reach a non-SSL URL will be automatically redirected by IIS to the standard 403.4 error page. First step is to change that page to your own page:

  1. In your project, create a new web form called "NonSslRedirect.aspx".
  2. In IIS MMC, right click your application virtual directory, click the "Custom Errors" tab and select the 403;4 error.
  3. Click "Edit Properties...", select "URL" in "Message Type" and type the address of the page you added in step 1 (for example: /MyApp/NonSslRedirect.aspx).

Try again to navigate to a URL starting with http. You should be redirected by IIS to NonSslRedirect.aspx.

Now, in the code-behind file of NonSslRedirect.aspx, add code similar to the following to automatically redirect the users to the matching SSL URL:

protected void Page_Load(object sender, EventArgs e)

{

string originalUrl = Request.Url.ToString().Split(new char[1] { ';' })[1];

string urlWithHttps = "https" + originalUrl.Substring(4);

Response.Redirect(urlWithHttps);

}

This code will replace the http prefix in the requested URL with an https prefix and redirect the user to new URL.

Tuesday, March 13, 2007 8:21:00 PM (Jerusalem Standard Time, UTC+02:00)  #    Disclaimer  |  Comments [2]  |