Giter Club home page Giter Club logo

basicmiddleware's Introduction

ASP.NET Core Basic Middleware Components [Archived]

This GitHub project has been archived. Ongoing development on this project can be found in https://github.com/aspnet/AspNetCore.

This repo hosts a collection of basic middleware components for ASP.NET Core. This includes Buffering, HTTP Overrides, Response Compression, and URL Rewriting. The Rewrite middleware can import rules from IIS's UrlRewrite and Apache's mod_rewrite.

This project is part of ASP.NET Core. You can find samples, documentation and getting started instructions for ASP.NET Core at the AspNetCore repo.

basicmiddleware's People

Contributors

ajaybhargavb avatar andrewslavin avatar aspnetci avatar brennanconroy avatar david-peden-q2 avatar davidfowl avatar davidpeden3 avatar dougbu avatar eilon avatar halter73 avatar hishamco avatar javiercn avatar jkotalik avatar juntaoluo avatar kichalla avatar melnikov77 avatar mikaelm12 avatar mikeharder avatar moander avatar muratg avatar natemcmaster avatar nbarbettini avatar ntaylormullen avatar pakrym avatar pranavkm avatar rjmooney avatar ryanbrandenburg avatar sebastianc avatar tratcher avatar tthiery avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

basicmiddleware's Issues

IIS Rewrite Comprehensive Verification

IIS Url Rewrite has been implemented and is going through code review. We need heavy verification of all rules that can be provided. This can be done through scraping github for rules and seeing if we properly parse and apply the rules.

Url Rewrite Checklist

Features implemented in Url Rewrite:

Elements/Attributes in rules:

  • Rules
  • Name
  • Enabled
  • PatternSyntax ECMAScript
  • ExactMatch
  • StopProcessing
  • Matches
  • Conditions: MatchAll
  • Conditions: MatchAny
  • TrackAllCaptures
  • IsFile
  • IsDirectory
  • IgnoreCase
  • Negate
  • Action:Rewrite
  • Action:Redirect
  • AppendQueryString
  • RedirectType
  • Action:AbortRequest

Server Variables (common ones supported for now, TODO on complete list)

Features that are not implemented in UrlRewrite:

  • Global Rules
  • Outbound Rules
  • RewriteMaps
  • Custom Server Variables

Elements/Attributes in rules:

  • WildCard
  • ServerVariables
  • Action:CustomResponse
  • LogRewrittenUrl

Url Rewrite - No distinction between global and regular rules.

Currently global rules are treated like normal rules, while rather they should be treated to operate on both the path and path base (AFAIK).
Global rules:

– Rules in this collection can be defined only on the server level. Global rules are used to define server-wide URL rewriting logic. These rules are defined within the ApplicationHost.config file, and they cannot be overridden or disabled on any lower configuration levels. Global rules always operate on the absolute URL's path (that is, the requested URI without the server name). These rules are evaluated early in the IIS request-processing pipeline (PreBeginRequest event).

Support mime-type wildcards

In IIS a dev can specify wildcard mime types when checking if it should compress the response. Right now the middleware can only do exact matches. It would be much simpler if devs could specify wildcards.

Note in IIS it can opt in or out with wildcards, and override with specific values. E.g. text/* can be enabled and text/foo can be disabled. Most specific match wins.

RE:
https://www.iis.net/configreference/system.webserver/httpcompression/dynamictypes
IIS/Express Defaults:

<httpCompression
      directory="%SystemDrive%\inetpub\temp\IIS Temporary Compressed Files">
   <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll" />
   <dynamicTypes>
      <add mimeType="text/*" enabled="true" />
      <add mimeType="message/*" enabled="true" />
      <add mimeType="application/javascript" enabled="true" />
      <add mimeType="*/*" enabled="false" />
   </dynamicTypes>
   <staticTypes>
      <add mimeType="text/*" enabled="true" />
      <add mimeType="message/*" enabled="true" />
      <add mimeType="application/javascript" enabled="true" />
      <add mimeType="*/*" enabled="false" />
   </staticTypes>
</httpCompression>

Request.IsHttps doesn't seem to like Azure + x-forwarded-*

I'm running the following code on the official RC2 in an Azure WebApp.

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Http;

