diff --git a/UptimeSharp/IUptimeClient.cs b/UptimeSharp/IUptimeClient.cs
index bac23e2..be23ef9 100644
--- a/UptimeSharp/IUptimeClient.cs
+++ b/UptimeSharp/IUptimeClient.cs
@@ -1,12 +1,24 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
namespace UptimeSharp
{
public interface IUptimeClient
{
+ ///
+ /// Accessor for the UptimeRebot API key
+ /// see: http://www.uptimerobot.com/api
+ ///
+ ///
+ /// The API key.
+ ///
string ApiKey { get; set; }
+
+ ///
+ /// Action which is executed before every request
+ ///
+ ///
+ /// The pre request callback.
+ ///
+ Action PreRequest { get; set; }
}
}
diff --git a/UptimeSharp/UptimeClient.cs b/UptimeSharp/UptimeClient.cs
index da24e1a..1223b36 100644
--- a/UptimeSharp/UptimeClient.cs
+++ b/UptimeSharp/UptimeClient.cs
@@ -1,10 +1,12 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Serialization;
+using System;
using System.Collections.Generic;
-using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
-using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
namespace UptimeSharp
{
@@ -32,29 +34,178 @@ namespace UptimeSharp
/// Accessor for the UptimeRebot API key
/// see: http://www.uptimerobot.com/api
///
+ ///
+ /// The API key.
+ ///
public string ApiKey { get; set; }
+ ///
+ /// Action which is executed before every request
+ ///
+ ///
+ /// The pre request callback.
+ ///
+ public Action PreRequest { get; set; }
+
///
/// Initializes a new instance of the class.
///
/// The API key
- public UptimeClient(string apiKey)
+ /// The HttpMessage handler.
+ /// Request timeout (in seconds).
+ public UptimeClient(string apiKey, HttpMessageHandler handler = null, int? timeout = null)
{
// assign public properties
ApiKey = apiKey;
// initialize REST client
- _restClient = new HttpClient(new HttpClientHandler()
+ _restClient = new HttpClient(handler ?? new HttpClientHandler()
{
AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip
});
+ if (timeout.HasValue)
+ {
+ _restClient.Timeout = TimeSpan.FromSeconds(timeout.Value);
+ }
+
// set base uri
_restClient.BaseAddress = baseUri;
// defines the response format
_restClient.DefaultRequestHeaders.Add("Accept", "application/json");
}
+
+
+ ///
+ /// Fetches a typed resource
+ ///
+ ///
+ /// Requested method (appended to base path)
+ /// The cancellation token.
+ /// Additional POST parameters
+ ///
+ protected async Task Request(string method, CancellationToken cancellationToken, Dictionary parameters = null) where T : class, new()
+ {
+ HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, method);
+ HttpResponseMessage response = null;
+
+ if (parameters == null)
+ {
+ parameters = new Dictionary();
+ }
+
+ // add api key to each request
+ parameters.Add("apiKey", ApiKey);
+
+ // require UptimeRobot to respond with JSON formatting
+ parameters.Add("format", "json");
+
+ // UptimeRobot returns by default JSON-P when json-formatting is set
+ // with this param it can return raw JSON
+ parameters.Add("noJsonCallback", "1");
+
+ // content of the request
+ request.Content = new FormUrlEncodedContent(parameters);
+
+ // call pre request action
+ if (PreRequest != null)
+ {
+ PreRequest(method);
+ }
+
+ // make async request
+ try
+ {
+ response = await _restClient.SendAsync(request, cancellationToken);
+ }
+ catch (HttpRequestException exc)
+ {
+ throw new UptimeSharpException(exc.Message, exc);
+ }
+
+ // validate HTTP response
+ ValidateResponse(response);
+
+ // cache headers
+ lastHeaders = response.Headers;
+
+ // read response
+ var responseString = await response.Content.ReadAsStringAsync();
+
+ responseString = responseString.Replace("[]", "{}");
+
+ // deserialize object
+ T parsedResponse = JsonConvert.DeserializeObject(
+ responseString,
+ new JsonSerializerSettings
+ {
+ Error = (object sender, ErrorEventArgs args) =>
+ {
+ throw new UptimeSharpException(String.Format("Parse error: {0}", args.ErrorContext.Error.Message));
+ },
+ Converters =
+ {
+ new BoolConverter(),
+ new UnixDateTimeConverter(),
+ new UriConverter()
+ }
+ }
+ );
+
+ return parsedResponse;
+ }
+
+
+ ///
+ /// Validates the response.
+ ///
+ /// The response.
+ ///
+ ///
+ /// Error retrieving response
+ ///
+ protected void ValidateResponse(HttpResponseMessage response)
+ {
+ // no error found
+ if (response.StatusCode == HttpStatusCode.OK)
+ {
+ return;
+ }
+
+ //string exceptionString = response.ReasonPhrase;
+ //bool isPocketError = response.Headers.Contains("X-Error");
+
+ //// fetch custom pocket headers
+ //string error = TryGetHeaderValue(response.Headers, "X-Error");
+ //int errorCode = Convert.ToInt32(TryGetHeaderValue(response.Headers, "X-Error-Code"));
+
+ //// create exception strings
+ //if (isPocketError)
+ //{
+ // exceptionString = String.Format("Pocket error: {0} ({1}) ", error, errorCode);
+ //}
+ //else
+ //{
+ // exceptionString = String.Format("Request error: {0} ({1})", response.ReasonPhrase, (int)response.StatusCode);
+ //}
+
+ //// create exception
+ //PocketException exception = new PocketException(exceptionString);
+
+ //if (isPocketError)
+ //{
+ // // add custom pocket fields
+ // exception.PocketError = error;
+ // exception.PocketErrorCode = errorCode;
+
+ // // add to generic exception data
+ // exception.Data.Add("X-Error", error);
+ // exception.Data.Add("X-Error-Code", errorCode);
+ //}
+
+ //throw exception;
+ }
}
}