Posted by: dotnetter | February 17, 2012

Ajax, the webfarm and GAC assemblies

I don’t write a lot here because I just don’t have the inspiration to fill up a blog, but sometimes I spend a lot of time trying to get my head around an issue. When I find a solution, I try to post it here so the world can benefit.

So, the last couple of weeks I spent some time trying to solve an issue in a load balanced web farm. The balancing works with – well – load on the servers. No sticky sessions, no round-robin. When performing a callback, the users received javascript errors. Sometimes.

I started by looking at the javascript we emit in the response. The javascript was valid. Even more: the error occured even before our startup script was hit. Strange. Some googling indicated the – stupid – way the .net framework generates web resource urls for GAC assemblies: it uses a hash over the resource name and assembly (including version). This becomes the ‘d’ querystring parameter of the emitted webresource.axd url. Then (God knows why!) the lastmodified date of the assembly, expressed in ticks, is added as the ‘t’ parameter.

We deploy our assembly with homebrewn extenders in the GAC; that’s where all of our assemblies are. Turns out there was a difference of 2 (two!) seconds in the lastmodified date of the assemblies between the webservers. This resulted in – tadaaa – a different ‘t’ parameter for the webresource url.

The most cited solution in google results: force the dates to be the same accross all servers in the webfarm. Well… do we really want to do that? Is it really that necessary?

Opens reflector looking for the AssemblyResourceLoader. Turns out it doesn’t use the ‘t’ parameter to resolve the request. So: no need to provide the ‘t’ parameter in a request. Next step: try to override the generation of the webresource url. Well, unless I’d copy all the code in the AssemblyResourceLoader class to modify one or two lines there’s no way: everything is internal or private and static.

And now, for you reader who made it all the way here: the solution I came up with.

The asp.net ajax client framework uses a clever trick to see if a script resource in the partial update response is already loaded: it takes all the script tags in the document and sees if the same src attribute is present. Since our ‘t’ parameter is different, but the rest isn’t: omit inspecting the ‘t’. Simple and because in javascript we can overwrite everything my best bet.

Here’s the code (only two javascript functions need tweaking) we now add to the page automatically as a startupscript during the initial page load. As you can see, the comparison now happens without the dreaded ‘t’. Problem solved. No powershell script intervention needed and, more importantly: we don’t have to remember setting all dates in the GAC the same.

Sys.Application.add_load(applicationLoadHandlerForScriptLoading);
function applicationLoadHandlerForScriptLoading() {
    Sys.Application.remove_load(applicationLoadHandlerForScriptLoading);
    Sys._ScriptLoader.readLoadedScripts = function Sys$_ScriptLoader$readLoadedScripts() {
        if(!Sys._ScriptLoader._referencedScripts) {
            var referencedScripts = Sys._ScriptLoader._referencedScripts = [];
            var existingScripts = document.getElementsByTagName('script');
            for (var i = existingScripts.length - 1; i >= 0; i--) {
                var scriptNode = existingScripts[i];
                var scriptSrc = CleanScriptReference(scriptNode.src);
                if (!Array.contains(referencedScripts, scriptSrc)) {
                    Array.add(referencedScripts, scriptSrc);
                }
            }
        }
    }

    Sys._ScriptLoader.isScriptLoaded = function Sys$_ScriptLoader$isScriptLoaded(scriptSrc) {
        var dummyScript = document.createElement('script');
        dummyScript.src = CleanScriptReference(scriptSrc);
        var scriptArray = Sys._ScriptLoader._getLoadedScripts();
        for(var i=0; i<scriptArray.length; i++) {
            scriptArray[i] = CleanScriptReference(scriptArray[i]);
        }
        return Array.contains(scriptArray, CleanScriptReference(dummyScript.src));
    }

    function CleanScriptReference(scriptSrc) {
        var output = scriptSrc;
        if (scriptSrc.length) {
            if(scriptSrc.indexOf('Resource.axd') > -1 && (scriptSrc.indexOf('&t=') > -1 || scriptSrc.indexOf('&amp;t=') > -1)) {
                var idx = scriptSrc.indexOf('&t=');
                if(idx < 0) {
                    idx = scriptSrc.indexOf('&amp;t=');
                }
                if(idx > 0) {
                    output = scriptSrc.substring(0, idx);
                }
            }
        }
        return output;
    }
}
Posted by: dotnetter | April 10, 2009

Script injection mitigation

Every now and then an architect comes up with a requirement which needs careful analysis and looking at benefits and risks. Today was one of such days.

