I am developing a Restful API where I need to check the authorization before making the actual DELETE request. So I thought it would be nice to use HEAD method as a preflight check.
I expected that an unauthorized request with HEAD method will return 401/403 response with no body. However, it turns out that WebApi2 crashes with following exception and closes the connection:
Exception caught: 'System.Net.ProtocolViolationException' in System.dll ("Bytes to be written to the stream exceed the Content-Length bytes size specified.")
Other HTTP methods (DELETE,GET) seem to work properly - return 401 response.
I can workaround it with a GET request, but it seems like a bug in WebApi. AuthorizeAttribute always adds a content, no matter what the original request method was.
My question is: Is it a bug or it is an intended behavior and there is a reason why I shouldn't use HEAD method here?
Here is a sample program that reproduces the issue:
namespace OwinServer
{
[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new[] { "value1", "value2" };
}
//HEAD api/values
public void Head()
{
}
//DELETE api/values
public void Delete()
{
}
}
class Program
{
static void Main(string[] args)
{
var baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start(baseAddress, Configuration))
{
Console.WriteLine("Host started");
Console.ReadLine();
}
}
public static void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
var config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
}
The behavior can be tested using PowerShell:
Sample request that fails:
Invoke-WebRequest -Uri 'http://localhost:9000/api/values' -Method HEAD
Sample request that works:
Invoke-WebRequest -Uri 'http://localhost:9000/api/values' -Method DELETE