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); }
//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; }
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); }
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); }
public InternalHelper(IServiceProvider serviceProvider) { ServiceProvider = serviceProvider; MiddlerOptions = serviceProvider.GetRequiredService <IMiddlerOptions>(); }
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; } }