Пример #1
0
 public Task <HttpResponseMessage> SendAsync(PrtgRequestMessage request, CancellationToken token)
 {
     //Cannot use HttpCompletionOption.ResponseHeadersRead without manually disposing
     //HttpResponseMessage objects, which will also dispose internal stream. Existing code
     //needs to be refactored to have the deserialization happen in a callback to ExecuteRequest
     //so that there is no problem wrapping the HttpResponseMessage up in a using for both
     //sync/async
     return(asyncClient.GetAsync(request.Url, token));
 }
Пример #2
0
        private void HandleSocketException(Exception ex, PrtgRequestMessage request)
        {
            var socketException = ex?.InnerException as SocketException;

            if (socketException != null)
            {
                var port = socketException.Message.Substring(socketException.Message.LastIndexOf(':') + 1);

                var protocol = request.Url.Substring(0, request.Url.IndexOf(':')).ToUpper();

                if (socketException.SocketErrorCode == SocketError.TimedOut)
                {
                    throw new TimeoutException($"Connection timed out while communicating with remote server via {protocol} on port {port}. Confirm server address and port are valid and PRTG Service is running.", ex);
                }
                else if (socketException.SocketErrorCode == SocketError.ConnectionRefused)
                {
                    throw new WebException($"Server rejected {protocol} connection on port {port}. Please confirm expected server protocol and port, PRTG Core Service is running and that any SSL certificate is trusted.", ex);
                }
            }
        }
Пример #3
0
 public Task <HttpResponseMessage> SendSync(PrtgRequestMessage request, CancellationToken token)
 {
     return(SendAsync(request, token));
 }
Пример #4
0
        private bool HandleRequestException(Exception innerMostEx, Exception fallbackHandlerEx, PrtgRequestMessage request, ref int retriesRemaining, Action thrower, CancellationToken token)
        {
            if (innerMostEx != null) //Synchronous + Asynchronous
            {
                if (retriesRemaining > 0)
                {
                    prtgClient.HandleEvent(prtgClient.retryRequest, new RetryRequestEventArgs(innerMostEx, request.Url, retriesRemaining));
                }
                else
                {
                    HandleSocketException(innerMostEx, request);

                    throw innerMostEx;
                }
            }
            else
            {
                if (fallbackHandlerEx != null && retriesRemaining > 0)
                {
                    prtgClient.HandleEvent(prtgClient.retryRequest, new RetryRequestEventArgs(fallbackHandlerEx, request.Url, retriesRemaining));
                }
                else
                {
                    thrower?.Invoke();

                    return(false);
                }
            }

            if (retriesRemaining > 0)
            {
                var attemptsMade = prtgClient.RetryCount - retriesRemaining + 1;
                var delay        = prtgClient.RetryDelay * attemptsMade;

                //Note that we don't have an asynchronous wait for the asynchronous version,
                //as this causes weird timing issues in tests like PrtgClient_RetriesWhileStreaming,
                //where the final retry occurs after StreamSensors has supposedly completed
                token.WaitHandle.WaitOne(delay * 1000);
            }

            retriesRemaining--;

            return(true);
        }
Пример #5
0
        private async Task <PrtgResponse> ExecuteRequestAsync(PrtgRequestMessage request, CancellationToken token, Func <HttpResponseMessage, Task <PrtgResponse> > responseParser = null)
        {
            prtgClient.Log($"Asynchronously executing request {request}", LogLevel.Request);

            int retriesRemaining = prtgClient.RetryCount;

            do
            {
                try
                {
                    if (token == CancellationToken.None && DefaultCancellationToken != CancellationToken.None)
                    {
                        token = DefaultCancellationToken;
                    }

                    var responseMessage = await webClient.SendAsync(request, token).ConfigureAwait(false);

                    PrtgResponse responseContent = null;

                    if (responseParser != null)
                    {
                        responseContent = await responseParser(responseMessage).ConfigureAwait(false);
                    }

                    if (responseContent == null)
                    {
                        responseContent = await GetAppropriateResponseAsync(responseMessage, prtgClient.LogLevel).ConfigureAwait(false);
                    }

                    //If we needed to log response, GetAppropriateResponseAsync will have handled this
                    if (responseContent.Type == PrtgResponseType.String)
                    {
                        prtgClient.Log(responseContent.StringValue, LogLevel.Response);
                    }

                    ValidateHttpResponse(responseMessage, responseContent);

                    return(responseContent);
                }
                catch (HttpRequestException ex)
                {
                    var inner = ex.InnerException as WebException;

                    var result = HandleRequestException(inner, ex, request, ref retriesRemaining, null, token);

                    if (!result)
                    {
                        throw;
                    }
                }
                catch (TaskCanceledException ex)
                {
                    //If the token we specified was cancelled, throw the TaskCanceledException
                    if (token.IsCancellationRequested)
                    {
                        throw;
                    }

                    //Otherwise, a token that was created internally for use with timing out was cancelled, so throw a timeout exception
                    throw new TimeoutException($"The server timed out while executing request.", ex);
                }
            } while (true); //Keep retrying as long as we have retries remaining
        }
