Example #1
0
        private MiddlerRuleMatch CheckMatch(IMiddlerOptions middlerOptions, MiddlerRule rule, MiddlerContext middlerContext)
        {
            var allowedHttpMethods = (rule.HttpMethods?.IgnoreNullOrWhiteSpace().Any() == true ? rule.HttpMethods.IgnoreNullOrWhiteSpace() : middlerOptions.DefaultHttpMethods).ToList();

            if (allowedHttpMethods.Any() && !allowedHttpMethods.Contains(middlerContext.Request.HttpMethod, StringComparer.OrdinalIgnoreCase))
            {
                return(null);
            }

            //var uri = new Uri(context.Request.GetEncodedUrl());

            var allowedSchemes = (rule.Scheme?.IgnoreNullOrWhiteSpace().Any() == true ? rule.Scheme.IgnoreNullOrWhiteSpace() : middlerOptions.DefaultScheme).ToList();

            if (allowedSchemes.Any() && !allowedSchemes.Any(scheme => Wildcard.Match(middlerContext.MiddlerRequestContext.Uri.Scheme, scheme)))
            {
                return(null);
            }

            if (!Wildcard.Match($"{middlerContext.MiddlerRequestContext.Uri.Host}:{middlerContext.MiddlerRequestContext.Uri.Port}", rule.Hostname ?? "*"))
            {
                return(null);
            }

            if (String.IsNullOrWhiteSpace(rule.Path))
            {
                rule.Path = "{**path}";
            }

            var parsedTemplate = TemplateParser.Parse(rule.Path);

            var defaults = parsedTemplate.Parameters.Where(p => p.DefaultValue != null)
                           .Aggregate(new RouteValueDictionary(), (current, next) =>
            {
                current.Add(next.Name, next.DefaultValue);
                return(current);
            });

            var matcher = new TemplateMatcher(parsedTemplate, defaults);
            var rd      = middlerContext.MiddlerRequestContext.GetRouteData();
            var router  = rd.Routers.FirstOrDefault() ?? new RouteCollection();

            if (matcher.TryMatch(middlerContext.MiddlerRequestContext.Uri.AbsolutePath, rd.Values))
            {
                var constraints = GetConstraints(middlerContext.RequestServices.GetRequiredService <IInlineConstraintResolver>(), parsedTemplate, null);
                if (MiddlerRouteConstraintMatcher.Match(constraints, rd.Values, router, RouteDirection.IncomingRequest, ConstraintLogger))
                {
                    middlerContext.SetRouteData(constraints);

                    return(new MiddlerRuleMatch
                    {
                        MiddlerRule = rule,
                        AccessMode = rule.AccessAllowed(middlerContext.Request) ?? middlerOptions.DefaultAccessMode
                    });
                }
            }

            return(null);
        }
Example #2
0
        //private FakeHttpContext FakeHttpContext { get; }
        public MiddlerContext(HttpContext httpContext, IMiddlerOptions middlerOptions)
        {
            HttpContext            = httpContext;
            MiddlerOptions         = middlerOptions;
            MiddlerRequestContext  = new MiddlerRequestContext(httpContext, middlerOptions);
            MiddlerResponseContext = new MiddlerResponseContext();

            MiddlerResponseContext.Body = new AutoStream(opts =>
                                                         opts
                                                         .WithMemoryThreshold(middlerOptions.AutoStreamDefaultMemoryThreshold)
                                                         .WithFilePrefix("middler"), Request.RequestAborted);
        }
        public MiddlerRequestContext(HttpContext httpContext, IMiddlerOptions middlerOptions)
        {
            HttpContext = httpContext;
            //Path = httpContext.Request.Path;
            Principal       = httpContext.User;
            SourceIPAddress = httpContext.Request.FindSourceIp().FirstOrDefault();
            ProxyServers    = httpContext.Request.FindSourceIp().Skip(1).ToList();
            Headers         = new SimpleDictionary <string>(httpContext.Request.GetHeaders());
            QueryParameters = new MiddlerRouteQueryParameters(httpContext.Request.GetQueryParameters());
            Uri             = new Uri(httpContext.Request.GetDisplayUrl());
            HttpMethod      = httpContext.Request.Method;
            ContentType     = httpContext.Request.ContentType;
            MiddlerOptions  = middlerOptions;

            Body = httpContext.Request.Body;
        }