The architect wanted the user to be able to enter ‘<‘ and ‘>’ or any combination with these signs in a comment textbox. Problem: you have to disable page validation to allow these signs to pass and we don’t want to do this because it opens the application up to script injection.

Instead of bouncing the request with the argument that we can’t do it because of security, we thought out of the box. All our input screens are AJAX enabled so if only we could intercept the postback, modify the contents of the text box (encode them) and then proceed with the postback.

No luck: the post body is compiled even before any eventhandlers on the PageRequestManager are invoked.

Back to nothing until… A stroke of genious: the asp.net ajax framework does not post any form elements whose name property is empty. Hmm looks like we have found our way in!

In short (I won’t give you the code as the general idea should do): we created a control which inherits from System.Web.UI.WebControls.TextBox. This control injects a hiddenfield in the overridden render method. Because we also implement the IScriptControl interface, we can attach client side behaviour. On load clientside we replace ‘&gt;’ and ‘&lt;’ in the value of the hiddenfield and put the result in the textbox.

The textbox onblur event is used to replace the < and > sign with their entities and the resultant text is put in the hiddenfiled’s value.

Since we override the Text property of the textbox server side and return the hiddenfield’s value here, using the control is transparent to the developer: no messing around with encoding, decoding and so on.

Script injection will not work as the script is just displayed, not executed (entities, remember?) and we didn’t even have to turn off page validation.

The bottom line: from now on these requirements will take us about 1 minute to fulfill and we don’t have to worry about opening up the application to people with less good intentions.

Nowhere on the web did I find a solution to this problem which did not involve turning off page validation. From now on if you encounter this: use the workaround above instead of disabling page validation. It might save you some trouble in the long run.

Posted by: dotnetter | January 9, 2009

Reflection and Generic Methods

Sometimes we want to do things which are not possible in the normal world. For example: we want to unit test private methods. Try to create an instance of the component and… well, it’s a private method: you can’t invoke it.

No big deal: we have reflection, .net’s trickbox. Use BindingFlags.NonPublic while getting the MethodInfo object and you’ve got your method to invoke.

You might say reflection gives a performance penalty, and that’s correct but in this particular case (unit testing) we’re not interested in performance: we want to test our methods and discover interference of new development.

A newer type of method: methods with generic parameters (public or private doesn’t matter). The solution: just one (1) additional line: methodInfo.MakeGenericMethod(Type[] genericTypes);

Codesample for your reference (yes, they’re generic so usable in all cases):

public static void RunMethodGeneric<TSource>(string methodName, List<Type> argumentTypes, List<Type>genericTypes, TSource instance, object[] objParams, BindingFlags bindingFlags)
{
    MethodInfo m = GetMethod<TSource>(methodName, argumentTypes, bindingFlags, instance);
    MethodInfo generic = m.MakeGenericMethod(genericTypes.ToArray()); 

    generic.Invoke(instance, objParams);
}

Need returntypes?

public static TResult RunMethodGeneric<TSource, TResult>(string methodName, List<Type> argumentTypes, List<Type>genericTypes, TSource instance, object[] objParams, BindingFlags bindingFlags)
{
    try
    {
        MethodInfo m = GetMethod<TSource>(methodName, argumentTypes, bindingFlags, instance);
        MethodInfo generic = m.MakeGenericMethod(genericTypes.ToArray());

        return (TResult)generic.Invoke(instance, objParams);
    }
    catch (TargetInvocationException ex)
    {
        if (ex.InnerException != null)
            throw ex.InnerException;
    }

    return default(TResult);
}
Posted by: dotnetter | December 25, 2008

Dynamic rules

Every now and then I receive a very interesting task. This time it’s a questionnaire which will be used to profile a user.

The (preliminary) requirements say it should be possible to have two types of questions: multiple choice and ‘free’ input ones. Multiple choice is easy: you define the possibilities and render a radiobutton list. The free text input is somewhat different: you have to take a datatype into account. It could be a date, a decimal, … No problem there: just render a validator doing the datatype check for you.

The interesting bit in this proof of concept is the scoring. As I said, the user has to be profiled. For multiple choice questions this does not pose any problems as well as you can just say the answer scores x in y’s field. Add up all selections and you’re done. The free text ones are trickier: here you have to define text rules in which you compare the value input by the user to a value (or range) to deduct a score x in y’s field.

Interestingly, this text rule is a bit trickier to use. What did I come up with? Create a Rule class with one method: bool DoesRuleApply().

