﻿namespace Tanka.Web.Infrastructure
{
    using System;
    using System.Linq;
    using global::Nancy;
    using global::Nancy.Responses;

    public static class AppHarborCompatibilityExtensions
    {
        public static void RequiresHttpsOrXProto(this INancyModule module, bool redirect = true)
        {
            module.Before.AddItemToEndOfPipeline(RequiresHttpsOrXForwardedProto(redirect));
        }

        private static Func<NancyContext, Response> RequiresHttpsOrXForwardedProto(bool redirect)
        {
            return ctx =>
            {
                Response response = null;
                Request request = ctx.Request;

                string scheme = request.Headers["X-Forwarded-Proto"].SingleOrDefault();

                if (!IsSecure(scheme, request.Url))
                {
                    if (redirect && request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))
                    {
                        Url redirectUrl = request.Url.Clone();
                        redirectUrl.Scheme = "https";
                        redirectUrl.Port = 443;
                        response = new RedirectResponse(redirectUrl.ToString());
                    }
                    else
                    {
                        response = new Response {StatusCode = HttpStatusCode.Forbidden};
                    }
                }

                return response;
            };
        }

        private static bool IsSecure(string scheme, Url url)
        {
            if (scheme == "https")
                return true;

            return url.IsSecure;
        }
    }
}
﻿namespace Tanka.Web.Infrastructure
{
    using System;
    using System.Linq;
    using global::Nancy;
    using global::Nancy.Responses;

    public static class AppHarborCompatibilityExtensions
    {
        public static void RequiresHttpsOrXProto(this INancyModule module, bool redirect = true)
        {
            module.Before.AddItemToEndOfPipeline(RequiresHttpsOrXForwardedProto(redirect));
        }

        private static Func<NancyContext, Response> RequiresHttpsOrXForwardedProto(bool redirect)
        {
            return ctx =>
            {
                Response response = null;
                Request request = ctx.Request;

                

                if (!IsSecure(request))
                {
                    if (redirect && request.Method.Equals("GET", StringComparison.OrdinalIgnoreCase))
                    {
                        Url redirectUrl = request.Url.Clone();
                        redirectUrl.Scheme = "https";
                        redirectUrl.Port = 443;
                        response = new RedirectResponse(redirectUrl.ToString());
                    }
                    else
                    {
                        response = new Response {StatusCode = HttpStatusCode.Forbidden};
                    }
                }

                return response;
            };
        }

        private static bool IsSecure(Request request)
        {
            if (request.Headers.Keys.Contains("X-Forwarded-Proto"))
            {
                var scheme = request.Headers["X-Forwarded-Proto"].FirstOrDefault();
                
                if (!string.IsNullOrWhiteSpace(scheme) && scheme == "https")
                    return true;
            }

            return request.Url.IsSecure;
        }
    }
}
Fix issue with checking header value
bugfix: Fix issue with checking header value

Fix the issue and handle the case of missing header value
