0

I'm trying to reconcile a few opinions I've found out in the wild. One source says that in C# Request.UrlReferrer will throw a System.UriFormatException if the HTTP header is malformed. The other says that Request.UrlReferrer actually doesn't throw an exception in this case, it just returns null.

That said, I'm developing a webapp that will capture the Referral Url for future reference. I'm checking it for null so that the "not set to instance of an object" error does not burst forth when converting to a string, etc., and that tests out fine. I am also wondering whether I should include error handling for potential System.UriFormatExceptions.

Has anyone run into this? Thank you!

EDIT: Given NightOwl888's answer below, it does appear that exceptions can occur. How often, I'm not sure, but I'd rather protect against it than risk exceptions on a public site.

I am only grabbing the referralUrl for logging, so it won't get used in any downstream application context. It's just getting grannGiven that, I'm guessing that the following code should cover me:

 Uri referrer = null;
        try
        {
            referrer = Request.UrlReferrer;
        }
        catch (UriFormatException)
        {
            referrer = null;
        }
        catch (Exception)
        {
            referrer = null;
        }
        var referralUrl = (referrer != null) ? referrer.ToString() : "None Found";

EDIT: Changed exceptions and added general catch

ewomack
  • 607
  • 9
  • 23
  • As for your edit: you should catch `UriFormatException` (or to be safe, `Exception`) because the property will never throw an `HttpException`. That is the one case where it will return `null` instead, so your exception handler is an unreachable execution path as it is now. – NightOwl888 Jun 07 '16 at 15:19
  • Yes, thank you. I erred. I did add a general catch after my last update. Thanks again! – ewomack Jun 07 '16 at 19:28

1 Answers1

0

Checking the source of System.Web.HttpContext.Current.Request.UrlReferrer shows the following.

public Uri UrlReferrer
{
    get
    {
        if ((this._referrer == null) && (this._wr != null))
        {
            string knownRequestHeader = this._wr.GetKnownRequestHeader(0x24);
            if (!string.IsNullOrEmpty(knownRequestHeader))
            {
                try
                {
                    if (knownRequestHeader.IndexOf("://", StringComparison.Ordinal) >= 0)
                    {
                        this._referrer = new Uri(knownRequestHeader);
                    }
                    else
                    {
                        this._referrer = new Uri(this.Url, knownRequestHeader);
                    }
                }
                catch (HttpException)
                {
                    this._referrer = null;
                }
            }
        }
        return this._referrer;
    }
}

So, indeed it is possible that a UriFormatException can occur if the URL is malformed, since HttpException is the only type that is set to null and UriFormatException does not inherit from HttpException.

A better option may be to use Request.Headers["Referer"], which will return the raw string as pointed out here. But do note that the header can contain any value (including values that are not URLs).

IMO, the Referer header should only be used for logging purposes because it is not reliable enough to use for implementing any kind of application functionality (unless there is some kind of backup functionality in the case it is missing or malformed). The browser can (and often does) neglect to send it in certain cases.

Community
  • 1
  • 1
NightOwl888
  • 55,572
  • 24
  • 139
  • 212
  • Thank you! I was leaning towards this path and you confirmed it. I also edit my text above in light of this – ewomack Jun 07 '16 at 13:48