The idea: you pass the rule text in the constructor, as well as the value the user supplied: public Rule(string ruleText, object value)
The rule text looks like this: “DateTime.Parse\”{0}\”) > DateTime.Parse(\”1970/01/01\”)” resulting in true if the date supplied by the user is before Jan 1st 1970. Obviously it could also be “DateTime.Parse\”{0}\”) > DateTime.Parse(\”1980/01/01\”) && DateTime.Parse(\”{0}\”) < DateTime.Parse(\”1990/12/31\”)” being true if the date falls between Jan 1st 1980 and Dec 31st 1990.
Simple enough eh. Well, not really: how do you check if this is true or false? In come dynamic classes. Remember: this is only my first thought and a rough proof of concept implementation.
    public class Rule
    {
        private string _ruleStatement = "1=1";
        public Rule(string ruleText, object value)
        {
            if(!string.IsNullOrEmpty(ruleText))
                _ruleStatement = string.Format(ruleText, value);
        }

        public bool DoesRuleApply()
        {
            //instantiate the compiler
            CSharpCodeProvider compiler = new CSharpCodeProvider();

            //set the parameters and reference the needed assemblies
            CompilerParameters parameters = new CompilerParameters();
            parameters.ReferencedAssemblies.Add("mscorlib.dll");
            parameters.ReferencedAssemblies.Add("System.dll");

            parameters.GenerateInMemory = true;
            parameters.CompilerOptions = "/target:library /optimize";
            parameters.GenerateExecutable = false;
            parameters.IncludeDebugInformation = false;

            //generate the assembly
            CompilerResults results = compiler.CompileAssemblyFromSource(parameters, getClassCode(_ruleStatement));

            //if any errors, the rule text might be faulty
            if (results.Errors.HasErrors)
            {
                return false;
            }

            //load the assmebly
            Assembly compiled = results.CompiledAssembly;

            //create a ruleexecutor object
            object classObject = compiled.CreateInstance("BM.DynamicRule.RuleExecutor");

            //if we can't instantiate one it is not valid
            if (classObject == null)
                return false;

            try
            {
                //run the Validate() method
                object result = classObject.GetType().InvokeMember("Validate", BindingFlags.InvokeMethod, null, classObject, null);

                //return result
                return (bool)result;
            }
            catch
            {
                //if we can't invoke the member: throw the exception
                throw;
            }
        }

        private string getClassCode(string statementToInclude)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("using System;");
            sb.Append("namespace BM.DynamicRule{");
            sb.Append("public class RuleExecutor{");
            sb.Append("public bool Validate(){");
            sb.Append("bool result = false;");
            sb.Append(string.Format("if({0}){{", statementToInclude));
            sb.Append("result = true;");
            sb.Append("}");
            sb.Append("return result;");
            sb.Append("}");
            sb.Append("}");
            sb.Append("}");

            return sb.ToString();
        }
    }

So what does it do? It wraps the rule text in an if statement in a dynamic class. Since we compile the assembly to memory, we don’t need any write access on the drive: great for a web application. All we then do is use reflection to create an instance and invoke the Validate() method. The result is passed back to the method where we invoked DoesRuleApply().

As this is only a first attempt, the exception handling is not up to par and the entire thing will get more complex over the next few days and weeks (probably the rule definition getting more ‘user friendly’). I think this is a good start though to get the proof of concept going.

Update: in the meantime the idea of a dynamically compiled class has been abandoned. The engine has become entirely generic and parses the rule text into ‘tokens’ which are interpreted afterwards. The entire engine (though basic as it is) is implemented in about 150 lines of code, is better than the idea above and last but not least: is easier maintainable.

Posted by: dotnetter | November 27, 2008

Crisis?

Everyone is talking about the crisis, the worst economic situation since the 1930’s, people fear loosing their jobs and so on. I don’t intend to repeat the contents of last week’s, yesterday’s and today’s papers.

I got strange news today. My client intends to renew my contract. Fair enough: they need people and hiring doesn’t go very fast. The period: an entire year. A year! Who says it’s the worst economic time since the 1930’s?!

Posted by: dotnetter | November 27, 2008

IE memory leak

A colleague of mine pointed out on Monday that certain pages in our webapplication have memory leaks. Courageous as we are, we started looking for the reason. Seemed every partial postback of a page made the allocated memory rise by almost half a megabyte. Okay, there is a lot of data getting refreshed on that page, but even then.

The problem is, there are some custom extended controls on that page. First step: comment everything except the initialise and dispose functions, leave the getters and setters as they are and don’t create any handlers etc. Leak contained? No way Jose!

