Example #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="SslRedirectContext"/> class.
 /// </summary>
 /// <param name="context">The HTTP-specific information about the request.</param>
 /// <param name="options">The options for the current request.</param>
 public SslRedirectContext(HttpContext context, SslRedirectOptions options)
 {
     HttpContext = context;
     Options     = options.Clone();
     _fwh        = new Lazy <ForwardedHeader>(() => ForwardedHeader.FromHttpContext(context));
 }
Example #2
0
        /// <summary>
        /// Constructs a <see cref="ForwardedHeader"/> object from a <see cref="HttpContext"/>.
        /// </summary>
        /// <param name="context">The context to parse.</param>
        /// <returns>The constructed <see cref="ForwardedHeader"/> object or <see langword="null"/>.</returns>
        public static ForwardedHeader FromHttpContext(HttpContext context)
        {
            var headers = context?.Request.Headers ??
                          throw new ArgumentNullException(nameof(context));

            ForwardedHeader result = null;

            ForwardedHeader header()
            {
                if (result == null)
                {
                    result = new ForwardedHeader();
                }
                return(result);
            }

            foreach (var pair in _xProtocolHeaders)
            {
                if (headers.ContainsKey(pair.Key))
                {
                    header().Protocol =
                        pair.Value.Equals(headers[pair.Key], StringComparison.OrdinalIgnoreCase) ?
                        ProtocolType.Https : ProtocolType.Http;
                }
            }

            if (headers.TryGetValue(HeaderNames.ForwardedFor, out var @for))
            {
                header().For = @for
                               .SelectMany(f => f.Split(new[] { ',' }, RemoveEmptyEntries))
                               .Select(f => f.Trim())
                               .ToArray();
            }
            else if (headers.TryGetValue(HeaderNames.ProxyUserIp, out var @ip))
            {
                header().For = @ip;
            }

            if (headers.TryGetValue(HeaderNames.ForwardedHost, out var host))
            {
                header().Host = host;
            }

            if (headers.TryGetValue(HeaderNames.ForwardedPort, out var pv))
            {
                if (Int32.TryParse(pv, out var port))
                {
                    header().Port = port;
                }
            }

            // https://tools.ietf.org/html/rfc7239
            if (headers.TryGetValue(HeaderNames.Forwarded, out var fw))
            {
                var values = fw
                             .SelectMany(f => f.Split(new[] { ';', ',' }, RemoveEmptyEntries))
                             .Select(f => f.Split(new[] { '=' }, RemoveEmptyEntries))
                             .Where(f => f.Length == 2)
                             .ToLookup(f => f[0].Trim().ToUpperInvariant(), f => f[1].Trim());

                if (values.Contains("PROTO"))
                {
                    header().Protocol = values["PROTO"].Last().Equals("https", StringComparison.OrdinalIgnoreCase) ?
                                        ProtocolType.Https : ProtocolType.Http;
                }

                if (values.Contains("FOR"))
                {
                    header().For = values["FOR"].ToArray();
                }

                if (values.Contains("HOST"))
                {
                    header().Host = values["HOST"].Last();
                }

                if (values.Contains("BY"))
                {
                    header().By = values["BY"].Last();
                }
            }

            return(result);
        }