I'm a C# developer located in Copenhagen, Denmark. I love simple solutions solving complex stuff.

Also I'm one of the founders of Servant.io.

jhovgaard on Twitter

Servant.io available in public preview

PUBLISHED 13 November, 2014 ()

What have changed?

Some of you may already know about Servant for IIS - a lightweight web interface for IIS (Which is still available at GitHub of course). Servant.io is the next step in making management of web servers even easier and much more awesome.

What we have done is simply move Servant to a hosted cloud environment like you know it from Boundary, New Relic and services like that. We have developed a small client/agent to be able to communicate with your servers (the source is open and available for everyone).

Servant.io brings new features

We’re working like crazy apes to bring new features. Below I’ll list the features we have pushed live so far.

The future

We have endless numbers of features that we want to introduce, but right now this is what we have in the official pipeline.

Pricing

Servant.io is currently in public preview which is completely free for everyone. When we feel like the product is worth paying for, we will introduce a price model.

I promise prices will be fair and will match the size of your organization. Also we will have a discount for students + completely free for open source organizations!


That’s all for now. I hope you’re as excited as we are. We want to bring the best web server manager ever.

Please leave a comment, I love feedback :-)

Do you still manage your web server through remote desktop or IIS Manager? Try Servant.io today!

How to use PJAX with Nancy

PUBLISHED 23 April, 2014 ()

What is PJAX and why?

Today most web applications use a layout page, because we need to maintain the same HTML code over multiple pages. This HTML could be the header, footer and so on.

When the user clicks around our application they need to download this header and footer again and again and again.

Some developers use AJAX to download data from the server, and then manipulate with the DOM using Javascript to show this new data. Some use big Javascript frameworks and call their application a SPA. This is clever, but isn’t compatible with search engines and non-javascript users. So developers is forced to support two “versions” - a AJAX version and a pure HTML version. Cumbersome and expensive if you care about SEO.

PJAX fixes this issue. When enabled it will tell the server if it should include the layout HTML or not. If Javascript is enabled (not a crawler) there’s no reason to include the layout. If not, the server returns the complete HTML.

Quote from https://github.com/defunkt/jquery-pjax: pjax works by grabbing html from your server via ajax and replacing the content of a container on your page with the ajax’d html. It then updates the browser’s current url using pushState without reloading your page’s layout or any resources (js, css), giving the appearance of a fast, full page load. But really it’s just ajax and pushState.

So to get to the point: PJAX is a plug-and-play plugin that reduces bandwidth usage, increase performance and is fully compatible with non-javascript users.

Also, please notice that PJAX is also part of the YUI library: http://yuilibrary.com/yui/docs/pjax/, however I will use the standalone version in this demo.

Setting up the demo

I’ll go through setting up the demo application real quick, since this article isn’t about Nancy, but PJAX. If you’re new to Nancy I suggest you start by reading my getting started on Nancy blog posts.

Required Nuget packages for the demo is the following:

install-package nancy.hosting.aspnet
install-package nancy.viewengines.razor
install-package jquery
install-package jquery.pjax

After installing Nuget packages I move the script folder into another folder called “Content” only to follow Nancy conventions.

A HomeModule containing a set of actions:

using Nancy;

namespace NancyPjaxDemo
{
    public class HomeModule : NancyModule
    {
        public HomeModule()
        {
            Get["/"] = p =>
            {
                return View["Index"];
            };

            Get["/first/"] = p =>
            {
                return View["First"];
            };

            Get["/second/"] = p =>
            {
                return View["Second"];
            };
        }
    }
}

A _Layout.cstml view:

@using System
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
	Layout loaded: @DateTime.Now
    <div id="container">
        @RenderBody()
    </div>
</body>
</html>

A Index.cshtml view:

@{
    Layout = "_Layout.cshtml";
}

<h1>Index page</h1>

<ul>
    <li><a href="/first/">First link</a></li>
    <li><a href="/second/">Second link</a></li>
</ul>

And at last a First.cshtml and Second.cshtml:

@{
    Layout = "_Layout.cshtml";
}

<h1>Welcome to second page!</h1>

<a href="/">Go back to the index page</a>

My solution explorer now looks like this:

Setting up the Javascript

Perfect, our demo is ready. Time to set up PJAX. First, let’s update the layout page to include jQuery and the PJAX library. I’ll add the following two lines just before my </body> tag:

<script src="~/Content/Scripts/jquery-2.1.0.min.js"></script>
<script src="~/Content/Scripts/jquery.pjax.js"></script>

Next I’ll tell PJAX to use my #container element which you can find in my _Layout.cshtml page:

<script>
    $(document).pjax('a', '#container', { timeout: 1000 });
</script>

This tells PJAX that whenever a user clicks a link, the content should be loaded into #container. The exact same behavior as Razor’s @RenderBody().

To summerize, my _Layout.cshtml page now looks like this:

@using System
<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
    <body>
        Layout loaded: @DateTime.Now
        <div id="container">
            @RenderBody()
        </div>
    
        <script src="~/Content/Scripts/jquery-2.1.0.min.js"></script>
        <script src="~/Content/Scripts/jquery.pjax.js"></script>
        <script>
            $(function() {
                $(document).pjax('a', '#container', { timeout: 1000 });
            });
        </script>
    </body>
</html>

Now when I click through my application I will see that PJAX now sends each request using AJAX instead of regular pageloads.

You’ll also notice the X-PJAX: true header (marked with yellow). This tells our application that this request should not contain the layout HTML, only the new HTML for the requested page.

Because PJAX detects that we are returning the Layout HTML again, it fires a regular pageload. What we need to do is tell Nancy to forget about the Layout page if we see this header.

Setting up Nancy for PJAX

First, we need to provide all views a bool indication whetever the request is coming from PJAX or not. I’ll do this by using the Before hook in Nancy in my HomeModule:

Before += ctx => {
    ViewBag.IsPjax = Request.Headers.Keys.Contains("X-PJAX");
    return null;
};

This will make my HomeModule look like this:

using System.Linq;
using Nancy;
	
namespace NancyPjaxDemo
{
    public class HomeModule : NancyModule
    {
        public HomeModule()
        {
            Before += ctx =>
            {
                ViewBag.IsPjax = Request.Headers.Keys.Contains("X-PJAX");
                return null;
            };

            Get["/"] = p =>
            {
                return View["Index"];
            };

            Get["/first/"] = p =>
            {
                return View["First"];
            };

            Get["/second/"] = p =>
            {
                return View["Second"];
            };
        }
    }
}

Great, now ViewBag.IsPjax can tell is if the request is coming from PJAX. Now we simply need to add an if-sentence to our Views, to make them able to ditch the layout if request is coming from PJAX:

@{
    Layout = ViewBag.IsPjax ? null : "_Layout.cshtml";
}

I’ll do this everywhere I set the Layout in Razor. In my demo it will be Index.cshtml, First.cshtml and Second.cshtml.

Now when I click around my application, I’ll see that the “Layout loaded” timestamp doesn’t change, but the content and URL does! If I disable Javascript, everything still works as any other regular webpage.

We’re done!

That’s it, one complete PJAX application. You should notice that when you write Javascript for PJAX application it is very important that all events is attached to the #container object. For example to handle a click event on some button, you should NOT do this:

Wrong way:

$('#MyButton').click(function() {});

Right way:

$('#container').on('click', '#MyButton', function() {});

The reason is that PJAX will inject the content of your pages into the existing DOM. The “wrong example” only hooks up to instances of my #MyButton on intilization, but PJAX injects #MyButton after initilization.

I hope you see the power of PJAX. I really do think this is the next big thing. I already use it in production and it is a huge timesaver and have really changed the way I do web applications. To be honest I tend to write much more C# than Javascript now, after PJAX. Simplicity at it’s best. PJAX have my vote for the no. 1 web technology of 2014.

The full source of this demo is available at GitHub: https://github.com/jhovgaard/nancy-pjax-demo.

Please leave a comment, I love feedback :-)

Do you still manage your web server through remote desktop or IIS Manager? Try Servant.io today!

Enable CSRF Protection in Nancy

PUBLISHED 23 April, 2014 ()

What is CSRF?

Alright, I’ll make this quick since most of you will know this already.

CSRF stands for Cross-Site Request Forgery. What it bascially means is, that you make one website do a request to another website, without letting the user know.

To ensure that a request is coming from your own website, we have to push a unique string into a hidden input in every form that we post - this is called the AntiForgeryToken.

If you want to know more about CSRF go check out the Wikipedia page, it’s actually very well explained.

CSRF and Nancy

