Сервер Kestrel медленно работает с «неверными данными запроса» - PullRequest
1 голос
/ 14 мая 2019

У меня есть устройство IOT (черный ящик, я не могу его перепрограммировать), которое отправляет запросы http POST (136 байт JSON, строка) по проводному Ethernet в мое очень простое консольное приложение на сервере .NET core 2.2.Я просто вывожу строку на консоль.

    [HttpPost]
    public void Post([FromBody] RootObject root)
    {
        string adv = root.prt;
        Console.WriteLine(adv);
    }

Я получаю отображать менее 1 строки в секунду, иногда 2.

Используя Fiddler в качестве обратного прокси-сервера, вместо этого я получаю от 5и 10 http req в секунду, это правильное поведение устройства.

Итак, я включил информационные журналы и получаю их каждую секунду с ошибкой «Неверная строка запроса»:

info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 POST http://192.168.0.92/api/values application/json 136
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'BluepycWeb.Controllers.ValuesController.Post (BluepycWeb)'
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Route matched with {action = "Post", controller = "Values"}. Executing action BluepycWeb.Controllers.ValuesController.Post (BluepycWeb)
02003F002293831000010033FF0006EFAA256B6D1A001E010201061AFF4C000215476C6F62616C2D54616700000000000000000000CD0101CC0001FF001FCC
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method BluepycWeb.Controllers.ValuesController.Post (BluepycWeb) with arguments (BluepycWeb.Controllers.RootObject) - Validation state: Valid
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action method BluepycWeb.Controllers.ValuesController.Post (BluepycWeb), returned result Microsoft.AspNetCore.Mvc.EmptyResult in 0.2158ms.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
      Executed action BluepycWeb.Controllers.ValuesController.Post (BluepycWeb) in 9.4032ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'BluepycWeb.Controllers.ValuesController.Post (BluepycWeb)'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
      Request finished in 24.5625ms 200
info: Microsoft.AspNetCore.Server.Kestrel[17]
      Connection id "0HLMO99UNQBGM" bad request data: "Invalid request line: '\x0D\x0A'"
Microsoft.AspNetCore.Server.Kestrel.Core.BadHttpRequestException: Invalid request line: '\x0D\x0A'
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.RejectRequestLine(Byte* requestLine, Int32 length)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.GetUnknownMethod(Byte* data, Int32 length, Int32& methodLength)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, Byte* data, Int32 length)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpParser`1.Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.IHttpParser<TRequestHandler>.ParseRequestLine(TRequestHandler handler, ReadOnlySequence`1& buffer, SequencePosition& consumed, SequencePosition& examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TakeStartLine(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.ParseRequest(ReadOnlySequence`1 buffer, SequencePosition& consumed, SequencePosition& examined)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.Http1Connection.TryParseRequest(ReadResult result, Boolean& endConnection)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[TContext](IHttpApplication`1 application)

Если я отправляю один и тот же JSON-платеж через Postman постоянно, без ошибок и задержек.Эта ошибка, которую я не знаю, как избежать, ни из-за того, что происходит (но, похоже, это не расстраивает Fiddler), кажется, на секунду повисает на моем сервере.

Любое предложение о том, как я могу решитьЭта проблема?Отменить / исправить ошибку?Сохранить ошибку, но не замедлить получение данных?

ОБНОВЛЕНИЕ: хостинг с IISExpress, нет проблем, нет ошибки «Недопустимая строка запроса:« \ x0D \ x0A »», очень быстро.Проблема только в использовании Kestrel.

Спасибо!

1 Ответ

1 голос
/ 26 июня 2019

Вчера у меня возникла такая же проблема с моим сервисом ASP .NETCore.Затем понял, что я отправляю запросы HTTPS на мой сервер Kestrel, пока он не настроен на прослушивание протокола HTTPS, поэтому Kestrel жалуется.

Если вы хотите использовать HTTPS в вашей пустельге, у вас есть несколько вариантов для его настройки.Например:

С присвоенным сертификатом сервера:

var host = new WebHostBuilder() .UseKestrel(options => options.Listen(IPAddress.Any, 443, listenOptions => listenOptions.UseHttps("MyCert.pfx")))

С несколькими именами хостов и сертификатами:

public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
    .UseStartup<Startup>()
    .ConfigureKestrel((context, options) =>
    {
        options.ListenAnyIP(5005, listenOptions =>
        {
            listenOptions.UseHttps(httpsOptions =>
            {
                var localhostCert = CertificateLoader.LoadFromStoreCert(
                    "localhost", "My", StoreLocation.CurrentUser, 
                    allowInvalid: true);
                var exampleCert = CertificateLoader.LoadFromStoreCert(
                    "example.com", "My", StoreLocation.CurrentUser, 
                    allowInvalid: true);
                var subExampleCert = CertificateLoader.LoadFromStoreCert(
                    "sub.example.com", "My", StoreLocation.CurrentUser, 
                    allowInvalid: true);
                var certs = new Dictionary<string, X509Certificate2>(
                    StringComparer.OrdinalIgnoreCase);
                certs["localhost"] = localhostCert;
                certs["example.com"] = exampleCert;
                certs["sub.example.com"] = subExampleCert;

                httpsOptions.ServerCertificateSelector = (connectionContext, name) =>
                {
                    if (name != null && certs.TryGetValue(name, out var cert))
                    {
                        return cert;
                    }

                    return exampleCert;
                };
            });
        });
    });
...