Nancy: OPTIONS route ignores Before/After pipelines

Created on 28 Jan 2014  ·  7Comments  ·  Source: NancyFx/Nancy

I use Nancy together with backbone. When I save a model to the server, backbone sends a OPTIONS request to check if the server accepts PUT requests (see this SO answer). Nancy answers these automatically, but it does not run the after pipeline of my module, which looks like this:

After += ctx => ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");

Because the Access-Control-Allow-Origin is not set, the request fails:

OPTIONS http://localhost:5555/machines No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. vendor.js:3
XMLHttpRequest cannot load http://localhost:5555/machines. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access. 

Request headers:

Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en,de-DE;q=0.8,de;q=0.6,en-US;q=0.4,fr;q=0.2
Access-Control-Request-Headers:accept, content-type
Access-Control-Request-Method:PUT
Cache-Control:no-cache
Connection:keep-alive
Host:localhost:5555
Origin:http://localhost
Pragma:no-cache
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.76 Safari/537.36

Response headers:

Allow:GET, POST, PUT
Cache-Control:private
Connection:Close
Content-Length:0
Date:Tue, 28 Jan 2014 08:20:13 GMT
Server:ASP.NET Development Server/11.0.0.0
X-AspNet-Version:4.0.30319

Most helpful comment

I am having this same issue and the ApplicationStartup did not help me

All 7 comments

Since the OPTIONS request is handled outside of a module, the DefaultRouteResolver returns a ResolveResult where Before and After pipelines are null, here.

This results in the DefaultRequestDispatcher returning early and not invoking any pipeline, here.

The solution would be to somehow get the pipelines into the DefaultRouteResolver, maybe by adding an Initialize method like IDiagnostics, IApplicationStartup, etc. and invoke that in the bootstrapper somewhere :smile:

I only came so far:

protected override NancyInternalConfiguration InternalConfiguration
{
    get
    {
        return NancyInternalConfiguration.WithOverrides(x => x.RouteResolver = typeof(CustomRouteResolver));
    }
}

public class CustomRouteResolver : DefaultRouteResolver 
{
  public CustomRouteResolver(INancyModuleCatalog catalog, INancyModuleBuilder moduleBuilder, IRouteCache routeCache, IRouteResolverTrie trie)
        : base(catalog, moduleBuilder, routeCache, trie)
    {

    }
    public void Initialize()
    {
    }
}

Resolve does not run any callbacks before passing the request to BuildOptionsResult, which is why I have no idea what to do in Initialize. But I don't know Nancy very well...

Can you help? Thank you very much!

I'll take a look at it :wink:

So this is within a NancyModule? Is there a reason why this has to be inside a specific module? I wrote a test that passes perfectly:

[Fact]
public void Should_invoke_AfterRequest_pipeline()
{
    var afterPipelineInvoked = false;
    var bootstrapper = new ConfigurableBootstrapper();

    bootstrapper.AfterRequest
            .AddItemToEndOfPipeline(ctx => afterPipelineInvoked = true);

    new Browser(bootstrapper).Options("/");

    Assert.True(afterPipelineInvoked);
}

Try adding the Access-Control-Allow-Origin header in the bootstrapper's ApplicationStartup method instead :smile:

You are totally right, it works when I do this the bootstrapper:

protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
{
    pipelines.AfterRequest += (ctx) =>
    {
        ctx.Response.Headers.Add("Access-Control-Allow-Origin", "*");
    }
}

Thanks again! :thumbsup:

Glad you figured it out! :dancers:

I am having this same issue and the ApplicationStartup did not help me

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zaid-Ajaj picture Zaid-Ajaj  ·  4Comments

phillip-haydon picture phillip-haydon  ·  10Comments

jchannon picture jchannon  ·  7Comments

Radzhab picture Radzhab  ·  11Comments

phillip-haydon picture phillip-haydon  ·  3Comments