Like any other functionality in Nancy, you will not get a full blown plug-and-play solution. As always Nancy is all about lightweight and total freedom, so we have to make a little effort:

  1. Enable CSRF support in the Bootstrapper.
  2. Insert the AntiForgeryToken in every <form> element of our application.
  3. Validate the posted CSRF token using the built-in Nancy Helper method ValidateCsrfToken().
  4. Handle when Nancy can’t accept a given token (or if none is provided).

Alright let’s go.

1. Enable CSRF support

Create a NancyDefaultBootstrapper class or use your existing. Add the following line to your ApplicationStartup() method:

Nancy.Security.Csrf.Enable(pipelines);

My bootstrapper now looks like this:

using Nancy;
using Nancy.Bootstrapper;
using Nancy.TinyIoc;

namespace NancyCsrfDemo
{
    public class Bootstrapper : DefaultNancyBootstrapper
    {
        protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
        {
            base.ApplicationStartup(container, pipelines);
            Nancy.Security.Csrf.Enable(pipelines);
        }
    }
}

Add the AntiForgeryToken to the form

Alright, you should already have some views in your application, one of them containing some form. In my example I’m using Razor as the viewengine.

To add the AntiForgeryToken to my form I simply add Html.AntiForgeryToken() to anywhere inside my <form> element.

My view looks like this:

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title></title>
</head>
    <body>
        <h1>Welcome to Nancy CSRF Demo, @ViewBag.Name</h1>
        <form action="/" method="POST">
            Name:<br/>
            <input type="text" name="name" value="@ViewBag.Name" />
            <input type="submit" />
            @Html.AntiForgeryToken()
        </form>
    </body>
</html>

The generated value of @Html.AntiForgeryToken() looks something like this (the string will change for each request):

<input type="hidden" name="NCSRF" value="AAEAAAD/////AQAAAAAAAAAMAgAAAD1OYW5jeSwgVmVyc2lvbj0wLjIyLjIuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBQEAAAAYTmFuY3kuU2VjdXJpdHkuQ3NyZlRva2VuAwAAABw8UmFuZG9tQnl0ZXM+a19fQmFja2luZ0ZpZWxkHDxDcmVhdGVkRGF0ZT5rX19CYWNraW5nRmllbGQVPEhtYWM+a19fQmFja2luZ0ZpZWxkBwAHAg0CAgAAAAkDAAAAOrVPNrYs0YgJBAAAAA8DAAAACgAAAAI4qmisW7sYu2FlDwQAAAAgAAAAAsdnVjuuU1fzpb58LEjF1pcK98u9ENMjG0viyxLpvlv/CwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="/>

Validate the posted token

When the user clicks my submit button their browser will send my application the value of the AntiForgeryToken/CSRF token. We need to handle this.

Nancy have a builtin method called ValidateCsrfToken(). The method will automatically lookup Request.Form.Ncsrf and throw a CsrfValidationException if the token is not valid.

The exception will end up showing a Error 500 page to the user, which isn’t fortunately. To overcome this we catch this exact exception and show some other result. Here’s my NancyModule:

using Nancy;
using Nancy.Security;

namespace NancyCsrfDemo
{
    public class HomeModule : NancyModule
    {
        public HomeModule()
        {
            Get["/"] = p =>
            {
                return View["Index"];
            };

            Post["/"] = p =>
            {
                try
                {
                    this.ValidateCsrfToken();
                }
                catch (CsrfValidationException)
                {
                    return Response.AsText("Csrf Token not valid.").WithStatusCode(403);
                }
                
                ViewBag.Name = Request.Form.Name;
                return View["Index"];
            };
        }   
    }
}   

As you can I simply return a text response to the user, telling them the token is invalid. Also I’m returning a 403 Forbidden status code instead of 500 Internal Error. You may choose another solution :-)

Simple as that!

That is how CSRF protection works using Nancy. Please notice I’m not showing best practice here. You should move the try-catch into a BaseModule (maybe use the Before hook), there’s no need to copy/paste that code into every action of your application.

If I helped you out, please leave a comment, I love feedback :-)

The full example/demo is available at GitHub: https://github.com/jhovgaard/nancy-csrfdemo

Do you still manage your web server through remote desktop or IIS Manager? Try Servant.io today!

Servant for IIS is now open-source!

PUBLISHED 9 September, 2013 ()

Servant for IIS on GitHub!