Example #4
0
        private MiddlerRuleMatch FindMatchingEndpoint(IMiddlerOptions middlerOptions, List <MiddlerRule> rule, MiddlerContext middlerContext)
        {
            for (int i = 0; i < rule.Count; i++)
            {
                var match = CheckMatch(middlerOptions, rule[i], middlerContext);
                if (match != null)
                {
                    if (match.AccessMode != AccessMode.Ignore)
                    {
                        match.RemainingEndpointInfos = rule.Skip(i + 1).ToList();
                        return(match);
                    }
                }
            }

            return(null);
        }
Example #5
0
        public static IServiceCollection AddMiddler(this IServiceCollection services, IMiddlerOptions options)
        {
            services.AddSingleton <IMiddlerMap, MiddlerMap>();
            services.AddSingleton <IMiddlerOptions>(sp => options);
            services.AddTransient <InternalHelper>(sp => new InternalHelper(sp));
            services.AddTransient <IMiddlerMapActionsBuilder, MiddlerMapActionsBuilder>();

            return(services);
        }
Example #6
0
 public InternalHelper(IServiceProvider serviceProvider)
 {
     ServiceProvider = serviceProvider;
     MiddlerOptions  = serviceProvider.GetRequiredService <IMiddlerOptions>();
 }
Example #7
0
        public async Task InvokeAsync(HttpContext httpContext, IMiddlerOptions middlerOptions, InternalHelper intHelper)
        {
            var sw = new Stopwatch();

            sw.Start();
            EnsureLoggers(httpContext);
            //Stream originalBody = null;

            var middlerMap = httpContext.RequestServices.GetRequiredService <IMiddlerMap>();


            var endpoints = middlerMap.GetFlatList(httpContext.RequestServices);

            var executedActions = new Stack <IMiddlerAction>();

            var middlerContext = new MiddlerContext(httpContext, middlerOptions);

            //var first = true;
            try
            {
                bool terminating;
                do
                {
                    var matchingEndpoint = FindMatchingEndpoint(middlerOptions, endpoints, middlerContext);

                    if (matchingEndpoint == null)
                    {
                        //await _next(httpContext).ConfigureAwait(false);
                        break;
                    }

                    if (matchingEndpoint.AccessMode == AccessMode.Deny)
                    {
                        await httpContext.Forbid().ConfigureAwait(false);

                        return;
                    }

                    //middlerContext.Features.Set(matchingEndpoint);

                    endpoints = matchingEndpoint.RemainingEndpointInfos;

                    //var interMediateStreamNeeded = matchingEndpoint.MiddlerRule.Actions.Any(a => !a.WriteStreamDirect);
                    //if (interMediateStreamNeeded)
                    //{
                    //    originalBody ??= httpContext.Response.Body;
                    //    httpContext.Response.Body = new AutoStream(opts =>
                    //        opts
                    //            .WithMemoryThreshold(middlerOptions.AutoStreamDefaultMemoryThreshold)
                    //            .WithFilePrefix("middler"), middlerContext.Request.RequestAborted);

                    //}



                    terminating = false;
                    foreach (var endpointAction in matchingEndpoint.MiddlerRule.Actions)
                    {
                        if (!endpointAction.Enabled)
                        {
                            continue;
                        }
                        //if (!first)
                        //{
                        //    middlerContext.PrepareNext();
                        //}
                        var action = intHelper.BuildConcreteActionInstance(endpointAction);
                        if (action != null)
                        {
                            await ExecuteRequestAction(action, middlerContext);

                            executedActions.Push(action);
                            terminating = action.Terminating;
                            //first = false;
                        }

                        if (terminating)
                        {
                            break;
                        }
                    }
                } while (!terminating);


                if (executedActions.Any())
                {
                    while (executedActions.TryPop(out var executedAction))
                    {
                        await ExecuteResponseAction(executedAction, middlerContext);
                    }

                    //httpContext.Response.Body = middlerContext.MiddlerResponseContext.Body;

                    await WriteToAspNetCoreResponseBodyAsync(httpContext, middlerContext).ConfigureAwait(false);
                }
                else
                {
                    await _next(httpContext);
                }
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, ex.Message);
                throw;
            }
        }