internal static int CloneResponseParser(PrtgResponse response) { var decodedResponse = WebUtility.UrlDecode(response.StringValue); var id = Convert.ToInt32(Regex.Replace(decodedResponse, "(.+id=)(\\d+)(&.*)?", "$2")); return(id); }
internal Dictionary <string, string> GetDictionary(PrtgResponse response) { var xml = GetXml(response); var dictionary = xml.Descendants().ToDictionary(x => x.Name.ToString().Substring(PropertyPrefix.Length), e => e.Value); return(dictionary); }
internal static int CloneResponseParser(PrtgResponse response) { var decodedResponse = WebUtility.UrlDecode(response.StringValue); if (decodedResponse.Contains(CommandFunction.DuplicateObject.GetDescription())) { throw new PrtgRequestException("PRTG successfully cloned the object, however failed to return a response containing the location of the new object. This violates the Clone Object API contract and indicates a bug in PRTG."); } var id = Convert.ToInt32(Regex.Replace(decodedResponse, "(.+?id=)(\\d+)(&.*)?", "$2")); return(id); }
internal XElement GetXml(PrtgResponse response) { var str = response.StringValue; var inputXml = GetInputXml(str); var ddlXml = GetDropDownListXml(str); var textXml = GetTextAreaXml(str); var dependencyXml = GetDependency(str); //if the dependency xml is null does that cause an issue for the xelement we create below? var elm = new XElement("properties", inputXml, ddlXml, textXml, dependencyXml); return(elm); }
private void ValidateHttpResponse(HttpResponseMessage responseMessage, PrtgResponse response) { if (responseMessage.StatusCode == HttpStatusCode.BadRequest) { var xDoc = XDocument.Load(response.ToXmlReader()); var errorMessage = xDoc.Descendants("error").First().Value; throw new PrtgRequestException($"PRTG was unable to complete the request. The server responded with the following error: {errorMessage}"); } else if (responseMessage.StatusCode == HttpStatusCode.Unauthorized) { throw new HttpRequestException("Could not authenticate to PRTG; the specified username and password were invalid."); } responseMessage.EnsureSuccessStatusCode(); if (responseMessage.RequestMessage?.RequestUri?.AbsolutePath == "/error.htm") { var errorUrl = responseMessage.RequestMessage.RequestUri.ToString() .Replace("&%2339;", "\""); //Strange text found when setting ChannelProperty.PercentMode in PRTG 18.4.47.1962 var queries = UrlUtilities.CrackUrl(errorUrl); var errorMsg = queries["errormsg"]; errorMsg = errorMsg.Replace("<br/><ul><li>", " ").Replace("</li></ul><br/>", " "); throw new PrtgRequestException($"PRTG was unable to complete the request. The server responded with the following error: {errorMsg}"); } if (response.Type == PrtgResponseType.String) { if (response.StringValue.StartsWith("<div class=\"errormsg\">")) //Example: GetProbeProperties specifying a content type of Probe instead of ProbeNode { var msgEnd = response.StringValue.IndexOf("</h3>"); var substr = response.StringValue.Substring(0, msgEnd); var substr1 = Regex.Replace(substr, "\\.</.+?><.+?>", ". "); var regex = new Regex("<.+?>"); var newStr = regex.Replace(substr1, ""); throw new PrtgRequestException($"PRTG was unable to complete the request. The server responded with the following error: {newStr}"); } } }
internal static T GetObjectProperties <T>(PrtgResponse response, XmlEngine xmlEngine, ObjectProperty mandatoryProperty) { var xml = HtmlParser.Default.GetXml(response); var xDoc = new XDocument(xml); //If the response does not contain the mandatory property, we are executing as a read only user, and //should return null var name = HtmlParser.DefaultPropertyPrefix + ObjectPropertyParser.GetObjectPropertyName(mandatoryProperty).TrimEnd('_'); if (xDoc.Descendants(name).ToList().Count > 0) { var items = xmlEngine.DeserializeObject <T>(xDoc.CreateReader()); return(items); } return(default(T)); }
internal static bool NeedsStringResponse(HttpResponseMessage message, LogLevel logLevel, bool isDirty) { return((logLevel & LogLevel.Response) == LogLevel.Response || isDirty || !PrtgResponse.IsSafeDataFormat(message)); }
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 }
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 }