15

I am looking for a way to rewrite the url in case the application path in the url has a different casing. Since the application path can vary for different deployments, I need to access it dynamically. Is there any way of doing it?

Background:

I am setting path of cookies to the application path. Since cookie path is case sensitive, I need to rewrite urls in case they are wrongly cased. I would also like to have alternate ways that do not need the use of the url rewrite module.

Example

Let's assume that for one deployment, the alias for the application is "ApplicationA" (for another deployment, the alias may be "ApplicationB").

http://<host>:<port>/<applicationA or Applicationa or APPLicationA etc.>/<rest of the url>

Redirect to 

http://<host>:<port>/ApplicationA/<rest of the url>
Victor Mukherjee
  • 10,487
  • 16
  • 54
  • 97
  • @NikolaiDante please see the edit. – Victor Mukherjee Jan 29 '16 at 10:23
  • Is the rule it will always start and end in an uppercase letter, but the middle should be lowercase? – NikolaiDante Jan 29 '16 at 10:25
  • No, the alias can be [A-Za-z0-9]+, and the rewrite should only happen when this alias part of the url is in different case. – Victor Mukherjee Jan 29 '16 at 10:27
  • I recommend stop bother/use casing on url's, and just lowercase saving/reading cookies on all incoming request and your problems should be gone? – Asons Feb 02 '16 at 20:39
  • @LGSon yes, that is one workaround. But it will have performance penalty since there will be lots of redirects. It is a legacy application, so changing individual urls in the application is not feasible. – Victor Mukherjee Feb 03 '16 at 07:03
  • When you deploy, why are you use casing in the first place? ... if you stop with that, as I suggest, you don't have to bother with redirects and cookie path issues. – Asons Feb 03 '16 at 09:43

4 Answers4

0

Not sure if REWRITE is correct operation in your case, maybe you should use REDIRECT(permanent), but below is rule which allowed me fetch Application name in specific case:

<system.webServer>
    <rewrite>
        <rules>
            <rule name="My Rule" stopProcessing="true">
                <match url="^(.+)" ignoreCase="false" />
                <conditions>
                    <add input="{REQUEST_URI}" pattern="TmP/.+" ignoreCase="false" negate="true" />
                    <add input="{REQUEST_URI}" pattern="tmp/(.+)" ignoreCase="true" />
                </conditions>
                <action type="Redirect" url="TmP/{C:1}" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>
Uriil
  • 11,948
  • 11
  • 47
  • 68
0

I think creating and adding a custom Http Module can solve your problem. An HTTP module is called on every request in response to the BeginRequest and EndRequest events.

You can access the URL dynamically and redirect it by changing its case.

private void PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        var f = req.Url;
        f="Change case of URL";
        if (condition)
        {

            app.Response.Redirect(f);
        }

    }
Vignesh Pandi
  • 349
  • 1
  • 4
  • 15
0

Updated

May I suggest you subscribe to the BeginRequest event using a HTTPModule.

With the RewritePath method you would gain speed against Redirect, where you just match and rewrite the url if the casing is wrong, ... or actually just adjust the casing might be faster than to check it first and then adjust (test and see before you pick solution).

A positive side effect is you can easily put in other tests and make exceptions etc.

public class AdjustCasingModule : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += OnBeginRequest;
    }

    protected void BeginRequest(object sender, EventArgs e)
    {
        var httpContext = ((HttpApplication)sender).Context;

        string[] path = httpContext.Request.Path.Split('/');

        if (path[1].Length > 0)
        {
            Regex rgx = new Regex(@"^[A-Z][a-z]*[A-Z]");

            if (!rgx.IsMatch(path[1]))
            {
                char[] a = path[1].ToLower().ToCharArray();
                a[0] = char.ToUpper(a[0]);
                a[char.Length - 1] = char.ToUpper(a[char.Length - 1]);
                path[1] = new string(a);
                httpContext.RewritePath(String.Join('/', path));
            }
        }
    }

    public void Dispose()
    {

    }
}

Side note:

I still recommend using lower case path in the first place.

Asons
  • 84,923
  • 12
  • 110
  • 165
0

Just a thought, if one would consider abandoning the camel case notation (ApplicationA) in favor of forced for example lowercase* (applicationa), you could use the ToLower keyword as below.

<system.webServer>
    <rewrite>
        <rules>
            <rule name="force lowercase" stopProcessing="true">
                <match url="(.*)" />
                <conditions>
                    <add input="{URL}" pattern="[A-Z]" ignoreCase="false" />
                </conditions>
                <action type="Redirect" url="{ToLower:{URL}}" redirectType="Temporary" />
            </rule>
        </rules>
    </rewrite>
</system.webServer>

*If you are committed to your original camelCase notation in the url then I would defer to Uriil's approach above.

Jeff Mergler
  • 1,384
  • 20
  • 27