Wauw, happy days! This was a biggy! I’ve decided to completely open-source my number 1 pet project, Servant for IIS, under the MIT license. This means that you can jump right to https://github.com/jhovgaard/servant and check out the source. You can of course fork your own version, make it more awesome and send me your pull request!

I received a couple of questions regarding the open sourcing of Servant. I’ll share my answers here:

Was Servant initially meant to be monetized?

Absolutely! I wanted to make a Pro edition and earn some cash that way. Unfortunately for my economy it felt wrong. I’ve never shared anything but my blog posts with the community, even that I got so much from it. Making money out of my first real project just felt bad so I decided to open source it instead.

Does open sourcing Servant mean you’ll stop supporting and developing it?

Not at all. I’ll continue to support and develop Servant like I used to. The only difference is that you guys can help me make it go a lot faster! :-)

So that’s it! My first open-source project. I’m very excited about the future of Servant. I hope to see a lot of issues getting created and even some pull requests (that really would be awesome!).

Thanks for reading!

Jonas

Do you still manage your web server through remote desktop or IIS Manager? Try Servant.io today!

Servant 1.1 released

PUBLISHED 5 July, 2013 ()

At last, Servant 1.1 is now released and publicly available. The release of the first version was a very overwhelming experience. I received a lot of wonderful feedback from people who loved what Servant brought to the IIS. At the same time I was also taught that developers simply don’t accept bugs and glitches in production software. Servant 1.1 is all about that - bugfixes and performance improvements (boring stuff, I agree).

I’ll walk through the most exciting changes, starting with new features.

HTTPS support

I’m introducing HTTPS support for the Servant engine itself. That means that you’re now able to change the URL of Servant to for example https://servant.example.com. When Servant detects HTTPS in the entered URL a self-signed certificate will be created and installed on the server. You will see the nasty browser warning telling you that the site is not safe. That’s expected. To avoid it you would need to buy a SSL certificate for Servant. I don’t expect requests for this feature, but if you need it, please add/vote the idea at the UserVoice site.

Automatic error reporting and usage statistics

I had a hard time solving users’ problems. To overcome this, exceptions in Servant is now being sent to Raygun.io. Also all traffic is tracked using Google Analytics. Everything is totally anonymous.

For Google Analytics Servant uses IP Anonymization to hide your servers IP and disable cookieDomain to hide your hostname.

For error reporting Servant isn’t sending any personal data either. Reports are limited to machine informations (hardware, OS info), URL (without hostname) and the stacktrace of the thrown exception.

If you don’t like any data leaving your server you can disable it all under settings or during the installation.

Support for virtual applications

This is step 1/2 of the most requested feature for Servant: support for virtual applications under sites. A lot of people found Servant completely useless because their IIS setup was completely depending on virtual applications and directories. Applications are now supported. Directories is coming, I just need to figure out a smart way to visualize it.

Intelligent exception parsing

Servant now parses exception more intelligently. Instead of showing a huge list of HttpException for example, exceptions are now being parsed and the top exception message is shown. The message is gathered from the stacktrace’s first line, exactly how IIS shows errors.

IIS Default Web Site were missing

Yes, the biggest bug on Servant 1.0 has been fixed. A lot of users experienced that the site created by IIS on installation simply wasn’t available in Servant. It turned out that this site contained special protocol bindings such as net.tcp. Servant only supports HTTP/HTTPS. I’ve fixed it by ignoring all other protocols meaning the default web site is now available from Servant too. How could this get through the beta I ask myself…

So here you go, a stable release of Servant! The release includes a lot of additional bugfixes which isn’t mentioned in this post. Of course there will still be more bugs and glitches but hopefully few enough to overcome.

What about Servant 1.2, any new features?

What a great question! Servant 1.1 was in no doubt hard work, simply because it was boring (isn’t bugfixing always?). Developing Servant 1.2 is super fun, because it’s all about new features, great features actually.

The feature 1.2 will be remembered for is… Ready? Full blown totally automated full stack deployment! Yes! Servant will download your source from a Git repository, it will build your project, deploy it to not one but all of your Servant-enabled servers. It will even warm up each server using proxy (to support loadbalancing setups) and at last it rolls back the deploy if a server returns anything but 200 OK.

So that’s it for now. Go download Servant 1.1 and test it out yourself.

What do you think about this release? Are you excited about the upcoming deploy feature?

Have a great day!

Jonas

Do you still manage your web server through remote desktop or IIS Manager? Try Servant.io today!