Well, that’s odd. Just a basic page with two textboxes and a button. One textbox in an update panel and the other one out of it. The button is the asyncpostback trigger. Look at drip: for every postback there are five (5!) references to each of the objects which are in the AJAX response. This means: three postbacks give three times five references to each object. This is outrageous. Look at the Process Explorer: no rise in memory allocation. What’s wrong here? The references remain, the allocated memory does not increase (or ever so slightly, but gets garbage collected).

We’re beginning to get desperate here. Needless to say we’ve got to get this fixed. Users have the application open all day long and refresh data a lot. Even when navigating to another page, only roughly half the extra-allocated memory gets de-allocated while all dispose functions are called (we checked).

Over the next couple of days we’ll have a lot of tests to do in order to contain this situation. I’ll post any solutions (if we find them!) here over the next couple of days (or weeks).

Update: in some scenarios we got as much as 746 leaks while navigating the application. We have started to mitigate the issue by always calling $clearHandlers on all ajax pages and controls; and by detaching any events on the pre-ajax controls. This way we have eliminated about 95% of the leaks. For the remaining ones we keep scanning the controls whenever we have to update them. The 100% mark might not be met for another six months or so, but for now we’re a bit safer.

Posted by: dotnetter | November 13, 2008

Method chosen

As a followup to my previous post about choosing a project management methodology, I’d like to let you know that I’ve chosen to walk the PMBOK path.

What’s the reason behind this?

  • PMBOK is backed by an institute, as opposed to the user groups in Prince2 which seem a little unstructured and less efficient at spreading trends, best pratices, new insights etc.,
  • people are stimulated to stay up to date (PDUs) and renew their certification vs the life-long certification of Prince2,
  • many publications by PMI (magazines, but also their e-library) vs well, nothing in Prince2-world (or I was very unsuccessful at discovering them),
  • my gut(t)-feeling (buikgevoel in Dutch); don’t know whether this word is correct

So, since last Sunday, I’m a PMI member and eagerly waiting to receive their information packet as well as the magazines. Over the next few months, I will receive formal training and get the chance to work in a project management team under a senior project manager.

This new phase in my carreer is not only welcome, it is much needed! Today I am just surviving the days and weeks, only looking forward to the weekends; not the achievements, solutions and creative input. Whenever a job does that to me (autopilot-like behaviour), I know it’s time to pick up my things and go do something else. I need a drive; I need challenges.

Hopefully, the coming months will provide me with the needed skills and empower me to get back in the driver’s seat. If I would finally decide to leave the world of IT, the same skills can be applied in any other industry.

Posted by: dotnetter | October 28, 2008

Choosing a method

Well, it’s not easy to choose a methodology.

Although I’m not that old, I want to advance my carreer and I don’t see myself developing webapps for the coming 20 years.

Some time ago, I was involved in a project management team as a technical advisor. I liked this role a lot. Because of circumstances, I had to turn to development to remain an IT consultant. Now’s the time to cash in  on this effort (figuratively).

My employer has always known I seek a carreer in project management. Not because of the pay, but because I find it more interesting than learning the latest new features of a programming language and because it changes much slower (stability eh).

That being said, I have to choose. My take on this: there are two major methodologies. There’s Prince2 with it’s market acknowledgement (meaning higher day-rates; not unimportant for a consultant and his employer) but a lot (really a lot!) more paper-work which is an overhead in project management and not a guarantee to successful projects. On the other hand we have PMI’s method. Pro here is the need to renew (re-examine) the certification (stay up to date and sharp) and (seemingly) more successful projects. Con: less market support.

My employer and colleagues are saying it’s better to walk the PMI path in the long run. I have not decided yet, but I think they’re right. Prince2 seems to me like a method developed to justify the presence of a project (and program) management team whose only role, besides leading the project(s), is to generate documents. Here in Belgium we have a saying about statistics and it’s not very positive.

I’m aware that there are people who prefer one or the other methodology, but what are to you the real benefits (or cons) of either method?

Posted by: dotnetter | October 28, 2008

New .net logo

Well, seems there’s a new .net logo. I for one like it.

From what I can tell, there are two versions: one on a white background and another one on blue. I like the whote version (see below) more as it is ‘cleaner’.

What do y’all think?

Posted by: dotnetter | September 11, 2008

When in love…

