Fix and OWIN and Simple.Web

In readiness for my new course on building SPAs with AngularJS, TypeScript and Simple.Web, I published some updates to Simple.Web and Fix last night. The way Fix works has changed a bit, so I thought a quick post was in order.

The old Fix

I wrote Fix while the denizens of the OWIN mailing list were still hammering out the specification. (Its original name was actually CRack, as in “C# Rack” but also as in “This server is running on CRack”, but it was pointed out to me that that name might hamper adoption.) Fix was the original home of the stupefyingly complicated Func/Action signature that was proposed (by me) as a way of not taking a dependency on the Task type, so we could maintain compatibility with .NET 3.5. In case you missed them at the time, here’s a sample of the Request and Response delegates from an early version:

using RequestHandler = System.Action<
    System.Collections.Generic.IDictionary<string, string>,
    System.Func<byte[]>,
    System.Action<
        int,
        System.Collections.Generic.IEnumerable<
            System.Collections.Generic.KeyValuePair<string, string>
        >,
        System.Func<byte[]>
    >, 
    System.Action<System.Exception>>;
using ResponseHandler = System.Action<int, 
    System.Collections.Generic.IEnumerable<
        System.Collections.Generic.KeyValuePair<string, string>
    >,
    System.Func<byte[]>>;

As time passed and .NET 4.0 became more widespread, we decided that we should forget 3.5 in the name of keeping it reasonably simple, so that the OWIN delegate signature became:

Func<IDictionary<string,object>, Task>

(I know: boring, right?)

Based on this new standard, a small team at Microsoft began work in earnest on Katana, their implementation of OWIN “glue”; that is, the meta-code that plumbs servers, applications and middleware together. Support for that implementation is included in-the-box with Visual Studio 2013 and the latest One ASP.NET bits, and it’s one of the first Microsoft-published assemblies to have the Windows-only restriction removed from the license.

I do have some issues with Katana though. One of the things that project has embraced enthusiastically is the Owin.dll and its IAppBuilder interface, which some people think makes it easier to set things up. I don’t like that assembly dependency, and I don’t really like the IAppBuilder.Use method’s signature:

public interface IAppBuilder {
    IAppBuilder Use(object middleware, params object[] args);
}

You could literally call that with anything. The most basic valid argument is an OWIN delegate, i.e. a Func<IDictionary<string,object>, Task>. But that introduces an interesting problem as to how a component in an OWIN pipeline signifies that processing should stop or continue; as I understand it, it should return 404 to indicate that processing may continue, but I may be wrong.

My other issue is that Katana is full-on Microsoft, enterprise-ready, all-things-to-all-consumers, and complicated in ways I don’t quite understand, such as in the way it’s interacting with IIS’s integrated pipeline. That’s what Microsoft do, and I’m not exactly criticising them for it, but sometimes you don’t need a Swiss Army knife. Sometimes you just need a knife.

Because of these issues, and also because OWIN should not be reduced to a single implementation, Fix has moved to it’s new home on GitHub and I’m continuing to work on it, and hoping the community will pitch in (which is why it’s not under my name anymore).

The new Fix

Fix 0.4 has been simplified from the previous version, which used to use MEF to do auto-discovery of apps and middleware and stick them together any which way it wanted. That’s a bloody stupid approach, since the order in which middleware runs is hugely important and something you should have total control over. So now, Fix uses a setup class to configure the pipeline. That class should be called OwinAppSetup, and should have a public method (instance or static) that takes – you guessed it – an Action delegate. Here’s a sample:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.IO;

namespace FixExample
{
    using System.Text;
    using UseAction = Action<
        Func<
            IDictionary<string, object>, // OWIN Environment
            Func<Task>, // Next component in pipeline
            Task // Return
        >
    >;

    public static class OwinAppSetup
    {
        public static void Setup(UseAction use)
        {
            use(async (env, next) =>
            {
                var stream = (Stream) env["owin.ResponseBody"];
                await stream.WriteAsync("<h1>OWIN!</h1>");
                env["owin.ResponseStatusCode"] = 200;
            });
        }

        public static Task WriteAsync(this Stream stream, string text)
        {
            var bytes = Encoding.Default.GetBytes("<h1>OWIN!</h1>");
            return stream.WriteAsync(bytes, 0, bytes.Length);
        }
    }
}

If that delegate looks complicated, it shouldn’t; it’s just a slight variation on the OWIN delegate signature, wrapped in an Action. (If it still looks complicated, you can take a dependency on Fix.dll and write a method that takes a single Fixer parameter.) ((If you really like IAppBuilder, there is a Fix.AppBuilder package that will let your Setup method take an instance of IAppBuilder, although it will currently throw a NotSupportedException if you call Use with anything but Fix’s preferred delegate signature.))

Fix’s variant OWIN delegate (inspired by the Connect package for Node.js) differs in that it takes an additional parameter of type Func<Task>. Fix expects any middleware or application to call that function in order to continue processing; if it wants to terminate the request itself, it just doesn’t call it.

This introduces a lot of additional power and flexibility. OWIN components, whether middleware or applications, can do what they do to the environment dictionary, and then do one of three things:

  • Ignore the next delegate to complete processing, as in the example above;
  • Call the next delegate and return its return value directly;

    or

  • Await the next delegate and do some more processing.

Now middleware components can very easily modify the Request parts of the environment dictionary before an application is called, but can also modify the Response parts after the application has returned; for example, to compress the output in the “owin.ResponseBody” stream.

Self-hosting

Presently, the OwinAppSetup class is only required if you are using the Fix.AspNet package to host your OWIN application on IIS. If you want a self-hosted application, you can use a lightweight HTTP server like Nowin or Flux, and consume the Fix.Fixer class directly to configure an application and build an OWIN delegate for the server. There’s an example in the Fix repository using the Nowin server in a console application. Here’s the Main method from that sample, using Simple.Web as the application framework:

using System;
using Fix;
using Nowin;
using Simple.Web;

namespace SimpleNowinDemo
{
    class Program
    {
        static void Main()
        {
            // Build the OWIN app
            var app = new Fixer()
                .Use(Application.Run) // Simple.Web
                .Build();

            // Set up the Nowin server
            var builder = ServerBuilder.New()
                .SetPort(1337)
                .SetOwinApp(app);

            // Run
            using (builder.Start())
            {
                Console.WriteLine("Listening on port 1337. Enter to exit.");
                Console.ReadLine();
            }
        }
    }
}

(That’s why there’s no Simple.Web.Hosting.Self package; it’s just not necessary.)

But… Simple.Web.AspNet?

Yes, there is a Simple.Web.AspNet package, but it’s basically a meta-package that adds Fix and Fix.AspNet. It also creates the OwinAppSetup class for you, and adds the Application.Run method to it. In fact, it’s currently Simple.Web.AspNet that adds the FixHttpHandler to web.config, which is wrong and I’m going to sort that out once I’ve posted this.

What’s next?

Fix 0.4 works, and I am using it in production with Simple.Web. My next job is to move the static file handling from Simple.Web into a Simple.Owin.Statics middleware, and create Simple.Owin.Cors and Simple.Owin.Xsrf.

There are also a few areas where I’m really hoping the community will engage with discussion and pull requests:

Fix’s alternative delegate

I’m going to add some kind of wrapper for the original OWIN delegate, but it would be good if middleware and framework authors considered adding support for the Fix alternative. It really does make life easier (and applications more performant). Yes, I know, variants are bad because standards, but sometimes variants can improve standards and that’s a good thing.

Fix.AppBuilder

As mentioned, this is currently just a very simple wrapper around Fixer’s Use method, but I’d like it to support all the same signatures as the Katana implementation (well, most of them).

Standardising server start-up

I’d really like to come up with some kind of standard for configuring and starting OWIN-compliant HTTP servers. I’m thinking of something similar to the OwinAppSetup class, maybe have a convention where there is a class called OwinServerSetup with a standardised Start method. Here’s how that would look with Nowin:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net;

namespace Nowin
{
  using AppFunc = Func<IDictionary<string, object>, Task>;

  public static class OwinServerSetup
  {
    public static IDisposable Start(AppFunc app, 
                  IPAddress address, 
                  int? port, 
                  X509Certificate certificate)
    {
      var builder = ServerBuilder.New().SetOwinApp(app);
      if (address != null)
      {
        builder.SetAddress(address);
      }
      if (port.HasValue)
      {
        builder.SetPort(port.Value);
      }
      if (certificate != null)
      {
        builder.SetCertificate(certificate);
      }

      return builder.Start();
    }
  }
}

This would enable a FixUp.exe app that you could just run from the command line, something like:

D:\Code\MyApp> fixup nowin.dll myapp.dll

If you maintain a .NET HTTP server and think this is an interesting idea, please get in touch via Twitter or something.

Comments

  1. > But that introduces an interesting problem as to how a component in an OWIN pipeline signifies that processing should stop or continue; as I understand it, it should return 404 to indicate that processing may continue, but I may be wrong.

    Yeah this is wrong. A component signifies stopping by completing the task, or continuing to the next stage by invoking the ‘next’ appfunc passed into it’s ctor. If a component completes without setting a status code, 200 is used by default. Some middleware, such as nancy, is ‘terminating’ by default. That is, if it can’t handle the request, it’ll return 404 and complete the task. Nancy can be configured to ‘pass-through’ in such circumstances, if the user wants.

    > such as in the way it’s interacting with IIS’s integrated pipeline.
    That’s all optional though and, I believe, is really there for back-compat / interop with existing apps reasons (not unreasonable).

    Good post though, interesting take on the application composition.

  2. I agree that the management of middleware (continue or not) belongs in the deployment, not baked into the middleware. Middleware should be responsible for a specific function, caching, auth, etc, and should have no responsibility as to how it is deployed. It does take a little bit more work than just constructor injection, but the value of post processing the result from the remainder of the pipeline is hugemongous.

  3. Hi, Nowin author here. First thanks again for such nice promotion.

    OwinServerFactory pattern for ms.owin.host is relatively complex, but not that much (each server author needs to write it just once and generally forget it). What is bad that even-though I added support for setting certificate for https, it is useless because there is no way to set it from ms.owin.host. Also complexity to enable IMHO useless feature to listen on 2+ addresses and using same AppFunc, is just to maintain HttpListener feature, where you get this for free. This could be really host feature to orchestrate multiple server instances if needed.
    I also don’t mind to include your much easier to write pattern for server startup. Let me know if I should do it by posting feature request on github.

Trackbacks

  1. […] Fix and OWIN and Simple.Web – Mark Rendle discusses some of his latest changes to Simple.Web and Fix (formerly CRack) his non-task API dependent implementation of OWIN interfaces, discussing how it can self host Simple.Web. […]

  2. […] Fix and OWIN and Simple.Web (Mark Rendle) […]

  3. […] Rendle, quien ya en una ocasión había hablado sobre el oss en .net, ha publicado en su blog un articulo en el que habla sobre algunas nuevas características incluidas en el proyecto […]

  4. […] this is not part of the OWIN specification. There’s another wire up solution in the form of Mark Rendles “fix” that just needs a lamdba function, but this isn’t part of OWIN either. There just isn’t […]

  5. […] exactly when or why this happened. The major problem is that implementations like Simple.Owin, Fix, and Dyfrig, which don’t rely on IAppBuilder, are incompatible with a majority of the current […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 4,057 other followers

%d bloggers like this: