示例#1
0
        protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
        {
            base.ConfigureRequestContainer(container, context);

            var store = container.Resolve<IDocumentStore>();
            container.Register<IDocumentSession>(store.OpenSession()); 
        }
示例#2
0
        /// <summary>
        /// Gets all matches for a given requested route
        /// Overridden to handle greedy capturing
        /// </summary>
        /// <param name="segments">Requested route segments</param>
        /// <param name="currentIndex">Current index in the route segments</param>
        /// <param name="capturedParameters">Currently captured parameters</param>
        /// <param name="context">Current Nancy context</param>
        /// <returns>A collection of <see cref="MatchResult"/> objects</returns>
        public override IEnumerable<MatchResult> GetMatches(string[] segments, int currentIndex, IDictionary<string, object> capturedParameters, NancyContext context)
        {
            var fullGreedy = this.GetFullGreedy(segments, currentIndex, capturedParameters);
            if (!this.Children.Any())
            {
                return fullGreedy;
            }

            var sb = new StringBuilder(segments[currentIndex]);
            var results = new List<MatchResult>();
            currentIndex++;

            while (!this.NoMoreSegments(segments, currentIndex - 1))
            {
                var currentSegment = segments[currentIndex];

                TrieNode matchingChild;
                if (this.Children.TryGetValue(currentSegment, out matchingChild))
                {
                    var parameters = new Dictionary<string, object>(capturedParameters);
                    parameters[this.parameterName] = sb.ToString();
                    results.AddRange(matchingChild.GetMatches(segments, currentIndex, parameters, context));
                }

                sb.AppendFormat("/{0}", currentSegment);
                currentIndex++;
            }

            if (!results.Any())
            {
                results.AddRange(fullGreedy);
            }

            return results;
        }
        public void Should_add_negotiated_headers_to_response()
        {
            // Given

            var module = new ConfigurableNancyModule(with =>
            {
                with.Get("/headers", x =>
                {
                    var context =
                        new NancyContext { NegotiationContext = new NegotiationContext() };

                    var negotiator =
                        new Negotiator(context);
                    negotiator.WithHeader("foo", "bar");

                    return negotiator;
                });
            });

            var brower = new Browser(with =>
            {
                with.ResponseProcessor<TestProcessor>();

                with.Module(module);
            });

            // When
            var response = brower.Get("/headers");

            // Then
            Assert.True(response.Headers.ContainsKey("foo"));
            Assert.Equal("bar", response.Headers["foo"]);
        }
        /// <summary>
        /// Applies a filter to the provided list of routes. Routes that do not pass the filter will be places in the second item of the returned tuple
        /// along with the provided <paramref name="rejectReason"/>.
        /// </summary>
        /// <param name="routes">The routes that the filter should be applied to.</param>
        /// <param name="context">The context of the current request.</param>
        /// <param name="rejectReason">The message that should be attached to rejected routes.</param>
        /// <param name="condition">The condition that routes need to fulfill.</param>
        /// <returns>A tuple of valid and rejected routes.</returns>
        public static Tuple<List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>, Dictionary<string, List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>>> Filter(this Tuple<List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>, Dictionary<string, List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>>> routes, NancyContext context, string rejectReason, Func<NancyContext, Tuple<string, int, RouteDescription, IRoutePatternMatchResult>, Tuple<bool, Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>> condition)
        {
            var result = new Tuple<List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>, Dictionary<string, List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>>>(
                new List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>(),
                routes.Item2
                );

            foreach (var conditionResult in routes.Item1.Select(route => condition.Invoke(context, route)))
            {
                if (conditionResult.Item1)
                {
                    result.Item1.Add(conditionResult.Item2);
                }
                else
                {
                    if (!result.Item2.ContainsKey(rejectReason))
                    {
                        result.Item2.Add(rejectReason, new List<Tuple<string, int, RouteDescription, IRoutePatternMatchResult>>());
                    }

                    result.Item2[rejectReason].Add(conditionResult.Item2);
                }
            }

            return result;
        }
        public void Should_apply_default_accept_when_no_accept_header_sent()
        {
            // Given
            var browser = new Browser(with =>
            {
                with.ResponseProcessor<TestProcessor>();

                with.Module(new ConfigurableNancyModule(x =>
                {
                    x.Get("/", parameters =>
                    {
                        var context =
                            new NancyContext { NegotiationContext = new NegotiationContext() };

                        var negotiator =
                            new Negotiator(context);

                        return negotiator;
                    });
                }));
            });

            // When
            var response = browser.Get("/");

            // Then
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
        }
        /// <summary>
        /// Handle the error code
        /// </summary>
        /// <param name="statusCode">Status code</param>
        /// <param name="context">The <see cref="NancyContext"/> instance of the current request.</param>
        /// <returns>Nancy Response</returns>
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            if (context.Response != null && context.Response.Contents != null && !ReferenceEquals(context.Response.Contents, Response.NoBody))
            {
                return;
            }

            string errorPage;

            if (!this.errorPages.TryGetValue(statusCode, out errorPage))
            {
                return;
            }

            if (String.IsNullOrEmpty(errorPage))
            {
                return;
            }

            Func<HttpStatusCode, NancyContext, string, string> expansionDelegate;
            if (this.expansionDelegates.TryGetValue(statusCode, out expansionDelegate))
            {
                errorPage = expansionDelegate.Invoke(statusCode, context, errorPage);
            }

            ModifyResponse(statusCode, context, errorPage);
        }
        /// <summary>
        ///     Bind to the given model type
        /// </summary>
        /// <param name="context">Current context</param>
        /// <param name="modelType">Model type to bind to</param>
        /// <param name="instance">Optional existing instance</param>
        /// <param name="configuration">The <see cref="BindingConfig" /> that should be applied during binding.</param>
        /// <param name="blackList">Blacklisted property names</param>
        /// <returns>Bound model</returns>
        public object Bind(NancyContext context, Type modelType, object instance, BindingConfig configuration,
            params string[] blackList)
        {
            Type genericType = null;
            if (modelType.IsArray() || modelType.IsCollection() || modelType.IsEnumerable())
            {
                //make sure it has a generic type
                if (modelType.IsGenericType())
                {
                    genericType = modelType.GetGenericArguments().FirstOrDefault();
                }
                else
                {
                    var implementingIEnumerableType =
                        modelType.GetInterfaces().Where(i => i.IsGenericType()).FirstOrDefault(
                            i => i.GetGenericTypeDefinition() == typeof (IEnumerable<>));
                    genericType = implementingIEnumerableType == null ? null : implementingIEnumerableType.GetGenericArguments().FirstOrDefault();
                }

                if (genericType == null)
                {
                    throw new ArgumentException("When modelType is an enumerable it must specify the type", "modelType");
                }
            }

            var bindingContext =
                CreateBindingContext(context, modelType, instance, configuration, blackList, genericType);

            var bodyDeserializedModel = DeserializeRequestBody(bindingContext);

            return (instance as IEnumerable<string>) ?? bodyDeserializedModel;
        }
 public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     return new JsonResponse(BuildHypermedia(model, context), serializer)
                {
                    ContentType = "application/hal+json"
                };
 }
        private dynamic BuildHypermedia(object model, NancyContext context)
        {
            if (model == null) return null;

            if (model is IEnumerable)
            {
                //how to handle a collection at the root resource level?
                return ((IEnumerable)model).Cast<object>().Select(x => BuildHypermedia(x, context));
            }

            IDictionary<string, object> halModel = model.ToDynamic();
            var typeConfig = configuration.GetTypeConfiguration(model.GetType());
            if (typeConfig == null) return halModel;

            var links = typeConfig.LinksFor(model, context).ToArray();
            if (links.Any())
                halModel["_links"] = links.GroupBy(l => l.Rel).ToDictionary(grp => grp.Key, grp => BuildDynamicLinksOrLink(grp));

            var embeddedResources = typeConfig.Embedded().ToArray();
            if (embeddedResources.Any())
            {
                // Remove original objects from the model (if they exist)
                foreach (var embedded in embeddedResources)
                    halModel.Remove(embedded.OriginalPropertyName);
                halModel["_embedded"] = embeddedResources.ToDictionary(info => info.Rel, info => BuildHypermedia(info.GetEmbeddedResource(model), context));
            }

            var ignoredProperties = typeConfig.Ignored().ToArray();
            if (ignoredProperties.Any())
            {
                //remove ignored properties from the output
                foreach (var ignored in ignoredProperties) halModel.Remove(ignored);
            }
            return halModel;
        }
    public void ModifyResponseToRedirectToSessionAwareUrl(NancyContext context, SessionIdentificationData sessionIdentificationData, string parameterName) {
      if (context == null) throw new ArgumentNullException("context");
      if (sessionIdentificationData == null) throw new ArgumentNullException("sessionIdentificationData");
      if (string.IsNullOrWhiteSpace(parameterName)) throw new ArgumentNullException("parameterName");
      if (context.Request == null) throw new ArgumentException("The specified context does not contain a request", "context");
      if (context.Response == null) throw new ArgumentException("The specified context does not contain a response", "context");

      var originalUri = (Uri) context.Request.Url;
      var uriBuilder = new UriBuilder(originalUri);
      var queryParameters = HttpUtility.ParseQueryString(uriBuilder.Query);
      queryParameters.Set(parameterName, sessionIdentificationData.ToString());

      var newQueryString = string.Empty;
      if (queryParameters.Count > 0) {
        var newQueryBuilder = new StringBuilder();
        foreach (var paramName in queryParameters.AllKeys) {
          newQueryBuilder.Append(string.Format("{0}={1}&", paramName, HttpUtility.UrlEncode(queryParameters[paramName])));
        }
        newQueryString = newQueryBuilder.ToString().TrimEnd('&');
      }
      uriBuilder.Query = newQueryString;
      var redirectUrl = uriBuilder.ToString();

      context.Response.StatusCode = HttpStatusCode.Found;
      context.Response.Headers["Location"] = redirectUrl;
    }
示例#11
0
        /// <summary>
        /// Gets the route, and the corresponding parameter dictionary from the URL
        /// </summary>
        /// <param name="context">Current context</param>
        /// <param name="routeCache">Route cache</param>
        /// <returns>Tuple - Item1 being the Route, Item2 being the parameters dictionary, Item3 being the prereq, Item4 being the postreq</returns>
        public ResolveResult Resolve(NancyContext context, IRouteCache routeCache)
        {
            if (routeCache.IsEmpty())
            {
                return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null);
            }

            var routesThatMatchRequestedPath = this.GetRoutesThatMatchRequestedPath(routeCache, context);

            if (NoRoutesWereAbleToBeMatchedInRouteCache(routesThatMatchRequestedPath))
            {
                return new ResolveResult(new NotFoundRoute(context.Request.Method, context.Request.Uri), DynamicDictionary.Empty, null, null);
            }

            var routesWithCorrectRequestMethod =
                GetRoutesWithCorrectRequestMethod(context.Request, routesThatMatchRequestedPath);

            if (NoRoutesWereForTheRequestedMethod(routesWithCorrectRequestMethod))
            {
                return new ResolveResult(new MethodNotAllowedRoute(context.Request.Uri, context.Request.Method), DynamicDictionary.Empty, null, null);
            }

            var routeMatchesWithMostParameterCaptures =
                GetRouteMatchesWithMostParameterCaptures(routesWithCorrectRequestMethod);

            var routeMatchToReturn =
                GetSingleRouteToReturn(routeMatchesWithMostParameterCaptures);

            return this.CreateRouteAndParametersFromMatch(context, routeMatchToReturn);
        }
