Response 400 (Bad Request) on Long Url
My team owns a REST service that takes a series of IDs as input and responds with documents. Recently, a consumer of the service ran into an issue when they wanted to request 50 documents. But the problem wasn't the service's ability to handle the request. The problem was the request never made it to our service and the end user was getting a 400 response (Bad Request). The URL was 337 characters long.
I first tried changing the value of maxUrlLength in my Web.config
<httpRuntimetargetFramework="4.5"maxUrlLength="2083"maxQueryStringLength="2048" />
But that didn't fix it. I was still getting a 400 response for the long url. I did some searching and it looks like a lot of users have run into the same issue. Unfortunately, the answer given was always to make the web.config change above, which wasn't working for me. There were also the very unhelpful "well you shouldn't have a URL that long!" comments. At some point, my service may need to limit how many ids it accepts or move the requested ids into the body, etc, but right now the service would be able to respond with 50 documents if it could just get the request!
After little more searching and I found that this actually requires a two part change. In addition to the web.config value, a registry entry also has to be set to tell HTTP.sys to allow longer URLs (Imran Baloch wrote a helpful blog about this here: https://weblogs.asp.net/imranbaloch/archive/2010/04/23/understanding-400-bad-request-exception.aspx). By default, HTTP.sys permits 255 segments at a maximum length of 260 characters each. That 260 character limit was the cause of my issue. So, as part of my site deployment powershell script, I need to update the value in the registry value with something like:
Set-ItemProperty -Path HKLM:\System\CurrentControlSet\Services\HTTP\Parameters -Name UrlSegmentMaxLength -Value 2000 -Type "Dword"
Now according to https://support.microsoft.com/kb/820129, to get this registry change to take effect, I need to restart the HTTP System Service by calling "net stop http" and "net start http". But I keep running into a problem where something is blocking the HTTP system service from stopping and the service hangs. The only reliable way I have found to get this registry change to take effect is to reboot the machine (or VM). Thus, my Azure deployment script now starts with
$regkey="HKLM:\System\CurrentControlSet\Services\HTTP\Parameters"
$regname="UrlSegmentMaxLength"
$regvalue="2000"
$regtype="Dword"
$exists= Get-ItemProperty $regkey $regname -ErrorAction SilentlyContinue
if (-not($exists) -or$exists.$regname-ne$regvalue)
{
Set-ItemProperty- Path $regkey -Name $regname -Value $regvalue -Type $regtype
Restart-Computer
}
And, now my service now receives the request.