lordmilko / PrtgAPI

C#/PowerShell interface for PRTG Network Monitor
MIT License
301 stars 37 forks source link

Some times: "Error while copying content to a stream" "The response ended prematurely." exception from the client #261

Closed AlphatronMBS closed 2 years ago

AlphatronMBS commented 2 years ago

Describe the bug

Hello,

I've use the PRTG Client a lot in my program and sometimes I get the exception "Error while copying content to a stream"

I've been seach on the internet:

"Because the controller's ActionFilterAttribute's OnActionExecuting method is calling ReadAsStreamAsync, the Content can't be read again. I changed ReadAsStreamAsync to ReadAsStringAsync and the request's Content is available in the controller. Apparantly, ReadAsStringAsync buffers the Content so it's still available. "

Is this the solution in you're repro or is there something I must change in my program?

Thanks a lot. Michiel.

Steps to reproduce

public async Task<List<Log>> CreateReport(string GroupName, string probename = null)
        {
            try
            {
                if (probename == null)
                    probename = DefaultProbe;

                var testgroup = await client.GetGroupsAsync(Property.Probe, FilterOperator.Contains, probename);
                var Group = testgroup.Single(x => x.Name == GroupName);
                if (Group != null)
                {
                    var test = await client.GetLogsAsync(Group.Id, RecordAge.LastWeek, 500, new LogStatus[] { LogStatus.Down });
                    return test;
                }
                else
                {
                    return null;
                }
            }
            catch (Exception ex)
            {
              log.Error(ex,"error ");
                return null;
            }
        }

When I use this methode a lot  the error will throw.

What is the output of 'Get-PrtgClient -Diagnostic'?

Software Version And Server Information
PRTG Version    PRTG Network Monitor 21.4.73.1656 x64
Auto-Update Status  [13-12-2021 10:06:32] The downloaded PRTG version (21.4.73.1656) is not newer than your current version (21.4.73.1656).
Operating System    Microsoft Windows 10 Pro (10.0 Build 19042), 12 CPUs (12x x64 Model 63 Step 2), code page "Windows-1252", on "SSDPR-CL100-240-G2"
Server Time 6-1-2022 11:44:30 (W. Europe Standard Time)
Server CPU Load 1%
User Name   PRTG System Administrator
Active User Sessions    PRTG System Administrator
Browser Apple Safari Google Chrome (Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62)

Additional context

No response

lordmilko commented 2 years ago

Hi @AlphatronSecurity,

I attempted to replicate this issue with the following program (and a breakpoint set in the catch block in case something happens) however did not encounter an exception after a few minutes of leaving it running

class Program
{
    private static PrtgClient client;

    static void Main(string[] args)
    {
        Task.Run(async () => await MainAsync()).Wait();
    }

    private static async Task MainAsync()
    {
        client = new PrtgClient("http://prtg.example.com", "prtgadmin", "prtgadmin");

        while (true)
            await CreateReport("Servers");
    }

    public static async Task<List<Log>> CreateReport(string GroupName, string probename = null)
    {
        try
        {
            if (probename == null)
                probename = "Local Probe";

            var testgroup = await client.GetGroupsAsync(Property.Probe, FilterOperator.Contains, probename);
            var Group = testgroup.Single(x => x.Name == GroupName);
            if (Group != null)
            {
                var test = await client.GetLogsAsync(RecordAge.LastWeek, 500, new LogStatus[] { LogStatus.Down });
                return test;
            }
            else
            {
                return null;
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }
}

(I had to change how GetLogsAsync is called as my target group "Servers" didn't have any logs on it)

Are you able to advise if you can replicate the issue using the exact test program above (after modifying the group + probe name and PrtgClient connection details)

If so, can you please provide the stack trace of the exception as well as the error message + stack trace of any inner exceptions as well

AlphatronMBS commented 2 years ago

Hello, Thanks for you're quick answere.

I create a new .NET 6.0 console application with a extra counter:

using PrtgAPI;

class Program { private static PrtgClient client;

static void Main(string[] args)
{
    Task.Run(async () => await MainAsync()).Wait();
}

private static async Task MainAsync()
{
    client = new PrtgClient("http://192.168.34.140/", "prtgadmin", "prtgadmin");
    int counter = 0;
    while (true)
    {
        var list = await CreateReport("ANTWERPEN");
        Console.WriteLine("list " + list.Count() + " Counter:  " + counter);
        counter++;
    }
}

public static async Task<List<Log>> CreateReport(string GroupName, string probename = null)
{
    try
    {
        if (probename == null)
            probename = "Antwerpen (Local Probe)";

        var testgroup = await client.GetGroupsAsync(Property.Probe, FilterOperator.Contains, probename);
        if (testgroup == null)
        {
            return null;
        }

        var Group = testgroup.Single(x => x.Name == GroupName);
        if (Group != null)
        {
            var test = await client.GetLogsAsync(RecordAge.LastWeek, 500, new LogStatus[] { LogStatus.Down });
            return test;
        }
        else
        {
            return null;
        }
    }
    catch (Exception ex)
    {
        return null;
    }
}

}

on 1567 call's the error thrown

with ex.StackTrace at System.Net.Http.HttpContent.d63.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Net.Http.HttpClient.<gCore|83_0>d.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.RequestEngine.d26.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.RequestEngine.d16.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.ObjectEngine.<>c__DisplayClass10_01.<<GetObjectsRawAsync>b__0>d.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.ObjectEngine.<ParseInvalidXmlAsync>d__241.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.ObjectEngine.d10`1.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.Request.ObjectEngine.d91.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.PrtgClient.<GetLogsAsync>d__371.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.PrtgClient.<GetLogsAsync>d__355.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at PrtgAPI.PrtgClient.<GetLogsAsync>d__354.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at Program.d__3.MoveNext() in C:\Users\006asa005\source\repos\TETS\TestPRTG\TestPRTG\Program.cs:line 40

Let me know If you need more information.

Thanks.

lordmilko commented 2 years ago

I am unable to replicate this using .NET Framework, .NET 5 or .NET 6

Are you able to advise whether you can replicate this

If you can replicate it using the synchronous API calls, can you please post the stack trace from that

lordmilko commented 2 years ago

Also can you please post the message/stack trace of any inner exceptions (as well as any inner exceptions inside them, and so on); my understanding is there should be an inner exception of some sort when this error occurs

AlphatronMBS commented 2 years ago

Hello, In the old test (async) I have here below the inner exception. In my test it will generate very soon the error. I will built the requested test with the sync methodes.

The inner exceptions:

ex._innerException.SerializationStackTraceString: at System.Net.Http.HttpConnection.FillAsync(Boolean async) at System.Net.Http.HttpConnection.CopyToContentLengthAsync(Stream destination, Boolean async, UInt64 length, Int32 bufferSize, CancellationToken cancellationToken) at System.Net.Http.HttpConnection.ContentLengthReadStream.CompleteCopyToAsync(Task copyTask, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionResponseContent.SerializeToStreamAsync(Stream stream, TransportContext context, CancellationToken cancellationToken) at System.Net.Http.HttpContent.LoadIntoBufferAsyncCore(Task serializeToStreamTask, MemoryStream tempBuffer)

image

AlphatronMBS commented 2 years ago

Hello,

I think I have the solution.. The Esset Endpoint Security Network attack protection. has been turn on. When I put the program (.net core 6 with async methods) on a clean windows installation it works perfect. (now already 4000 call's without any exception).

Very sorry for that, and thank you for helping me.

Gr. Michiel