示例#12
0
        private object ResolveMethodParameter(ParameterInfo methodParameterInfo, IDictionary<string, object> queryParameters, NancyContext context)
        {
            if (IsQueryParameter(methodParameterInfo, queryParameters))
                return GetValueFromQueryParameters(methodParameterInfo, queryParameters);

            return GetValueFromRequestBody(methodParameterInfo, context);
        }
        public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
        {
            if (IsExactSirenContentType(requestedMediaRange))
            {
                return new ProcessorMatch
                {
                    ModelResult = MatchResult.DontCare,
                    RequestedContentTypeResult = MatchResult.ExactMatch
                };
            }

            if (IsWildcardSirenContentType(requestedMediaRange))
            {
                return new ProcessorMatch
                {
                    ModelResult = MatchResult.DontCare,
                    RequestedContentTypeResult = MatchResult.NonExactMatch
                };
            }

            return new ProcessorMatch
            {
                ModelResult = MatchResult.DontCare,
                RequestedContentTypeResult = MatchResult.NoMatch
            };
        }
 private static RollbarRequest GetRollbarRequest(NancyContext context) {
     var rr = new RollbarRequest {
         Url = context.Request.Url.ToString(),
         Method = context.Request.Method,
         Headers = context.Request.Headers.ToDictionary(x => x.Key, x => string.Join(",", x.Value)),
         Params = ((IDictionary<string, object>)context.Parameters).ToDictionary(x => x.Key, x => x.Value),
         UserIp = context.Request.UserHostAddress,
     };
     if (rr.Params.Count == 0) {
         rr.Params = null;
     }
     if (rr.Method == "GET") {
         rr.GetParams = ((IDictionary<string, object>) context.Request.Query).ToDictionary(x => x.Key, x => x.Value);
         if (rr.GetParams.Count == 0) {
             rr.GetParams = null;
         }
     }
     if (rr.Method == "POST") {
         rr.PostParams = ((IDictionary<string, object>) context.Request.Form)
             .Concat((IDictionary<string, object>) context.Parameters)
             .ToDictionary(x => x.Key, x => x.Value);
         if (rr.PostParams.Count == 0) {
             rr.PostParams = null;
         }
         rr.PostBody = context.Request.Body.AsString();
     }
     return rr;
 }
示例#15
0
        public NancyEngineFixture()
        {
            this.resolver = A.Fake<IRouteResolver>();
            this.response = new Response();
            this.route = new FakeRoute(response);
            this.context = new NancyContext();
            this.errorHandler = A.Fake<IErrorHandler>();
            this.requestDispatcher = A.Fake<IRequestDispatcher>();

            A.CallTo(() => this.requestDispatcher.Dispatch(A<NancyContext>._)).Invokes(x => this.context.Response = new Response());

            A.CallTo(() => errorHandler.HandlesStatusCode(A<HttpStatusCode>.Ignored, A<NancyContext>.Ignored)).Returns(false);

            contextFactory = A.Fake<INancyContextFactory>();
            A.CallTo(() => contextFactory.Create()).Returns(context);

            A.CallTo(() => resolver.Resolve(A<NancyContext>.Ignored)).Returns(new ResolveResult(route, DynamicDictionary.Empty, null, null, null));

            var applicationPipelines = new Pipelines();

            this.routeInvoker = A.Fake<IRouteInvoker>();

            A.CallTo(() => this.routeInvoker.Invoke(A<Route>._, A<DynamicDictionary>._, A<NancyContext>._)).ReturnsLazily(arg =>
            {
                return (Response)((Route)arg.Arguments[0]).Action.Invoke((DynamicDictionary)arg.Arguments[1]);
            });

            this.engine =
                new NancyEngine(this.requestDispatcher, contextFactory, new[] { this.errorHandler }, A.Fake<IRequestTracing>())
                {
                    RequestPipelinesFactory = ctx => applicationPipelines
                };
        }
        public FormsAuthenticationFixture()
        {
            this.cryptographyConfiguration = new CryptographyConfiguration(
                new RijndaelEncryptionProvider(new PassphraseKeyGenerator("SuperSecretPass", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, 1000)),
                new DefaultHmacProvider(new PassphraseKeyGenerator("UberSuperSecure", new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }, 1000)));

            this.config = new FormsAuthenticationConfiguration()
            {
                CryptographyConfiguration = this.cryptographyConfiguration,
                RedirectUrl = "/login",
                UserMapper = A.Fake<IUserMapper>(),
                RequiresSSL = false
            };

            this.secureConfig = new FormsAuthenticationConfiguration()
            {
                CryptographyConfiguration = this.cryptographyConfiguration,
                RedirectUrl = "/login",
                UserMapper = A.Fake<IUserMapper>(),
                RequiresSSL = true
            };

            this.context = new NancyContext
                               {
                                    Request = new Request(
                                                    "GET",
                                                    new Url { Scheme = "http", BasePath = "/testing", HostName = "test.com", Path = "test" })
                               };

            this.userGuid = new Guid("3D97EB33-824A-4173-A2C1-633AC16C1010");
        }
		public void Should_fail_to_create_xdocument_from_non_xml_body()
		{
			var context = new NancyContext() { Response = "hello" };
			sut = new BrowserResponse(context, A.Fake<Browser>());	

			Assert.Throws<XmlException>(() => sut.BodyAsXml());
		}
        private static string GetEmbeddedStaticContent(string virtualDirectory, string requestedFilename, string root = null)
        {
            var resource =
                string.Format("/{0}/{1}", virtualDirectory, requestedFilename);

            var context =
                new NancyContext
                {
                    Request = new Request("GET", resource, "http")
                };

            var assembly =
                Assembly.GetExecutingAssembly();

            var resolver =
                EmbeddedStaticContentConventionBuilder.AddDirectory(virtualDirectory, assembly, "Resources");

            var response =
                resolver.Invoke(context, null) as EmbeddedFileResponse;

            if (response != null)
            {
                using (var stream = new MemoryStream())
                {
                    response.Contents(stream);
                    return Encoding.UTF8.GetString(stream.GetBuffer(), 0, (int)stream.Length);
                }
            }

            return null;
        }
示例#19
0
        public void Should_fail_to_return_xml_body_on_non_xml_response()
        {
            var response = new JsonResponse<Model>(new Model() { Dummy = "Data" });
            var context = new NancyContext() { Response = response };

            Assert.Throws<InvalidOperationException>(() => context.XmlBody<Model>());
        }
示例#20
0
        private static void AddLinkHeaders(NancyContext context, IEnumerable<Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>> compatibleHeaders, Response response)
        {
            var linkProcessors = new Dictionary<string, MediaRange>();

            var compatibleHeaderMappings =
                compatibleHeaders.SelectMany(m => m.Item2).SelectMany(p => p.Item1.ExtensionMappings);

            foreach (var compatibleHeaderMapping in compatibleHeaderMappings)
            {
                if (!compatibleHeaderMapping.Item2.Matches(response.ContentType))
                {
                    linkProcessors[compatibleHeaderMapping.Item1] = compatibleHeaderMapping.Item2;
                }
            }

            if (!linkProcessors.Any())
            {
                return;
            }

            var baseUrl =
                context.Request.Url.BasePath + "/" + Path.GetFileNameWithoutExtension(context.Request.Url.Path);

            var links = linkProcessors.Keys
                .Select(lp => string.Format("<{0}.{1}>; rel=\"{2}\"", baseUrl, lp, linkProcessors[lp]))
                .Aggregate((lp1, lp2) => lp1 + "," + lp2);

            response.Headers["Link"] = links;
        }
示例#21
0
        /// <summary>
        /// Negotiates the response based on the given result and context.
        /// </summary>
        /// <param name="routeResult">The route result.</param>
        /// <param name="context">The context.</param>
        /// <returns>A <see cref="Response" />.</returns>
        public Response NegotiateResponse(dynamic routeResult, NancyContext context)
        {
            Response response;
            if (TryCastResultToResponse(routeResult, out response))
            {
                context.WriteTraceLog(sb =>
                    sb.AppendLine("[DefaultResponseNegotiator] Processing as real response"));

                return response;
            }

            context.WriteTraceLog(sb =>
                sb.AppendLine("[DefaultResponseNegotiator] Processing as negotiation"));

            NegotiationContext negotiationContext = GetNegotiationContext(routeResult, context);

            var coercedAcceptHeaders = this.GetCoercedAcceptHeaders(context).ToArray();

            context.WriteTraceLog(sb => GetAccepHeaderTraceLog(context, negotiationContext, coercedAcceptHeaders, sb));

            var compatibleHeaders = this.GetCompatibleHeaders(coercedAcceptHeaders, negotiationContext, context).ToArray();

            if (!compatibleHeaders.Any())
            {
                context.WriteTraceLog(sb =>
                    sb.AppendLine("[DefaultResponseNegotiator] Unable to negotiate response - no headers compatible"));

                return new NotAcceptableResponse();
            }

            return CreateResponse(compatibleHeaders, negotiationContext, context);
        }
        /// <summary>
        /// Handle the error code
        /// </summary>
        /// <param name="statusCode">Status code</param>
        /// <param name="context">The <see cref="NancyContext"/> instance of the current request.</param>
        /// <returns>Nancy Response</returns>
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            if (context.Response != null && context.Response.Contents != null && !ReferenceEquals(context.Response.Contents, Response.NoBody))
            {
                return;
            }

            if (!this.errorMessages.ContainsKey(statusCode) || !this.errorPages.ContainsKey(statusCode))
            {
                return;
            }

            var result = new DefaultStatusCodeHandlerResult(statusCode, this.errorMessages[statusCode], StaticConfiguration.DisableErrorTraces ? DisableErrorTracesTrueMessage : context.GetExceptionDetails());
            try
            {
                context.Response = this.responseNegotiator.NegotiateResponse(result, context);
                context.Response.StatusCode = statusCode;
                return;
            }
            catch (ViewNotFoundException)
            {
                // No view will be found for `DefaultStatusCodeHandlerResult`
                // because it is rendered from embedded resources below
            }

            this.ModifyResponse(statusCode, context, result);
        }
    public ResponseManipulatorForSessionFixture() {
      _responseManipulatorForSession = new ResponseManipulatorForSession();

      _context = new NancyContext {Response = new Response(), Request = new Request("GET", "http://www.google.be")};
      _sessionIdentificationData = new SessionIdentificationData {SessionId = "01SessionId", Hmac = new byte[] {211, 81, 204, 0, 47, 124}};
      _parameterName = "SID";
    }
示例#24
0
        /// <summary>
        /// Creates a token from a <see cref="IUserIdentity"/>.
        /// </summary>
        /// <param name="userIdentity">The user identity from which to create a token.</param>
        /// <param name="context">Current <see cref="NancyContext"/>.</param>
        /// <returns>The generated token.</returns>
        public string Tokenize(IUserIdentity userIdentity, NancyContext context)
        {
            var items = new List<string>
            {
                userIdentity.UserName,
                string.Join(this.claimsDelimiter, userIdentity.Claims),
                this.tokenStamp().Ticks.ToString(CultureInfo.InvariantCulture)
            };

            if (this.additionalItems != null)
            {
                foreach (var item in this.additionalItems.Select(additionalItem => additionalItem(context)))
                {
                    if (string.IsNullOrWhiteSpace(item))
                    {
                        throw new RouteExecutionEarlyExitException(new Response { StatusCode = HttpStatusCode.Unauthorized });
                    }
                    items.Add(item);
                }
            }

            var message = string.Join(this.itemDelimiter, items);
            var token = CreateToken(message);
            return token;
        }
        public void Should_add_negotiated_content_headers_to_response()
        {
            // Given

              var module = new ConfigurableNancyModule(with =>
              {
            with.Get("/headers", (x, m) =>
            {
              var context =
                  new NancyContext { NegotiationContext = new NegotiationContext() };

              var negotiator =
                  new Negotiator(context);
              negotiator.WithContentType("text/xml");

              return negotiator;
            });
              });

              var brower = new Browser(with =>
              {
            with.ResponseProcessor<TestProcessor>();

            with.Module(module);
              });

              // When
              var response = brower.Get("/headers");

              // Then
              Assert.Equal("text/xml", response.Context.Response.ContentType);
        }
示例#26
0
        /// <summary>
        /// Invokes the specified <paramref name="route"/> with the provided <paramref name="parameters"/>.
        /// </summary>
        /// <param name="route">The route that should be invoked.</param>
        /// <param name="cancellationToken">Cancellation token</param>
        /// <param name="parameters">The parameters that the route should be invoked with.</param>
        /// <param name="context">The context of the route that is being invoked.</param>
        /// <returns>A <see cref="Response"/> instance that represents the result of the invoked route.</returns>
        public async Task<Response> Invoke(Route route, CancellationToken cancellationToken, DynamicDictionary parameters, NancyContext context)
        {
            object result;

            try
            {
                result = await route.Invoke(parameters, cancellationToken).ConfigureAwait(false);
            }
            catch(RouteExecutionEarlyExitException earlyExitException)
            {
                context.WriteTraceLog(
                    sb => sb.AppendFormat(
                            "[DefaultRouteInvoker] Caught RouteExecutionEarlyExitException - reason {0}",
                            earlyExitException.Reason));
                return earlyExitException.Response;
            }

            if (!(result is ValueType) && result == null)
            {
                context.WriteTraceLog(
                    sb => sb.AppendLine("[DefaultRouteInvoker] Invocation of route returned null"));

                result = new Response();
            }

            return this.negotiator.NegotiateResponse(result, context);
        }
示例#27
0
        private static ResolveResult BuildMethodNotAllowedResult(NancyContext context, IEnumerable<string> allowedMethods)
        {
            var route =
                new MethodNotAllowedRoute(context.Request.Path, context.Request.Method, allowedMethods);

            return new ResolveResult(route, new DynamicDictionary(), null, null, null);
        }
示例#28
0
        /// <summary>
        /// Creates a response that sets the authentication cookie and redirects
        /// the user back to where they came from.
        /// </summary>
        /// <param name="context">Current context</param>
        /// <param name="userIdentifier">User identifier guid</param>
        /// <param name="cookieExpiry">Optional expiry date for the cookie (for 'Remember me')</param>
        /// <param name="fallbackRedirectUrl">Url to redirect to if none in the querystring</param>
        /// <returns>Nancy response with redirect.</returns>
        public static Response UserLoggedInRedirectResponse(NancyContext context, Guid userIdentifier, DateTime? cookieExpiry = null, string fallbackRedirectUrl = null)
        {
            var redirectUrl = fallbackRedirectUrl;

            if (string.IsNullOrEmpty(redirectUrl))
            {
                redirectUrl = context.Request.Url.BasePath;
            }

            if (string.IsNullOrEmpty(redirectUrl))
            {
                redirectUrl = "/";
            }

            string redirectQuerystringKey = GetRedirectQuerystringKey(currentConfiguration);

            if (context.Request.Query[redirectQuerystringKey].HasValue)
            {
                var queryUrl = (string)context.Request.Query[redirectQuerystringKey];

                if (context.IsLocalUrl(queryUrl))
                {
                    redirectUrl = queryUrl;
                }
            }

            var response = context.GetRedirect(redirectUrl);
            var authenticationCookie = BuildCookie(userIdentifier, cookieExpiry, currentConfiguration);
            response.AddCookie(authenticationCookie);

            return response;
        }
        private static void SaveSession(NancyContext ctx, IKeyValueStore store)
        {
            if (ctx.Request == null || ctx.Request.Session == null || !ctx.Request.Session.HasChanged)
                return;

            string id;
            if (ctx.Request.Cookies.ContainsKey(GetCookieName()))
            {
                id = ctx.Request.Cookies[GetCookieName()];
            }
            else
            {
                // TODO: Should we give a way to override how the id is generated?
                // TODO: Should we encrypt / hash the id so people can not just try out other values?
                id = Guid.NewGuid().ToString();
                ctx.Response.AddCookie(GetCookieName(), id);
            }

            IDictionary<string, object> items = new Dictionary<string, object>();
            foreach (var item in ctx.Request.Session)
            {
                items.Add(item.Key, item.Value);
            }

            store.Save(id, items);
        }
示例#30
0
        /// <summary>
        /// Adds the current response to the cache if required
        /// Only stores by Path and stores the response in a dictionary.
        /// Do not use this as an actual cache :-)
        /// </summary>
        /// <param name="context">Current context</param>
        public void SetCache(NancyContext context)
        {
            if (context.Response.StatusCode != HttpStatusCode.OK)
            {
                return;
            }

            object cacheSecondsObject;
            if (!context.Items.TryGetValue(ContextExtensions.OUTPUT_CACHE_TIME_KEY, out cacheSecondsObject))
            {
                return;
            }

            int cacheSeconds;
            if (!int.TryParse(cacheSecondsObject.ToString(), out cacheSeconds))
            {
                return;
            }

            var cachedResponse = new CachedResponse(context.Response);

            this.cachedResponses[context.Request.Path] = new Tuple<DateTime, Response, int>(DateTime.Now, cachedResponse, cacheSeconds);

            context.Response = cachedResponse;
        }
 /// <summary>
 /// Determines whether the processor can handle a given content type and model.
 /// </summary>
 /// <param name="requestedMediaRange">Content type requested by the client.</param>
 /// <param name="model">The model for the given media range.</param>
 /// <param name="context">The nancy context.</param>
 /// <returns>
 /// A <see cref="T:Nancy.Responses.Negotiation.ProcessorMatch" /> result that determines the priority of the processor.
 /// </returns>
 /// <exception cref="System.NotImplementedException"></exception>
 public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     // Tells Nancy that this processor can handle accept header values that end with "yaml"
     return(requestedMediaRange.Subtype.ToString().EndsWith("yaml")
         ? new ProcessorMatch {
         ModelResult = MatchResult.DontCare, RequestedContentTypeResult = MatchResult.NonExactMatch
     }
         : ProcessorMatch.None);
 }
 public CultureInfo DetermineCurrentCulture(NancyContext context)
 {
     return(System.Threading.Thread.CurrentThread.CurrentCulture);
 }
示例#33
0
 protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
 {
     base.ConfigureRequestContainer(container, context);
     //container.Register<IRequestUrl>((cContainer, overloads) => new RequestUrl(context));
     container.Register <NancyContext>((cContainer, overloads) => context);
     container.Register <IRequestUrl, RequestUrl>();
     container.Register <IGreeter, Greeter>();
     container.Register <IGreetingMessageService, GreetingMessageService>();
 }
示例#34
0
 public static void DisableOutputCache(this NancyContext context)
 {
     context.Items.Remove(OUTPUT_CACHE_TIME_KEY);
 }
示例#35
0
 /// <summary>
 /// Enable output caching for this route
 /// </summary>
 /// <param name="context">Current context</param>
 /// <param name="seconds">Seconds to cache for</param>
 public static void EnableOutputCache(this NancyContext context, int seconds)
 {
     context.Items[OUTPUT_CACHE_TIME_KEY] = seconds;
 }
示例#36
0
 private Response SetViewBagWithSettings(NancyContext arg)
 {
     ViewBag.Settings = AppConfiguration.Current;
     ViewBag.Pages    = BlogPosts.Where(p => p.Status == PostStatus.Publish && p.Type == PostType.Page).ToList();
     return(null);
 }
示例#37
0
 public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context)
 {
     throw new NotImplementedException();
 }
示例#38
0
 /// <summary>
 /// Initialise the request - can be used for adding pre/post hooks and
 /// any other per-request initialisation tasks that aren't specifically container setup
 /// related
 /// </summary>
 /// <param name="container">Container</param>
 /// <param name="pipelines">Current pipelines</param>
 /// <param name="context">Current context</param>
 protected virtual void RequestStartup(TContainer container, IPipelines pipelines, NancyContext context)
 {
 }
示例#39
0
 /// <summary>
 /// Get all NancyModule implementation instances
 /// </summary>
 /// <param name="context">The current context</param>
 /// <returns>An <see cref="IEnumerable{T}"/> instance containing <see cref="INancyModule"/> instances.</returns>
 public abstract IEnumerable <INancyModule> GetAllModules(NancyContext context);
示例#40
0
        // The bootstrapper enables you to reconfigure the composition of the framework,
        // by overriding the various methods and properties.
        // For more information https://github.com/NancyFx/Nancy/wiki/Bootstrapper

        protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
        {
            base.ConfigureRequestContainer(container, context);

            container.Register <ITeamRepository, TeamRepository>();
            container.Register <IMatchRepository, MatchRepository>();
        }
 public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
 {
     return(true);
 }
示例#42
0
 /// <summary>
 /// Retrieves a specific <see cref="INancyModule"/> implementation - should be per-request lifetime
 /// </summary>
 /// <param name="moduleType">Module type</param>
 /// <param name="context">The current context</param>
 /// <returns>The <see cref="INancyModule"/> instance</returns>
 public abstract INancyModule GetModule(Type moduleType, NancyContext context);
 public bool HandlesStatusCode(HttpStatusCode statusCode, NancyContext context)
 {
     return(statusCode == HttpStatusCode.NotFound);
 }
 public void Handle(HttpStatusCode statusCode, NancyContext context)
 {
     //I have nothing to add
 }
示例#45
0
        /// <summary>
        /// Determines whether the the processor can handle a given content type and model.
        /// </summary>
        /// <param name="requestedMediaRange">Content type requested by the client.</param>
        /// <param name="model">The model for the given media range.</param>
        /// <param name="context">The nancy context.</param>
        /// <returns>A <see cref="ProcessorMatch"/> result that determines the priority of the processor.</returns>
        public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
        {
            if (IsWildcardProtobufContentType(requestedMediaRange) || requestedMediaRange.Matches(Constants.ProtoBufContentType))
            {
                return(new ProcessorMatch
                {
                    ModelResult = MatchResult.DontCare,
                    RequestedContentTypeResult = MatchResult.ExactMatch
                });
            }

            return(new ProcessorMatch
            {
                ModelResult = MatchResult.DontCare,
                RequestedContentTypeResult = MatchResult.NoMatch
            });
        }
示例#46
0
        /// <summary>
        /// Log context and exception
        /// </summary>
        /// <param name="context"></param>
        /// <param name="exception"></param>
        public void LogData(NancyContext context, Exception exception)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var statusCode = context.GetStatusCode(exception);

            string exceptionMessage    = null;
            string exceptionStackTrace = null;

            if (exception != null)
            {
                exceptionMessage    = HandleFieldSize(exception.Message, ExceptionMaxLenghtExtension.ErrorMessageLenght);
                exceptionStackTrace = HandleFieldSize(exception.StackTrace, ExceptionMaxLenghtExtension.ErrorExceptionLenght);
            }

            object controller = "Unknow";
            object action     = "Unknow";

            if (context.Items != null)
            {
                context.Items.TryGetValue("Controller", out controller);
                context.Items.TryGetValue("Action", out action);
            }

            LogContext.PushProperty("RequestBody", context.GetRequestBody(this.NancySerilogConfiguration.Blacklist));
            LogContext.PushProperty("Method", context.Request.Method);
            LogContext.PushProperty("Path", context.Request.Path);
            LogContext.PushProperty("Host", context.Request.Url.HostName);
            LogContext.PushProperty("Port", context.Request.Url.Port);
            LogContext.PushProperty("Url", context.Request.Url);
            LogContext.PushProperty("QueryString", context.Request.Url.Query);
            LogContext.PushProperty("Query", context.GetQueryString());
            LogContext.PushProperty("RequestHeaders", context.GetRequestHeaders());
            LogContext.PushProperty("Ip", context.GetIp());
            LogContext.PushProperty("IsSuccessful", statusCode < 400);
            LogContext.PushProperty("StatusCode", statusCode);
            LogContext.PushProperty("StatusDescription", ((HttpStatusCode)statusCode).ToString());
            LogContext.PushProperty("StatusCodeFamily", context.GetStatusCodeFamily(exception));
            LogContext.PushProperty("ProtocolVersion", context.Request.ProtocolVersion);
            LogContext.PushProperty("ErrorException", exceptionStackTrace);
            LogContext.PushProperty("ErrorMessage", exceptionMessage);
            LogContext.PushProperty("ResponseContent", context.GetResponseContent());
            LogContext.PushProperty("ContentType", context.Response.ContentType);
            LogContext.PushProperty("ContentLength", context.GetResponseLength());
            LogContext.PushProperty("ResponseHeaders", context.GetResponseHeaders());
            LogContext.PushProperty("ElapsedMilliseconds", context.GetExecutionTime());
            LogContext.PushProperty("Version", this.NancySerilogConfiguration.Version);
            LogContext.PushProperty("RequestKey", context.GetRequestKey());
            LogContext.PushProperty("Controller", controller?.ToString());
            LogContext.PushProperty("Operation", action?.ToString());
            LogContext.PushProperty("Environment", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));

            if (context.Items.ContainsKey("NancySerilogAdditionalInfo"))
            {
                var additionalInfo = (AdditionalInfo)context.Items["NancySerilogAdditionalInfo"];

                if (additionalInfo?.Data != null)
                {
                    foreach (var item in additionalInfo.Data)
                    {
                        LogContext.PushProperty(item.Key, item.Value);
                    }
                }
            }



            if (exception != null || statusCode >= 500)
            {
                var errorTitle = this.NancySerilogConfiguration.ErrorTitle ?? DefaultErrorTitle;
                this.NancySerilogConfiguration.Logger.Error(errorTitle);
            }
            else
            {
                var informationTitle = this.NancySerilogConfiguration.InformationTitle ?? DefaultInformationTitle;
                this.NancySerilogConfiguration.Logger.Information(informationTitle);
            }
        }
示例#47
0
        protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context)
        {
            base.ConfigureRequestContainer(container, context);

            // Here we register our user mapper as a per-request singleton.
            // As this is now per-request we could inject a request scoped
            // database "context" or other request scoped services.
            container.Register <IUserMapper, UserDatabase>();
        }
示例#48
0
 /// <summary>
 /// Process the response.
 /// </summary>
 /// <param name="requestedMediaRange">Content type requested by the client.</param>
 /// <param name="model">The model for the given media range.</param>
 /// <param name="context">The nancy context.</param>
 /// <returns>A <see cref="Response"/> instance.</returns>
 public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     return(new ProtoBufResponse(model));
 }
    public void Handle(HttpStatusCode statusCode, NancyContext context)
    {
        var error = new { StatusCode = statusCode, Message = "Not Found" };

        context.Response = _negotiator.NegotiateResponse(error, context);
    }
示例#50
0
        protected override void RequestStartup(TinyIoCContainer requestContainer, IPipelines pipelines, NancyContext context)
        {
            // At request startup we modify the request pipelines to
            // include forms authentication - passing in our now request
            // scoped user name mapper.
            //
            // The pipelines passed in here are specific to this request,
            // so we can add/remove/update items in them as we please.
            var formsAuthConfiguration =
                new FormsAuthenticationConfiguration()
            {
                RedirectUrl = "~/login",
                UserMapper  = requestContainer.Resolve <IUserMapper>(),
            };

            FormsAuthentication.Enable(pipelines, formsAuthConfiguration);
        }
示例#51
0
        private static Func <ResponseFactoryCacheKey, Func <NancyContext, Response> > BuildContentDelegate(NancyContext context, string applicationRootPath, string requestedPath, string contentPath, string[] allowedExtensions)
        {
            return(pathAndRootPair =>
            {
                context.Trace.TraceLog.WriteLog(x => x.AppendLine(string.Concat("[StaticContentConventionBuilder] Attempting to resolve static content '", pathAndRootPair, "'")));

                var extension =
                    Path.GetExtension(pathAndRootPair.Path);

                if (!string.IsNullOrEmpty(extension))
                {
                    extension = extension.Substring(1);
                }

                if (allowedExtensions.Length != 0 && !allowedExtensions.Any(e => string.Equals(e.TrimStart(new [] { '.' }), extension, StringComparison.OrdinalIgnoreCase)))
                {
                    context.Trace.TraceLog.WriteLog(x => x.AppendLine(string.Concat("[StaticContentConventionBuilder] The requested extension '", extension, "' does not match any of the valid extensions for the convention '", string.Join(",", allowedExtensions), "'")));
                    return ctx => null;
                }

                var transformedRequestPath =
                    GetSafeRequestPath(pathAndRootPair.Path, requestedPath, contentPath);

                transformedRequestPath =
                    GetEncodedPath(transformedRequestPath);

                var fileName =
                    Path.GetFullPath(Path.Combine(applicationRootPath, transformedRequestPath));

                var contentRootPath =
                    Path.GetFullPath(Path.Combine(applicationRootPath, GetEncodedPath(contentPath)));

                if (!IsWithinContentFolder(contentRootPath, fileName))
                {
                    context.Trace.TraceLog.WriteLog(x => x.AppendLine(string.Concat("[StaticContentConventionBuilder] The request '", fileName, "' is trying to access a path outside the content folder '", contentPath, "'")));
                    return ctx => null;
                }

                if (!File.Exists(fileName))
                {
                    context.Trace.TraceLog.WriteLog(x => x.AppendLine(string.Concat("[StaticContentConventionBuilder] The requested file '", fileName, "' does not exist")));
                    return ctx => null;
                }

                context.Trace.TraceLog.WriteLog(x => x.AppendLine(string.Concat("[StaticContentConventionBuilder] Returning file '", fileName, "'")));
                return ctx => new GenericFileResponse(fileName, ctx);
            });
        }
示例#52
0
 protected override void RequestStartup(Nancy.TinyIoc.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines, NancyContext context)
 {
     base.RequestStartup(container, pipelines, context);
 }
示例#53
0
        protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
        {
            pipelines.OnError.AddItemToEndOfPipeline(
                (nancyContext, exception) =>
                new JsonResponse(
                    new
            {
                error = exception.Message
            },
                    new DefaultJsonSerializer()));

            base.RequestStartup(container, pipelines, context);
        }
示例#54
0
        protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
        {
            pipelines.BeforeRequest += (x) =>
            {
                return(null);
            };

            pipelines.AfterRequest += (x) =>
            {
                if (x.Request.Url.Path.ToLower() == "/api" || x.Request.Url.Path.ToLower() == "/doc")
                {
                    x.Response.WithContentType("application/pdf");
                }
                bool isView = false; //判断返回数据是否为 view text/html 否则  转换 application/json
                if (x.Response.Contents.Target.ToString() == "Nancy.Responses.MaterialisingResponse")
                {
                    var r = (Nancy.Responses.MaterialisingResponse)x.Response.Contents.Target;
                    if (r.ContentType == "text/html")
                    {
                        isView = true;
                    }
                }
                if (!isView)
                {
                    x.Response.WithContentType("application/json;charset=UTF-8");
                }
                x.Response.WithHeader("Access-Control-Allow-Origin", "*");
                x.Response.WithHeader("Access-Control-Allow-Methods", "GET");
            };

            pipelines.OnError += Error;

            base.RequestStartup(container, pipelines, context);
        }
 public ProcessorMatch CanProcess(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     return(new ProcessorMatch
     {
         RequestedContentTypeResult = MatchResult.DontCare,
         ModelResult = MatchResult.DontCare
     });
 }
示例#56
0
 /// <summary>
 /// Retrieves a specific <see cref="NancyModule"/> implementation based on its key
 /// </summary>
 /// <param name="moduleKey">Module key</param>
 /// <param name="context">The current context</param>
 /// <returns>The <see cref="NancyModule"/> instance that was retrived by the <paramref name="moduleKey"/> parameter.</returns>
 public abstract NancyModule GetModuleByKey(string moduleKey, NancyContext context);
示例#57
0
 /// <summary>
 /// 自定义请求启动函数
 /// </summary>
 /// <param name="container"></param>
 /// <param name="pipelines"></param>
 /// <param name="context"></param>
 protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
 {
     //CORS Enable
     pipelines.AfterRequest.AddItemToEndOfPipeline((ctx) =>
     {
         var originlist = ctx.Request.Headers["Origin"];
         foreach (var origin in originlist)
         {
             ctx.Response.WithHeader("Access-Control-Allow-Origin", origin);
         }
         ctx.Response.WithHeader("Access-Control-Allow-Methods", "POST,GET")
         .WithHeader("Access-Control-Allow-Credentials", "true")
         .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type");
     });
 }
 public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     return((string)model);
 }
示例#59
0
 public Response Process(MediaRange mediaRange, dynamic model, NancyContext context)
 => new JsonResponse((object)model, serializer, environment);
 public Response Process(MediaRange requestedMediaRange, dynamic model, NancyContext context)
 {
     return(string.Format(ResponseTemplate, requestedMediaRange, model == null ? "None" : model.GetType()));
 }