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"]);
        }
        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);
        }
        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);
        }
 private static void AddNegotiatedHeaders(Negotiator negotiator, Response response)
 {
     foreach (var header in negotiator.NegotiationContext.Headers)
     {
         response.Headers[header.Key] = header.Value;
     }
 }
        private static Response CreateNegotiatedResponse(NancyContext context, IResponseNegotiator responseNegotiator, Exception exception)
        {
            HttpServiceError httpServiceError = HttpServiceErrorUtilities.ExtractFromException(exception, HttpServiceErrorDefinition.GeneralError);

            Negotiator negotiator = new Negotiator(context)
                .WithHttpServiceError(httpServiceError);

            return responseNegotiator.NegotiateResponse(negotiator, context);
        }
        private static Response CreateNegotiatedResponse(NancyContext context, IResponseNegotiator responseNegotiator, Exception exception, HttpServiceError defaultError)
        {
            HttpServiceError httpServiceError = ExtractFromException(exception, defaultError);

            Negotiator negotiator = new Negotiator(context)
                .WithServiceError(httpServiceError);

            return responseNegotiator.NegotiateResponse(negotiator, context);
        }
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            context.NegotiationContext = new NegotiationContext();

            Negotiator negotiator = new Negotiator(context)
                .WithHttpServiceError(HttpServiceErrorDefinition.InternalServerError);

            context.Response = responseNegotiator.NegotiateResponse(negotiator, context);
        }
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            context.NegotiationContext = new NegotiationContext();

            Negotiator negotiator = new Negotiator(context)
                .WithServiceError(new NotFoundError(context.Request.Path));

            context.Response = responseNegotiator.NegotiateResponse(negotiator, context);
        }
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            context.NegotiationContext = new NegotiationContext();

            Negotiator negotiator = new Negotiator(context)
                .WithStatusCode(HttpServiceErrorDefinition.NotFoundError.HttpStatusCode)
                .WithModel(HttpServiceErrorDefinition.NotFoundError.ServiceErrorModel);

            context.Response = responseNegotiator.NegotiateResponse(negotiator, context);
        }
        private Response DefaultError(NancyContext ctx)
        {
            var defaultErrorRepresentation = new ErrorRepresentation(HttpStatusCode.InternalServerError, DefaultErrorCode);

            defaultErrorRepresentation.Message = DefaultErrorMessage;

            var negotiator = new Negotiator(ctx).WithStatusCode(HttpStatusCode.InternalServerError).WithModel(defaultErrorRepresentation);

            return responseNegotiator.NegotiateResponse(negotiator, ctx);
        }
        /// <summary>
        /// Gets a <see cref="NegotiationContext"/> 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="NegotiationContext"/>.</returns>
        private static NegotiationContext GetNegotiationContext(object routeResult, NancyContext context)
        {
            var negotiator = routeResult as Negotiator;

            if (negotiator == null)
            {
                context.WriteTraceLog(sb =>
                                      sb.AppendFormat("[DefaultResponseNegotiator] Wrapping result of type {0} in negotiator\n", routeResult.GetType()));

                negotiator = new Negotiator(context).WithModel(routeResult);
            }

            return(negotiator.NegotiationContext);
        }
        private Response Error(Exception rootException, NancyContext ctx)
        {
            var errorMapping = errorMap[rootException.GetType()];

            var errorRepresentation = errorMapping.Representation;

            if (string.IsNullOrEmpty(errorRepresentation.Message))
            {
                errorRepresentation.Message = rootException.Message;
            }

            var negotiator = new Negotiator(ctx).WithStatusCode(errorMapping.HttpStatusCode).WithModel(errorRepresentation);

            return responseNegotiator.NegotiateResponse(negotiator, ctx);
        }
Exemple #13
0
        public static Response HandleException(NancyContext ctx, Exception ex, IResponseNegotiator responder)
        {
            LogException(ctx, ex);

            // Return AjaxError JSON if the client was making an AJAX request. Otherwise show an error page.
            var negotiator = new Negotiator(ctx);
            negotiator = negotiator.WithStatusCode(HttpStatusCode.InternalServerError)
                // Use this model as a JSON response if the client asked for application/json
                .WithMediaRangeModel("application/json", new AjaxError(AjaxError.InternalError, "Sorry, something went wrong when processing your request."))

                // Use this model as the model for the view if anything other than JSON
                .WithModel(new ErrorViewModel(ex))
                // Use this view for text/html
                .WithView("Error");
            return responder.NegotiateResponse(negotiator, ctx);
        }
        public void Handle(HttpStatusCode statusCode, NancyContext context)
        {
            var response = new Negotiator(context);

            Error error = null;
            if (context.Items.ContainsKey("OnErrorException"))
            {
                var exception = context.Items["OnErrorException"] as Exception;
                error = new Error { ErrorMessage = exception.Message, FullException = exception.ToString() };
            }

            response.WithModel(new ErrorPageViewModel
                {
                    Title = "Sorry, something went wrong",
                    Summary = error == null ? "An unexpected error occurred." : error.ErrorMessage,
                    Details = error == null ? null : error.FullException // TODO: Obey "ShowFullErrors" flag in config
                }).WithStatusCode(statusCode).WithView("Error");

            var errorresponse = responseNegotiator.NegotiateResponse(response, context);
            string s = "";
            context.Response = errorresponse;
        }
        public void Should_set_reason_phrase_on_response()
        {
            // Given
            var module = new ConfigurableNancyModule(with =>
            {
                with.Get("/customPhrase", (x, m) =>
                {
                    var context =
                        new NancyContext();

                    var negotiator =
                        new Negotiator(context);
                    negotiator.WithReasonPhrase("The test is passing!").WithStatusCode(404);

                    return negotiator;
                });
            });

            var browser = new Browser(with =>
            {
                with.StatusCodeHandler<DefaultStatusCodeHandler>();
                with.ResponseProcessor<TestProcessor>();
                with.Module(module);
            });

            // When
            var response = browser.Get("/customPhrase", with => with.Accept("application/json"));

            // Then
            Assert.Equal("The test is passing!", response.ReasonPhrase);
        }
        private Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>[] GetCompatibleHeaders(NancyContext context, Negotiator negotiator)
        {
            var coercedAcceptHeaders = this.GetCoercedAcceptHeaders(context).ToArray();

            List<Tuple<string, decimal>> acceptHeaders;

            var permissableMediaRanges = negotiator.NegotiationContext.PermissableMediaRanges;

            if (permissableMediaRanges.Any(mr => mr.IsWildcard))
            {
                acceptHeaders = coercedAcceptHeaders
                    .Where(header => header.Item2 > 0m)
                    .ToList();
            }
            else
            {
                acceptHeaders = coercedAcceptHeaders.Where(header => header.Item2 > 0m)
                    .SelectMany(header => permissableMediaRanges.Where(mr => mr.Matches(header.Item1)).Select(mr => Tuple.Create(mr.ToString(), header.Item2)))
                    .ToList();
            }

            return (from header in acceptHeaders
                    let compatibleProcessors = (IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>)GetCompatibleProcessorsByHeader(header.Item1, negotiator.NegotiationContext.GetModelForMediaRange(header.Item1), context)
                    where compatibleProcessors != null
                    select new Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>(
                        header.Item1,
                        compatibleProcessors
                    )).ToArray();
        }
        private static Response NegotiateResponse(IEnumerable<Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>> compatibleHeaders, object model, Negotiator negotiator, NancyContext context)
        {
            foreach (var compatibleHeader in compatibleHeaders)
            {
                var prioritizedProcessors = compatibleHeader.Item2
                    .OrderByDescending(x => x.Item2.ModelResult)
                    .ThenByDescending(x => x.Item2.RequestedContentTypeResult);

                foreach (var prioritizedProcessor in prioritizedProcessors)
                {
                    var processorType = prioritizedProcessor.Item1.GetType();
                    context.WriteTraceLog(sb => sb.AppendFormat("[DefaultRouteInvoker] Invoking processor: {0}\n", processorType));

                    var response =
                        SafeInvokeResponseProcessor(prioritizedProcessor.Item1, compatibleHeader.Item1, negotiator.NegotiationContext.GetModelForMediaRange(compatibleHeader.Item1), context);

                    if (response != null)
                    {
                        return response;
                    }
                }
            }

            return null;
        }
        private static Negotiator GetNegotiator(object routeResult, NancyContext context)
        {
            var negotiator = routeResult as Negotiator;

            if (negotiator == null)
            {
                context.WriteTraceLog(sb => sb.AppendFormat("[DefaultRouteInvoker] Wrapping result of type {0} in negotiator\n", routeResult.GetType()));

                negotiator = new Negotiator(context);
                negotiator.WithModel(routeResult);
            }

            return negotiator;
        }
        private static Func<dynamic, NancyModule, dynamic> CreateNegotiatedResponse(Action<Negotiator> action = null)
        {
            return (parameters, module) =>
                {
                    var negotiator = new Negotiator(module.Context);

                    if (action != null)
                    {
                        action.Invoke(negotiator);
                    }

                    return negotiator;
                };
        }
        public void Should_set_reason_phrase_on_response()
        {
            // Given
            var module = new ConfigurableNancyModule(with =>
            {
                with.Get("/customPhrase", (x, m) =>
                {
                    var context =
                        new NancyContext();

                    var negotiator =
                        new Negotiator(context);
                    negotiator.WithReasonPhrase("The test is passing!");

                    return negotiator;
                });
            });

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

                with.Module(module);
            });

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

            // Then
            Assert.Equal("The test is passing!", response.ReasonPhrase);
        }
        public void Should_override_with_extension()
        {
            // Given
            var browser = new Browser(with =>
            {
                with.ResponseProcessor<TestProcessor>();

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

                        var negotiator =
                            new Negotiator(context);

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

            // When
            var response = browser.Get("/test.foo", with =>
            {
                with.Header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4");
                with.Accept("application/xml", 0.9m);
                with.Accept("text/html", 0.9m);
            });

            // Then
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.True(response.Body.AsString().Contains("foo/bar"), "Media type mismatch");
        }
        public void Should_boost_html_priority_if_set_to_the_same_priority_as_others()
        {
            // 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);

                        negotiator.WithAllowedMediaRange("application/xml");
                        negotiator.WithAllowedMediaRange("text/html");

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

            // When
            var response = browser.Get("/", with =>
            {
                with.Header("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; ru-RU) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4");
                with.Accept("application/xml", 0.9m);
                with.Accept("text/html", 0.9m);
            });

            // Then
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.True(response.Body.AsString().Contains("text/html"), "Media type mismatch");
        }
        private static Func<dynamic, dynamic> CreateNegotiatedResponse(Action<Negotiator> action = null)
        {
            var context =
                new NancyContext { NegotiationContext = new NegotiationContext() };

            var negotiator =
                new Negotiator(context);

            if (action != null)
            {
                action.Invoke(negotiator);
            }

            return parameters => negotiator;
        }
        private Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>[] GetCompatibleHeaders(IEnumerable<Tuple<string, decimal>> coercedAcceptHeaders, NancyContext context, Negotiator negotiator)
        {
            List<Tuple<string, decimal>> acceptHeaders;

            var permissableMediaRanges = negotiator.NegotiationContext.PermissableMediaRanges;

            if (permissableMediaRanges.Any(mr => mr.IsWildcard))
            {
                acceptHeaders = coercedAcceptHeaders
                    .Where(header => header.Item2 > 0m)
                    .ToList();
            }
            else
            {
                acceptHeaders = coercedAcceptHeaders.Where(header => header.Item2 > 0m)
                    .SelectMany(header => permissableMediaRanges.Where(mr => mr.Matches(header.Item1)).Select(mr => Tuple.Create(mr.ToString(), header.Item2)))
                    .ToList();
            }

            return this.GetCompatibleProcessors(acceptHeaders, negotiator, context).ToArray();
        }
        public void Should_ignore_stupid_browsers_that_ask_for_xml()
        {
            // 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);

                        negotiator.WithAllowedMediaRange("application/xml");
                        negotiator.WithAllowedMediaRange("text/html");

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

            // When
            var response = browser.Get("/", with =>
            {
                with.Header("User-Agent", "Mozilla/5.0 (Windows; U; MSIE 7.0; Windows NT 6.0; en-US)");
                with.Accept("application/xml", 1.0m);
                with.Accept("application/xhtml+xml", 1.0m);
                with.Accept("*/*", 0.9m);
            });

            // Then
            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
            Assert.True(response.Body.AsString().Contains("text/html"), "Media type mismatch");
        }
Exemple #26
0
 private static void CheckForContentTypeHeader(Negotiator negotiator, Response response)
 {
     if (negotiator.NegotiationContext.Headers.ContainsKey("Content-Type"))
       {
     response.ContentType = negotiator.NegotiationContext.Headers["Content-Type"];
     negotiator.NegotiationContext.Headers.Remove("Content-Type");
       }
 }
        private IEnumerable<Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>> GetCompatibleProcessors(IEnumerable<Tuple<string, decimal>> acceptHeaders, Negotiator negotiator, NancyContext context)
        {
            foreach (var header in acceptHeaders)
            {
                var compatibleProcessors = (IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>)this.GetCompatibleProcessorsByHeader(
                    header.Item1, negotiator.NegotiationContext.GetModelForMediaRange(header.Item1), context);

                if (compatibleProcessors.Any())
                {
                    yield return new Tuple<string, IEnumerable<Tuple<IResponseProcessor, ProcessorMatch>>>(
                        header.Item1,
                        compatibleProcessors
                    );
                }
            }
        }