Het is alsof mijn hele denken beheerst wordt door de gedachte aan jou. Minstens honderd maal per dag denk ik plots, zonder aanwijsbare reden aan jou. Een glimlach verschijnt steevast op mijn lippen, wat vooral lastig uit te leggen is als je net op dat moment een gesprek hebt met een potentiële klant. Je moet dan snel een uitleg zoeken die aanvaardbaar is voor iemand die je enkel professioneel moet kennen. Langs mijn neus weg zeg ik dan dat ik de samenwerking keihard zie zitten. Dat is ook wel zo, maar de waarheid, de reden voor die glimlach ligt nét iets anders.

Ik blijf maar denken of ik jou probeer te verleiden, of dat het net andersom is. Overal zie ik symbolen in details, ik denk de hele week na over alles wat op zaterdag gebeurde en probeer dat allemaal in een context te plaatsen, al begin ik te vrezen dat ik de context net iets rooskleuriger zie dan hij is.

Soms ruik ik plots je parfum, uit het niets. Vooral op zondagen valt dit vaak voor, zelfs tot een tiental keren. Ik vraag mij vandaag nog af of ik op zondagochtend beter bij je was gebleven, of ik mijn kans verkeken heb om jouw minnaar te worden.

Ik hou ervan als je je hoofd op mijn schoot of tegen mijn schouder legt als je plots moe wordt op een avondje stappen. Ik krijg dan een gevoel van volledigheid; ik voel mij dan rustig, relaxed. Ik ben dan net jouw beschermer, degene bij wie je tot rust komt. Het volgende ogenblik schrik je op en kijkt dan indringend recht in mijn ogen. Mijn hart bonst dan steevast. Ik hou van je amandelvormige groene ogen. Ik vind ze mooi.

Veel mensen zeggen mij dat ik gek ben, een beetje obsessief zelfs. Dat ik mij te veel laat doen , een push-over ben. Is het dan zo fout om je een drankje (of twee, drie) te betalen, de taxi te regelen en véél te laat wakker te blijven om toch maar in jouw buurt te zijn? Mijn verstand zegt volmondig ja, maar het avontuur lonkt en mijn hart schreeuwt dat ik je zoveel mogelijk moet zien, details in mij opnemen, mij vergapen aan het wonderbaarlijk wezen dat je bent en steeds verbaasd worden. A man in love really does do crazy things. Het is alsof ik de pedalen volledig kwijt ben.

Ik vind het vreselijk als je mij uitnodigt om te gaan eten of op reis te gaan (avontuur!), ik dat volledig zie zitten en je enkele dagen later beslist dit alles met een (goede) vriendin te doen. Ik leef naar de dag toe en dan… leegte, niets, het komt er niet van, het gaat niet door. Hoe lang zijn we al aan het zeggen dat we eens rustig een koffietje gaan drinken op een weekavond? Het gebeurt gewoonweg niet. Hate it! Ik wil je vaak zien. Verrast worden, verleid worden, me in jou verliezen, elke dag opnieuw; dát is wat ik wil.

“Onmogelijk” denk ik soms. Ik word wat onzeker, denk súper veel na, word zenuwachtig, energiek. “Kalm” zeg ik dan tegen mezelf. Kalmeer en je komt er wel doorheen. Binnenin woedt een hevig vuur. Passie voel ik. Passie die ik met je wil delen. Ik durf het enkel niet te zeggen. Ik durf je niet te dicht te naderen. Ik ben bang om je aan te raken. Ik wil niet te snel gaan, ‘het’ rustig aan laten groeien. Ik ben bang omdat ik niet wil dat enig gebaar van mij jou uit het lood zou slaan. Bang omdat ik niet wil dat je schrikt van het effect dat je op mij hebt en wegrent. Ik wil je niet verliezen en zelfcensuur is tijdelijk dé oplossing.

Onzekerheid is zowat de grootste kwelling. Je voelt dat je een plafond bereikt. Het plafond van wat je aan kan. Ik wil je zoveel zeggen, woorden toefluisteren, je doen blozen, steun geven,… Maar ik durf het (nog) niet.

Aan de andere kant moedig ik mezelf aan. Streel haar hand even, leg je arm om haar schouder, kijk diep en indringend in haar ogen. Glimlach! Toe nou, glimlach, laat zien dat je blij bent. Kleine stapjes neem ik. Klein, maar ze doen mijn vertrouwen groeien. Ooit, op een dag zal ik mijzelf dwingen een grote stap te nemen, mijzelf helemaal bloot te geven. Wanneer is het gepaste moment? Wanneer zal ik de moed vinden om je te kussen, je hand te nemen en je weg te leiden uit de dagelijkse sleur, jouw hart te veroveren? Wanneer?

Older Posts »

Categories