namespace WebApplication2
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        public IConfigurationRoot Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.All
            });

            app.UseHttpMethodOverride();

            app.Use(async (context, next) =>
            {
                foreach (var header in context.Request.Headers)
                {
                    if (header.Key.StartsWith("x-f", StringComparison.OrdinalIgnoreCase))
                    await context.Response.WriteAsync($"{header.Key}: {header.Value}\r\n");
                }

                await context.Response.WriteAsync($"Method: {context.Request.Method}\r\n");
                await context.Response.WriteAsync($"Scheme: {context.Request.Scheme}\r\n");
                await context.Response.WriteAsync($"IsHttps: {context.Request.IsHttps}\r\n");

                await context.Response.WriteAsync("Hello World - " + DateTimeOffset.Now + Environment.NewLine);
                await context.Response.WriteAsync(Environment.NewLine);

                await context.Response.WriteAsync("Address:" + Environment.NewLine);
                await context.Response.WriteAsync("Host: " + context.Request.Headers["Host"] + Environment.NewLine);
                await context.Response.WriteAsync("PathBase: " + context.Request.PathBase.Value + Environment.NewLine);
                await context.Response.WriteAsync("Query: " + context.Request.QueryString.Value + Environment.NewLine);
                await context.Response.WriteAsync(Environment.NewLine);

                await context.Response.WriteAsync("Connection:" + Environment.NewLine);
                await context.Response.WriteAsync("RemoteIp: " + context.Connection.RemoteIpAddress + Environment.NewLine);
                await context.Response.WriteAsync("RemotePort: " + context.Connection.RemotePort + Environment.NewLine);
                await context.Response.WriteAsync("LocalIp: " + context.Connection.LocalIpAddress + Environment.NewLine);
                await context.Response.WriteAsync("LocalPort: " + context.Connection.LocalPort + Environment.NewLine);
                await context.Response.WriteAsync("ClientCert: " + context.Connection.ClientCertificate + Environment.NewLine);
                await context.Response.WriteAsync(Environment.NewLine);
            });
        }
    }
}

When issueing a request over http, the following is displayed

X-Forwarded-For: 78.192.yyy.xx:58475, 78.192.yyy.xx:58475
X-Forwarded-Proto: http
Method: GET
Scheme: http
IsHttps: False
Hello World - 5/29/2016 7:06:38 PM +00:00

Address:
Host: zzzzzzz.azurewebsites.net
PathBase: 
Query: ?

Connection:
RemoteIp: 127.0.0.1
RemotePort: 50068
LocalIp: 127.0.0.1
LocalPort: 11850
ClientCert: 

When issueing a request over https, the following is displayed

X-Forwarded-For: 78.192.yyy.xx:58531, 78.192.yyy.xx:58531
X-Forwarded-Proto: https
Method: GET
Scheme: http
**IsHttps: False**
RemoteIP: 127.0.0.1
RemotePort: 50132
Hello World - 5/29/2016 7:10:27 PM +00:00

Address:
Host: zzzzzzz.azurewebsites.net
PathBase: 
Query: ?

Connection:
RemoteIp: 127.0.0.1
RemotePort: 50132
LocalIp: 127.0.0.1
LocalPort: 11850
ClientCert: 

I must certainly be missing something obvious, but I can't see it. Any help would be greatly appreciated.

Change Logging for Header mismatch

@Tratcher
Here a Debug Log is issued when header symmetry fails (there are other examples in this class)

https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.HttpOverrides/ForwardedHeadersMiddleware.cs#L80

The code considers the headers untrusted and returns without setting

request.Scheme = currentValues.Scheme;

The result is a redirect loop when

[HttpsRequired]

and

X-Forwarded-For count != X-Forwarded-Proto count

This is a common scenario for

This situation is not very discoverable and can leave one scratching your head.
Why am I getting a re-direct loop?

Microsoft default LogLevel is Information , so if you look in the logs there is no indication of what actually went wrong aside from a log full of redirects.
Its also a situation which doesn't recover (browser gives up).

At the very least can we change these header checks to _logger.LogError?

Is it a candidate for raising an exception?

X-Forwarded-Proto doesn't handle multiple values

Came across this via aspnet/KestrelHttpServer#365 (comment) and I'm glad to see it in the core this round. There's a bug I see though:

Both of these should support comma-separated values. For example if you have an edge node in europe that's HTTPS but then HTTP back to the origin (the load balancer adding a second entry) and then to the app, you'll get:

