Art Of Programming

musings by Dmytrii Nagirniak

Fixing HTTPS Support in ASP.NET MVC Routing

I picked the great Steve’s idea to add support for HTTPS in the routing. But I found couple of bugs.

First thing I’ve noticed after adding it and using ActionLink - was invalid HTTPS URL :). It looked like /App/https:/localhost/AppAccount/LogIn.aspx.

This is totally unexpected. So I asked debugger for some help and first thing I’d noticed is that EnableAbsoluteRouting.MakeAbsoluteUrl - doesn’t track ApplicationPath slash which causes invalid link for site in root or in virtual directory. Fixed it the usual for ASP.NET way (with GetCorrectedAppPath).

 

It fixed the second RED problem. What about the leading virtual path appended to the link?

The problem is in the HttpsAwareHttpResponseWrapper.ApplyAppPathModifier and it is again related to the slash-thing. It receives appPath from MVC internals which is again slash-broken :). Then trying to apply RegEx to fails. There’s one more problem with RegEx: the pattern is not escaped, but that another story. So instead of using string.Substring I decided to use normal RegEx in rely on it.

So the final fix for me at this moment is:

HttpsAwareHttpResponseWrapper:

public override string ApplyAppPathModifier(string virtualPath) {
    return Regex.Replace(virtualPath, "(.*)http(s?):(.*)", "http$2:$3", RegexOptions.IgnoreCase);// Just remove everything before "httpS:"
}

 

EnableAbsoluteRouting

private string MakeAbsoluteUrl(RequestContext requestContext, string virtualPath, string scheme) {
    return string.Format("{0}://{1}{2}{3}/{4}",
        scheme,
        requestContext.HttpContext.Request.Url.Host,
        GetPortSegmentOfUrl(scheme),
        GetCorrectedAppPath(requestContext.HttpContext.Request.ApplicationPath),
        virtualPath);
}
private string GetCorrectedAppPath(string appPath) {
    if (appPath.Length > 0 && appPath[0] != '/')
        return appPath = '/' + appPath; // Make sure there's slash
    return appPath;
}

 

Hope it will help.

I’m sure I’ll find more bugs, but let’s leave it for tomorrow :)

And many thanks to Steve Sanderson for the great idea.

Comments

Dmytrii Nagirniak
First of all please make sure you’ll check it works correctly. I wrote it late night and as Steve pointed it probably has some issues.

You need to rewrite the HttpsAwareHttpResponseWrapper.ApplyAppPathModifier
and
EnableAbsoluteRouting.GetCorrectedAppPath methods.
They are located in Steve’s download.
Yenkay
Hi Dmitriy Nagirnyak,

Where to include these functions ?

nk
Dmytrii Nagirniak
Hi Steve,

It was late time when I was digging into that code and I probably could do a mistake.
But couple of hours ago the site was working with this code.
(It can’t be a mystery…) Especially with *leading* slash.
I don’t even remember what for I’ve done it.
Steve Sanderson
Hey, thanks for letting me know about that. When I looked into it, it seemed that the problems in both cases were that ApplicationPath might not have a trailing slash (and I was assuming it would).

So, why is your GetCorrectedAppPath() method putting a *leading* slash on ApplicationPath? When I run the code, it always has a leading slash - the problem is that it might not have a trailing slash.

Or does it behave differently for you?
Halim
This comment has been removed by a blog administrator.

Comments