Я разрабатываю Restful API, где мне нужно проверить авторизацию перед выполнением фактического запроса DELETE. Поэтому я подумал, что было бы неплохо использовать метод HEAD в качестве предполетной проверки.
Я ожидал, что несанкционированный запрос с HEAD-методом вернет ответ 401/403 без какого-либо органа. Тем не менее, оказывается, что WebApi2 выходит из строя со следующим исключением и закрывает соединение:
Exception caught: 'System.Net.ProtocolViolationException' in System.dll ("Bytes to be written to the stream exceed the Content-Length bytes size specified.")
Другие методы HTTP (DELETE, GET), похоже, работают нормально - возвращают ответ 401.
Я могу обойти это с помощью запроса GET, но это похоже на ошибку в WebApi. AuthorizeAttribute всегда добавляет контент, независимо от того, каким был исходный метод запроса.
Мой вопрос: это ошибка или это предполагаемое поведение, и есть причина, почему я не должен использовать метод HEAD здесь?
Вот пример программы, которая воспроизводит проблему:
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);
}
}
}
Поведение можно протестировать с помощью PowerShell:
Образец запроса, который не выполняется:
Invoke-WebRequest -Uri 'http://localhost:9000/api/values' -Method HEAD
Образец запроса, который работает:
Invoke-WebRequest -Uri 'http://localhost:9000/api/values' -Method DELETE
Об этом говорилось https://github.com/aspnet/AspNetWebStack/issues/189. Кажется, они ожидают, что вы справитесь с этим в конце.