X-Forwarded-Proto: http, https

Or if it's HTTPS at both hops (yay security!):

X-Forwarded-Proto: https, https

While it doesn't answer the complicated question of what the app should get in complicated scenarios (this will definitely vary with such setups), it needs to not at least not break by default. I think using the 0-th entry is correct in both cases for the basic middleware use case.

Default middleware for request validation, like IIS has

Remember this?

<configuration>
   <system.web>
      <pages validateRequest="true" />
   </system.web>
</configuration>

http://www.asp.net/whitepapers/request-validation

The awesome thing about IIS ASP.NET websites is that they prevented html/script injections AS A DEFAULT!

In .NET Core, it isn't even possible.

I think there should be a middleware that does validation on posted form values, http headers, etc.

Maybe some of the Microsoft employees here can ping the IIS team for the code ;)

Verify Rewrite middleware for release

  • Verify different flavors
    • Mod rewrite
    • URL rewrite
    • Code based
  • Missing functionality, and recommendations on adding any of those
  • API surface
  • Test coverage
  • Etc.

Fix NuGet package descriptions

https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Rewrite/project.json

  • Was: ASP.NET Core basic middleware for:\r\nRewrite Url module.
  • Change to: ASP.NET Core basic middleware for rewriting URLs. Includes:\r\n* Support for custom URL rewrite rules\r\m* Support for running IIS URL Rewrite module rules\r\n* Support for running Apache mod_rewrite rules. (feel free to massage this a bit if it's not exactly right)

https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Buffering/project.json

  • Was: ASP.NET Core middleware for buffering response bodies.
  • No change.

https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.HttpOverrides/project.json

  • Was: ASP.NET Core basic middleware for:\r\nX-Forwarded-* headers to forward headers from a proxy.\r\nHTTP method override header.
  • Change to: ASP.NET Core basic middleware for supporting HTTP method overrides. Includes:\r\nX-Forwarded-* headers to forward headers from a proxy.\r\nHTTP method override header.

https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.ResponseCompression/project.json

  • Was: ASP.NET Core middleware for HTTP Response compression.
  • No change.

Mod Rewrite Comprehensive Verification

Mod Url Rewrite has been implemented. We need heavy verification of all rules that can be provided. This can be done through scraping github for rules and seeing if we properly parse and apply the rules.

Add Support for the AbortRequest action in Url Rewrite

An AbortRequest action causes the URL Rewrite Module to drop the HTTP connection for the current request. The action does not have any parameters. Use of this action implies that no subsequent rules are evaluated for the current URL after this action is performed.

DisableResponseBuffering does not work as expected in ResponseCompression

Writes would not flush automatically in the following code.

 app.Map("/slownb", a =>
            {
                a.UseResponseCompression();
                a.Run(async w =>
                {
                    w.Response.Headers["Content-Type"] = "text/html";

                    var nb = w.Features.Get<IHttpBufferingFeature>();
                    nb.DisableResponseBuffering();

                    while (!w.RequestAborted.IsCancellationRequested)
                    {
                        await w.Response.WriteAsync("1");
                        await Task.Delay(TimeSpan.FromSeconds(0.1));
                    }
                });
            });

@Tratcher

Consider adding a 'correlationId' middleware

From @rynowak on February 24, 2016 23:3

It's a common pattern (like WCF activity ID) to create a correlation id and use it across multiple services with logging. This way if your logs all go to the same store you can associate all of the business processes across service/server boundaries that are part of the same unit of work.

  1. Front-end server creates a correlation ID and creates a log scope
  2. Front-end server stashes the correlation ID in a way that some other code can get it (http context extension?)
  3. Front-end server makes a call to another service - propagates the ID by taking it out of http context and passing it via a header (http client)
  4. Back-end server reads the header and creates a log scope
  5. And so on...

There's 3-5 lines of boilerplate required to do steps 1,2, and 4, and we could easily make a middleware that does it for you.

We might want to add an extension method for step 3.

Copied from original issue: aspnet/Logging#371

Clean Exception Handling

If any exception is thrown while parsing a mod_rewrite or UrlRewrite file, we should provided the line and character index so the user knows exactly where an error is.

Create URL Rewrite Middleware

Objectives:

  • Add URL Rewrite for incoming PathStrings and QueryStrings
  • Support Regex expressions on input and based on match modify output
  • Add capture parameters within matching string to be used on modified output
  • Add URL Redirect which on match would terminate (Ex http to https)

Using Rewrite to Redirect to Canonical URL's for Better SEO

To improve Search Engine Optimization SEO, there should only be a single URL for each resource. Case differences and/or URL's with/without trailing slashes are treated as different URL's by search engines (See Google's comments and Bing's).

It would be greate to write an extension method for IApplicationBuilder called UseRedirectToCanonicalUrl that does this. Here are the special considerations:

  1. The host name is treated differently by search engines. All of the following are equivelant:
  2. IOptions<RouteOptions> can be used to determine the AppendTrailingSlash and LowercaseUrls settings. These can be used to work out whether to add or remove a trailing slash and also whether we should be lower-casing URL's.
  3. You need to deal with exceptions to the rule. For example, if you have routes to dynamically generate robots.txt, sitemap.xml etc. you don't want to redirect these to add trailing slashes, nor do you care about case differences as these routes are effectively being treated as if they were static files.
  4. Sometimes you want to have case-sensitive query strings. ASP.NET Identity for example requires them. This is another exception to the rule that needs to be handled. Perhaps a LowercaseQueryStrings property could be added to IOptions<RouteOptions>.

I have already written a RedirectToCanonicalUrlAttribute MVC Core filter to do the above and I've been thinking about converting it to middleware, then I saw this project and now think it can be used for this purpose. I provide two ways of providing exceptions to the rule:

[NoTrailingSlash]
[Route("robots.txt", Name = "GetRobotsText")]
public IActionResult RobotsText() {}
[NoLowercaseQueryString]
[Route("foo", Name = "GetFoo")]
public IActionResult Foo(string caseSensitiveQueryParameter) {}

@ZestyBread I watched the community standup this morning, are you still working at Microsoft? Would you be interested in a PR?

Add Docs

The Rewrite middleware should eventually be documented within AspNetCore before 1.1 release. Stating what is implemented, references to IIS and mod_rewrite, etc.

Verify server variable semantics

Many of the server variables in UrlRewrite and mod_rewrite can obtain different aspects of the HttpRequest (in HttpContext). Though I did my best to verify these, the documentation is lacking. There is definitely some fuzziness when it comes to PathBase with Path in any url checks for conditions.
See:
https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ServerVariables.cs
and https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Rewrite/Internal/UrlRewrite/ServerVariables.cs

Also search for server variable definitions online (if available).

Clean up response compression

Open items:

  • More convenient Options
    • Compression providers
    • Compression negotiator
  • accept-encoding q-value negotiation (perf)
  • should mime types be case sensitive? (No)
  • Make sure no negotiation happens / no bytes written if there's no body.
  • Flush
  • Exception
  • Hook ISendFileFeature?
  • API Review

Testing:

Release:

  • Bump version from 0.1.0 to 1.0.0 when ready

Rewrite Middleware to its own repo?

I feel that eventually the Rewrite middleware should be in its own repo. It has gotten to the point where it is almost on the scale of Routing, and with the inevitable extensions that will be added, it will grow more.

Just a thought.

OverrideHeaderMiddleware doesn't handle X-Forwarded-For with ports

Code from IISPlatformHandler that should be moved to OverrideHeaderMiddleware to correctly handle ports.

        private static void UpdateRemoteIp(HttpContext httpContext)
        {
            var xForwardedForHeaderValue = httpContext.Request.Headers.GetCommaSeparatedValues(XForwardedForHeaderName);
            if (xForwardedForHeaderValue != null && xForwardedForHeaderValue.Length > 0)
            {
                IPAddress ipFromHeader;
                int? port;
                if (IPAddressWithPortParser.TryParse(xForwardedForHeaderValue[0], out ipFromHeader, out port))
                {
                    var connection = httpContext.Connection;
                    var remoteIPString = connection.RemoteIpAddress?.ToString();
                    if (!string.IsNullOrEmpty(remoteIPString))
                    {
                        httpContext.Request.Headers[XOriginalIPName] = remoteIPString;
                    }
                    if (port.HasValue)
                    {
                        if (connection.RemotePort != 0)
                        {
                            httpContext.Request.Headers[XOriginalPortName] = connection.RemotePort.ToString(CultureInfo.InvariantCulture);
                        }
                        connection.RemotePort = port.Value;
                    }
                    connection.RemoteIpAddress = ipFromHeader;
                }
            }
        }
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Net;
using Microsoft.AspNet.IISPlatformHandler;
using Xunit;

namespace Microsoft.AspNet.PipelineHandler.Tests
{
    public class IPAddressWithPortParserTests
    {
        [Theory]
        [InlineData("127.0.0.1", "127.0.0.1", null)]
        [InlineData("127.0.0.1:1", "127.0.0.1", 1)]
        [InlineData("1", "0.0.0.1", null)]
        [InlineData("1:1", "0.0.0.1", 1)]
        [InlineData("::1", "::1", null)]
        [InlineData("[::1]", "::1", null)]
        [InlineData("[::1]:1", "::1", 1)]
        public void ParsesCorrectly(string input, string expectedAddress, int? expectedPort)
        {
            IPAddress address;
            int? port;
            var success = IPAddressWithPortParser.TryParse(input, out address, out port);
            Assert.True(success);
            Assert.Equal(expectedAddress, address?.ToString());
            Assert.Equal(expectedPort, port);
        }

        [InlineData("[::1]:")]
        [InlineData("[::1:")]
        [InlineData("::1:")]
        [InlineData("127:")]
        [InlineData("127.0.0.1:")]
        [InlineData("")]
        [InlineData("[]")]
        [InlineData("]")]
        [InlineData("]:1")]
        public void ShouldNotParse(string input)
        {
            IPAddress address;
            int? port;
            var success = IPAddressWithPortParser.TryParse(input, out address, out port);
            Assert.False(success);
            Assert.Equal(null, address);
            Assert.Equal(null, port);
        }
    }
}

Add support for the CustomResponse action in Url Rewrite

A CustomResponse action causes the URL Rewrite Module to respond to the HTTP client by using a user-specified status code, subcode, and reason. Use of a CustomResponse action implies that no subsequent rules are evaluated for the current URL after this action is performed.
CustomResponse action has the following configuration options:

  • statusCode – Specifies the status code to use in response to the client.
  • subStatusCode – Specifies the substatus code to use in response to the client.
  • statusReason – Specifies the reason phrase to use with the status code.
  • statusDescription – Specifies the one line description to put in the body of the response.

Url Rewrite custom response

Currently not supporting custom responses for Url Rewrite Rules (part of the match). This feature seemed rarely used, but should be considered in the final implementation.
Ex:

<action type="CustomResponse" statusCode="503"  
subStatusCode="0"  
statusReason="Site is unavailable"  
statusDescription="Site is down for maintenance" />  

Force HTTPS in beta8 broken

I was using the following suggestion to force SSL prior to beta8: #10

It seems the same code is causing a redirect loop for some reason. I can't seem to get it to work.

Leading slash throws off rewrite pattern match

Repro

var options = new RewriteOptions();
options.Rewrite("/app/(.+)", "/app?q={R:1}"); // "/app?q=$1" after #77
app.UseRewriter(options);

Request to localhost:5000/app/abcd
Expected
Rewrites to localhost:5000/app?q=abcd

Actual
No rewrite. The match condition is not met because the UrlRewriteRule strips the leading slash

initMatchResults = InitialMatch.Evaluate(path.ToString().Substring(1), context);

cc @ZestyBread

Refactor ModRewriteRedirect/Rewrite Action and Redirect/Rewrite Action together.

Actions occur once the rule has passed. These can be consolidated into one class. Thought they needed to be distinct because of mod_rewrite allowing for more options, but we can probably construct UrlRewrite rules with defaults in mod_rewrite.
See:
https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Rewrite/Internal/ModRewrite/ModRewriteRedirectAction.cs
Versus
https://github.com/aspnet/BasicMiddleware/blob/dev/src/Microsoft.AspNetCore.Rewrite/Internal/UrlActions/RedirectAction.cs

Add HTTP compression middleware

Add middleware for doing HTTP response compression. Should support GZIP and Brotli. Would need to be configurable to allow control of:

  • enabled compression algorithms (maybe support compression providers?)
  • response content types to compress (should default to a known good list)
  • buffering behavior

E.g.:

public void Configure(IApplicationBuilder app)
{
    app.UseResponseCompression();
    app.UseStaticFiles();
    app.Run(async context =>
    {
        context.Response.ContentType = "text/plain";
        await context.Response.WriteAsync("Hello compressed!");
    });
}

OverrideHeaderMiddleware re-written as ForwardedHeadersMiddleware

RE: 44f03ef

OverrideHeaderMiddleware has been renamed to ForwardedHeadersMiddleware. See the following usage:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});

