public BindContext(RestRequest request, Snippet <MethodInfo> snippet) { Request = request.AssertNotNull(); Snippet = snippet.AssertNotNull(); Debug.EnsureBlankLine(); Debug.WriteLine("Binding request to {0}...", snippet.Member.GetCSharpRef(ToCSharpOptions.InformativeWithNamespaces)); var asmUri = AsmResource.Uri ?? String.Empty; var typeUri = TypeResource.Uri ?? String.Empty; var methodUri = MethodResource.Uri ?? String.Empty; var uriTemplate = asmUri + typeUri + methodUri; ResourceTemplate = uriTemplate; Debug.WriteLine(" * Resource template: {0}", ResourceTemplate); var parsed1 = new Url(request.Resource).Parse(uriTemplate); var parsed2 = new Url(request.Resource + "/").Parse(uriTemplate); var parsed = parsed1 ?? parsed2; Resource = request.Resource; ParsedResource = parsed; Debug.WriteLine(" * Resource: {0}", Resource); if (parsed != null) { Debug.WriteLine(" + Resource matches the template"); var code = snippet.Member; HandlerCode = code; HandlerContext = new HandlerContext(request, parsed, code); Handler = () => { HandlerContext.Validate().AssertTrue(); var result = HandlerContext.Invoke(); var response = request.Response; var is_json = request["Content-Type"] == "application/json"; if (is_json) { response.Succeed(new Json(result)); } else { response.Succeed(result); } }; if (HandlerContext.Validate()) { Debug.WriteLine(" + Handler arguments are bound successfully"); var asmMethods = AsmResource.Allow; var typeMethods = TypeResource.Allow; var methodMethods = MethodResource.Allow; var allowedMethods = asmMethods & typeMethods & methodMethods; AllowedMethods = allowedMethods; Debug.WriteLine(" * Allowed HTTP methods: " + AllowedMethods); var allowMethod = false; allowMethod |= (request.Method == "GET" && ((allowedMethods & RestMethods.Get) != 0)); allowMethod |= (request.Method == "PUT" && ((allowedMethods & RestMethods.Put) != 0)); allowMethod |= (request.Method == "POST" && ((allowedMethods & RestMethods.Post) != 0)); allowMethod |= (request.Method == "MERGE" && ((allowedMethods & RestMethods.Merge) != 0)); allowMethod |= (request.Method == "DELETE" && ((allowedMethods & RestMethods.Delete) != 0)); Method = request.Method; Debug.WriteLine(" * HTTP method: " + Method); if (allowMethod) { Debug.WriteLine(" + HTTP method is allowed"); var authenticators = SnippetRegistry.Methods <AuthenticationFilterAttribute>(); var skipAuthentication = AsmResource.SkipAuthentication || TypeResource.SkipAuthentication || MethodResource.SkipAuthentication; var boundAuthenticators = authenticators.Select(authenticator => { Debug.WriteLine(" * Authorizing against {0}...", authenticator.Member.GetCSharpRef(ToCSharpOptions.InformativeWithNamespaces)); return(new HandlerContext(request, parsed, authenticator.Member)); }).ToReadOnly(); var authenticated = skipAuthentication || boundAuthenticators.All(authenticator => authenticator.Validate() && Equals(authenticator.Invoke(), true)); if (authenticated) { Debug.WriteLine(" + Authentication successful"); var authorizers = SnippetRegistry.Methods <AuthorizationFilterAttribute>(); var skipAuthorization = AsmResource.SkipAuthorization || TypeResource.SkipAuthorization || MethodResource.SkipAuthorization; var boundAuthorizers = authorizers.Select(authorizer => { Debug.WriteLine(" * Authorizing against {0}...", authorizer.Member.GetCSharpRef(ToCSharpOptions.InformativeWithNamespaces)); return(new HandlerContext(request, parsed, authorizer.Member)); }).ToReadOnly(); var authorized = skipAuthorization || boundAuthorizers.All(authorizer => authorizer.Validate() && Equals(authorizer.Invoke(), true)); if (authorized) { Debug.WriteLine(" + Authorization successful"); Debug.WriteLine(" * Bind successful"); Result = BindResult.Success; } else { Debug.WriteLine(" FAIL => Failed to authorize"); Result = BindResult.NotAuthorized; } } else { Debug.WriteLine(" FAIL => Failed to authenticate"); Result = BindResult.NotAuthenticated; } } else { Debug.WriteLine(" FAIL => HTTP method is not allowed"); Result = BindResult.MethodMismatch; } } else { Debug.WriteLine(" FAIL => Failed to bind handler arguments"); Result = BindResult.ArgsMismatch; } } else { Debug.WriteLine("FAIL => Resource doesn't match the template"); Result = BindResult.UrlMismatch; } }