Пример #6
0
        private PrtgResponse ExecuteRequest(PrtgRequestMessage request, CancellationToken token, Func <HttpResponseMessage, PrtgResponse> responseParser = null)
        {
            prtgClient.Log($"Synchronously executing request {request}", LogLevel.Request);

            int retriesRemaining = prtgClient.RetryCount;

            do
            {
                try
                {
                    if (token == CancellationToken.None && DefaultCancellationToken != CancellationToken.None)
                    {
                        token = DefaultCancellationToken;
                    }

                    var responseMessage = webClient.SendSync(request, token).Result;

                    PrtgResponse responseContent = null;

                    if (responseParser != null)
                    {
                        responseContent = responseParser(responseMessage);
                    }

                    if (responseContent == null)
                    {
                        responseContent = GetAppropriateResponse(responseMessage, prtgClient.LogLevel);
                    }

                    //If we needed to log response, GetAppropriateResponse will have handled this
                    if (responseContent.Type == PrtgResponseType.String)
                    {
                        prtgClient.Log(responseContent.StringValue, LogLevel.Response);
                    }

                    ValidateHttpResponse(responseMessage, responseContent);

                    return(responseContent);
                }
                catch (Exception ex) when(ex is AggregateException || ex is TaskCanceledException || ex is HttpRequestException)
                {
                    var innerException = ex.InnerException;

                    if (innerException is TaskCanceledException)
                    {
                        //If the token we specified was cancelled, throw the TaskCanceledException
                        if (token.IsCancellationRequested)
                        {
                            throw innerException;
                        }

                        //Otherwise, a token that was created internally for use with timing out was cancelled, so throw a timeout exception
                        innerException = new TimeoutException($"The server timed out while executing request.", ex.InnerException);
                    }

                    var result = HandleRequestException(ex.InnerException?.InnerException, innerException, request, ref retriesRemaining, () =>
                    {
                        if (innerException != null)
                        {
                            throw innerException;
                        }
                    }, token);

                    if (!result)
                    {
                        throw;
                    }
                }
            } while (true); //Keep retrying as long as we have retries remaining
        }
        private bool HandleRequestException(Exception innerMostEx, Exception fallbackHandlerEx, PrtgRequestMessage request, ref int retriesRemaining, Action thrower)
        {
            if (innerMostEx != null) //Synchronous + Asynchronous
            {
                if (retriesRemaining > 0)
                {
                    prtgClient.HandleEvent(prtgClient.retryRequest, new RetryRequestEventArgs(innerMostEx, request.Url, retriesRemaining));
                }
                else
                {
                    HandleSocketException(innerMostEx, request);

                    throw innerMostEx;
                }
            }
            else
            {
                if (fallbackHandlerEx != null && retriesRemaining > 0)
                {
                    prtgClient.HandleEvent(prtgClient.retryRequest, new RetryRequestEventArgs(fallbackHandlerEx, request.Url, retriesRemaining));
                }
                else
                {
                    thrower?.Invoke();

                    return(false);
                }
            }

            if (retriesRemaining > 0)
            {
                var attemptsMade = prtgClient.RetryCount - retriesRemaining + 1;
                var delay        = prtgClient.RetryDelay * attemptsMade;

                Thread.Sleep(delay * 1000);
            }

            retriesRemaining--;

            return(true);
        }