The processing of forwarded headers has also changed significantly. For x-forwarded-for there are new options for KnownProxies and KnownNetworks allowing you to specify which remote parties to trust x-forwarded headers from. This will be applied recursively when there is more than one x-forwarded-for value.

All of the enabled x-forwarded headers are now applied in unison. The process aborts if there an inconsistent number of forwarders as it becomes impossible to determine which ones were applied by which proxy. There is also a ForwardLimit option which if enabled restricts the number of entries evaluated.

Credit: @pmhsfelix.

Add more comprehensive code rules

In the initial sample/ review of the rewrite module, the standard builder model was used to add rules. There are a few simple examples that exist, but these should be verified for operation and more code rules should be added.
Right now we have rules like RedirectRule or RedirectScheme, but a review of these should be done as well as more rules added (check if file exists, rewriting query, etc).

Microsoft.AspNet.HttpOverrides.Tests test failures on CoreCLR on Linux

info: Exec
info:   program: /usr/bin/env
info:   commandline: bash -c ". \"/home/cesars/src/aspnet/universe/BasicMiddleware/packages/KoreBuild/build/dnvm.sh\"; dnvm run default -runtime coreclr test"
info:   workingdir: test/Microsoft.AspNet.HttpOverrides.Tests
xUnit.net DNX Runner (64-bit DNXCore 5.0)
  Discovering: Microsoft.AspNet.HttpOverrides.Tests
  Discovered:  Microsoft.AspNet.HttpOverrides.Tests
  Starting:    Microsoft.AspNet.HttpOverrides.Tests
      Assert.Equal() Failure
                    ↓ (pos 4)
      Expected: testHost
      Actual:   testhost
                    ↑ (pos 4)
      Stack Trace:
           at Microsoft.AspNet.HttpOverrides.OverrideMiddlewareHeaderTests.<>c__DisplayClass2_0.<XForwardedHostOverrideChangesRequestHost>b__1(HttpContext context)
           at Microsoft.AspNet.HttpOverrides.OverrideHeaderMiddleware.Invoke(HttpContext context)
           at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.Hosting.Internal.HostingEngine.<>c__DisplayClass32_0.<<Start>b__0>d.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.TestHost.ClientHandler.<>c__DisplayClass3_0.<<SendAsync>b__0>d.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.TestHost.ClientHandler.<SendAsync>d__3.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
           at Microsoft.AspNet.HttpOverrides.OverrideMiddlewareHeaderTests.<XForwardedHostOverrideChangesRequestHost>d__2.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
      Assert.Equal() Failure
                    ↓ (pos 4)
      Expected: testHost
      Actual:   testhost
                    ↑ (pos 4)
      Stack Trace:
           at Microsoft.AspNet.HttpOverrides.OverrideMiddlewareHeaderTests.<>c__DisplayClass5_0.<AllForwardsEnabledChangeRequestRemoteIpHostandProtocol>b__1(HttpContext context)
           at Microsoft.AspNet.HttpOverrides.OverrideHeaderMiddleware.Invoke(HttpContext context)
           at Microsoft.AspNet.Hosting.Internal.RequestServicesContainerMiddleware.<Invoke>d__3.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.Hosting.Internal.HostingEngine.<>c__DisplayClass32_0.<<Start>b__0>d.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.TestHost.ClientHandler.<>c__DisplayClass3_0.<<SendAsync>b__0>d.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at Microsoft.AspNet.TestHost.ClientHandler.<SendAsync>d__3.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
           at Microsoft.AspNet.HttpOverrides.OverrideMiddlewareHeaderTests.<AllForwardsEnabledChangeRequestRemoteIpHostandProtocol>d__5.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  Finished:    Microsoft.AspNet.HttpOverrides.Tests
=== TEST EXECUTION SUMMARY ===
   Microsoft.AspNet.HttpOverrides.Tests  Total: 11, Errors: 0, Failed: 2, Skipped: 0, Time: 0.708s

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.