AlexB
AlexB

Reputation: 4538

ASP.NET Core 1.1 Url Rewriting - www to non-www

Here's the core I use with ASP.NET Core 1.1 Url Rewriting middleware to redirect from www. to non-www:

var options = new RewriteOptions()
    .AddRedirect("^(www\\.)(.*)$", "$2");
app.UseRewriter(options);

and for some reason it doesn't work. I know regex is correct. What's wrong here?

Here's the complete Configure function:

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseRequestLocalization(new RequestLocalizationOptions() { DefaultRequestCulture = new RequestCulture("ru-ru") });

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            // URL Rewriting
            var options = new RewriteOptions()
                //.AddRedirect(@"^(https?:\/\/)(www\.)(.*)$", "$1$3");
                .AddRedirect("^(www\\.)(.*)$", "$2");
            app.UseRewriter(options);

            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                   name: "default",
                   template: "{action=Index}/{id?}",
                   defaults: new { controller = "Home" }
                   );
        });
    }

Upvotes: 6

Views: 1905

Answers (1)

Justin Kotalik
Justin Kotalik

Reputation: 385

The issue is that the .AddRedirect and .AddRewrite only look at the path/query string of a URL. So your regex is correct, however the method is only looking at the path/query, so it will never see www. This behavior is standard to most rewriters, like Apache mod_rewrite and IIS UrlRewrite. However, this use case should be easily supported and we will look into it soon!

For now, to get your expected behavior, you can create a custom rule like this. Note I can't test the code at this moment, but the general idea should be right.

        app.UseRewriter(new RewriteOptions().Add(ctx =>
        {
            // checking if the hostName has www. at the beginning
            var req = ctx.HttpContext.Request;
            var hostName = req.Host;
            if (hostName.ToString().StartsWith("www."))
            {
                // Strip off www.
                var newHostName = hostName.ToString().Substring(4);

                // Creating new url
                var newUrl = new StringBuilder()
                                      .Append(req.Scheme)
                                      .Append(newHostName)
                                      .Append(req.PathBase)
                                      .Append(req.Path)
                                      .Append(req.QueryString)
                                      .ToString();

                // Modify Http Response
                var response = ctx.HttpContext.Response;
                response.Headers[HeaderNames.Location] = newUrl;
                response.StatusCode = 301;
                ctx.Result = RuleResult.EndResponse;
            }
        }));

Upvotes: 4

Related Questions