Node.js's null terminator of death

By creator1988 on Monday 19 November 2012 18:29 - Comments (3)
Category: Backend, Views: 7.641

Recently we embraced our new 'review for security' strategy, that included a security 101 given by yours truly and a very big messages like 'Don't reinvent the fucking wheel'. Just saying.

http://100procentjan.nl/tweakers/dontwheel.png

Working on this subject intensively also learned me to really really test for security. Developers, and I'm not an exception here, are focussed on code quality, feature stability and security is not always on their radar. And that's a shame because reviewing for security really gives you this 'Dade Murphy' hackers feeling. Meet me at the 'null terminator of death'.

Read more »

Schizofrene code met node.js nl

Door creator1988 op donderdag 20 oktober 2011 11:59 - Reacties (16)
Categorieën: Backend, Frontend, Views: 6.809

Allereerst een kleine update, op 1 oktober ben ik overgestapt van de de gevestigde orde naar de wondere wereld van een startup. Niet alleen cultureel een verschil, maar ook een shift van .NET naar javascript, van Solr naar Redis, van SVN naar Git en van een Xeon workstation naar een Macbook Air. En nog belangrijker, van tafeltennis naar tafelvoetbal. Voor de mensen die niet 74 feeds in Google Reader hebben zitten: Cloud9 is een IDE, vergelijkbaar met Eclipse of Visual Studio, maar volledig draaiend in de browser; het is 'c9.io' intikken en gaan. Debugging, stack exploration, versiebeheer, you name it.

Cloud9 is helemaal gebouwd in javascript, de client is gebouwd op APF, een open source framework voor web applicaties dat intern is ontwikkeld (heeft wel wat weg van Webforms). De backend draait op node.js, een event-based framework voor het schrijven van server side applicaties in javascript. Doordat node vanaf design geschreven is met het idee dat alle code event-driven moet werken heb je bijna geen blocking calls, en kunnen je threads sneller vrijgegeven worden: ergo: je kan meer requests handlen in je web server (gesimplificeerde weergave :)).

Direct spelen met alle code
Het leuke van werken aan een IDE is dat je features die je zelf handig vind gewoon kan inbouwen, zoals het met een klik laten klonen van de GitHub repository waar alle code samples uit de blogpost zitten. Ergo, om alle code uit deze post in hun echte context te zien en meteen te runnen klik hier en druk hierna op 'Run'.

Lees verder »

Google Analytics in MVC nl

Door creator1988 op donderdag 05 mei 2011 15:14 - Reacties (7)
Categorie: Backend, Views: 3.342

Wanneer je iets in je MVC applicatie wil implementeren dat op (bijna) elke pagina terug moet komen, zoals Google Analytics, is dat een probleem dat lastig te tackelen is. Tactieken die ik in de praktijk heb gezien:
  • 1. Een baseclass maken met daarop de property 'GoogleAnalyticsTag', en alle Masterpages van dit model laten overerven. In de masterpage vervolgens <%= Model.GoogleAnalyticsTag %> doen.
  • 2. In je action 'ViewData["GoogleAnalyticsTag"]' zetten, om geen afhankelijkheid op alle modellen te hebben.
  • 3. Een losse action maken, en in je masterpage '<%=Html.RenderAction("GoogleAnalytics", "SomeController")%>'.
3 is op zich de 'way-to-go' wat mij betreft, maar in tegenstelling tot 1. en 2. waar je in je action (of model) de GA tag zet heb je hier geen action context meer. En dus zag de code er in een van onze applicaties uit als:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
var url = HttpContext.Current.Request.Url.PathAndQuery;
var tag = "";

if (url.StartsWith("/koop/")) tag += "koop/";
if (url.StartsWith("/huur/")) tag += "huur/";

if (new Regex(@"/(koop|huur)/[\w-]+/\w+-\d+-[\w-]+/").Match(url).Success) {
    if (url.Contains("omschrijving")) tag += "object-omschrijving";
    if (url.Contains("fotos")) tag += "object-fotos";
}

// etc. etc. etc.

Ononderhoudbaar, buggevoelig, en super hacky. Dat kan mooier!

Lees verder »

API documentatie genereren uit code? nl

Door creator1988 op maandag 21 maart 2011 14:20 - Reacties (12)
Categorie: Backend, Views: 3.529

Om het proces van API updates wat te verzachten willen we switchen van een op basis van een Word doc gegenereerd document, naar documentatie op basis van onze code (C#, met XML documentatie). Nu zou dat prima moeten kunnen met SandCastle, maar die genereert de documentatie op basis van onze code, en niet op basis van onze DataContracts. Probleem, want in de uiteindelijke API zijn alleen de data contracts beschikbaar, en zijn de namen die we zelf intern gebruiken niet beschikbaar. Wie weet een tool die wél nette documentatie voor WCF services kan genereren (REST en SOAP) op basis van XML Docs?

MSIL injection met PostSharp nl

Door creator1988 op dinsdag 08 februari 2011 14:41 - Reacties (4)
Categorie: Backend, Views: 2.647

Wanneer je manager een nieuwe techniek ten strengste verbied met als argument 'we snappen je code normaal al niet, dit maakt het alleen maar erger' weet je dat je goud in handen hebt. Voor een eigen projectje om vals te spelen met Football Manager (waar ik later absoluut nog eens terug kom) had ik globaal de volgende situatie:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public byte CurrentAbility
{
    get {
        if (_mode == DbMode.Cached) {
            // in cached mode, hebben we een byte-array met alle waardes
            return _bytes[Offsets.CurrentAbility];
        } else {
            // anders lezen we via een helper-method
            return ProcessManager.ReadByte(_address + Offsets.CurrentAbility);
        }
    }
    set {
        // zelfde soort code voor de setter
    }
}

Leuk, neat, en vrij goed te lezen; probleem alleen dat ik een paar honderd properties heb, met een stuk of zeven verschillende types. Te veel werk. En aangezien je in eigen projecten toch helemaal los mocht gaan, leek een oplossing op basis van AOP me veel leuker. Nieuwe situatie:

C#:
1
2
[FMEntity(Offsets.CurrentAbility)]
public byte CurrentAbility { getset; }

Bovenstaande is best eenvoudig werkend te krijgen met PostSharp, een framework voor Aspect Oriented Programming in .NET. Een eenvoudige implementatie van bovenstaande is iets als:

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FMEntityAttribute : LocationInterceptionAspect
{
    public FMEntityAttribute (int offset) {
        // doe wat
    }
    
    public override void OnGetValueLocationInterceptionArgs args ) {
        if (args.Instance is byte) {
            // doe byte lezen enzo
        }
    }
    
    public override void OnSetValueLocationInterceptionArgs args ) {
        // ongeveer hetzelfde
    }
}

Je kunt nu alle logica die toch steeds hetzelfde is, eenvoudig webabstraheren in een aparte file. Maar... té traag. In mijn geval werd het bepalen van de rating voor spelers ruim tien keer zo traag; door alle overhead. Oplossing? Zelf MSIL injecten!

Lees verder »