Case sensitive request headers in ASP.NET

29 Aug 2021

Few strange issues just happens to us, and whole internet never seem to consider that as a problem. This is one such case, where the case-sensitivity affects your code.

You maybe using similar fancy code to retrieve the value for a particular HTTP Request header and encountered this strange challenge. Does the below code "contains" statement looks similar to yours ?

public string GetCountryCode(HttpRequest request)
{
    var cookies = request.Cookies;
    string countryCode;
    if (cookies.AllKeys.Contains(DebugCookieName))
    {
        var cookie = cookies.Get(DebugCookieName);
        var urlDecodeValue = WebUtility.UrlDecode(cookie?.Value);

        var debugCookie =
            JsonConvert.DeserializeObject<DebugCookie>(urlDecodeValue,
                _jsonSerializerSettings);
        countryCode = debugCookie.CountryCode;
    }
    else
    {
        var headers = request.Headers;
        countryCode = headers.AllKeys.Contains(CfIpCountry)
            ? headers.Get(CfIpCountry)
            : _defaultCountryCode;
    }

    return countryCode;
}

You might think about upper-casing all the request headers keys and compare it using LINQ.

Well for your surprise

Request headers aren't case-sensitive and this isn't a challenge for you to address at all

HTTP 1.1/2 specification has defined that the headers should be case-insensitive, so .NET framework has already got that covered. You just need to use it correct.

In above code, you are reading AllKeys property and trying to match your header name with it,. is obviously a case-sensitive search. I was doing similar check to read the headers passed from Cloudflare and suddenly realized that my code isn't working due to difference in character casing, that I've receive from Cloudflare workers.

Instead of going on with normalizing the header keys to Upper in your code, you should be using the Request.Headers["KEY_NAME"] directly.
So a proper working code will be as follows

public string GetCountryCode(HttpRequest request)
{
    var cookies = request.Cookies;
    string countryCode;
    // If the debugging cookie is absent
    if (string.IsNullOrEmpty(cookies[DebugCookieName]?.Value))
    {
        countryCode = request.Headers[CfIpCountry] ?? _defaultCountryCode;
    }
    else
    {
        var urlDecodeValue = WebUtility.UrlDecode(cookies[DebugCookieName].Value);
        var debugCookie = JsonConvert.DeserializeObject<DebugCookie>(urlDecodeValue, _jsonSerializerSettings);
        countryCode = debugCookie.CountryCode;
    }

    return countryCode;
}

Yeah, most problems have simpiler solutions that we simply miss at the first go ;).

Hope this post saves your time. Happy hacking!