mirror of
https://github.com/fergalmoran/DnsServer.git
synced 2026-03-17 02:50:15 +00:00
FailoverApp: added feature to auto generate health check url based of the app record domain name. added support for https type for auto generating health check url with expected scheme.
This commit is contained in:
@@ -159,6 +159,9 @@ namespace Failover
|
||||
if (jsonAppRecordData.healthCheckUrl != null)
|
||||
healthCheckUrl = new Uri(jsonAppRecordData.healthCheckUrl.Value);
|
||||
|
||||
if (healthCheckUrl is null)
|
||||
healthCheckUrl = new Uri("http://" + question.Name);
|
||||
|
||||
List<DnsResourceRecord> answers = new List<DnsResourceRecord>();
|
||||
|
||||
GetAnswers(jsonAppRecordData.primary, question, appRecordTtl, healthCheck, healthCheckUrl, answers);
|
||||
@@ -199,6 +202,9 @@ namespace Failover
|
||||
if (jsonAppRecordData.healthCheckUrl != null)
|
||||
healthCheckUrl = new Uri(jsonAppRecordData.healthCheckUrl.Value);
|
||||
|
||||
if (healthCheckUrl is null)
|
||||
healthCheckUrl = new Uri("http://" + question.Name);
|
||||
|
||||
List<DnsResourceRecord> answers = new List<DnsResourceRecord>();
|
||||
|
||||
GetStatusAnswers(jsonAppRecordData.primary, FailoverType.Primary, question, 30, healthCheck, healthCheckUrl, answers);
|
||||
@@ -218,7 +224,7 @@ namespace Failover
|
||||
#region properties
|
||||
|
||||
public string Description
|
||||
{ get { return "Returns A or AAAA records from primary set of addresses with a continous health check as configured in the app config. When none of the primary addresses are healthy, the app returns healthy addresses from the secondary set of addresses. When none of the primary and secondary addresses are healthy, the app returns healthy addresses from the server down set of addresses. The server down feature is expected to be used for showing a service status page and not to serve the actual content.\n\nSet 'allowTxtStatus' to 'true' in your APP record data to allow checking health status by querying for TXT record."; } }
|
||||
{ get { return "Returns A or AAAA records from primary set of addresses with a continous health check as configured in the app config. When none of the primary addresses are healthy, the app returns healthy addresses from the secondary set of addresses. When none of the primary and secondary addresses are healthy, the app returns healthy addresses from the server down set of addresses. The server down feature is expected to be used for showing a service status page and not to serve the actual content.\n\nWhen an URL is not provided in 'healthCheckUrl' parameter for 'http' or 'https' type health check, the domain name of the APP record will be used to auto generate an URL.\n\nSet 'allowTxtStatus' parameter to 'true' in your APP record data to allow checking health status by querying for TXT record."; } }
|
||||
|
||||
public string ApplicationRecordDataTemplate
|
||||
{
|
||||
@@ -236,8 +242,8 @@ namespace Failover
|
||||
""serverDown"": [
|
||||
""3.3.3.3""
|
||||
],
|
||||
""healthCheck"": ""http"",
|
||||
""healthCheckUrl"": ""https://www.example.com"",
|
||||
""healthCheck"": ""https"",
|
||||
""healthCheckUrl"": null,
|
||||
""allowTxtStatus"": false
|
||||
}";
|
||||
}
|
||||
|
||||
@@ -135,6 +135,9 @@ namespace Failover
|
||||
if (jsonAppRecordData.healthCheckUrl != null)
|
||||
healthCheckUrl = new Uri(jsonAppRecordData.healthCheckUrl.Value);
|
||||
|
||||
if (healthCheckUrl is null)
|
||||
healthCheckUrl = new Uri("http://" + question.Name);
|
||||
|
||||
IReadOnlyList<DnsResourceRecord> answers;
|
||||
|
||||
if (question.Type == DnsResourceRecordType.TXT)
|
||||
@@ -192,7 +195,7 @@ namespace Failover
|
||||
#region properties
|
||||
|
||||
public string Description
|
||||
{ get { return "Returns CNAME record for primary domain name with a continous health check as configured in the app config. When the primary domain name is unhealthy, the app returns one of the secondary domain names in the given order of preference that is healthy. When none of the primary and secondary domain names are healthy, the app returns the server down domain name. The server down feature is expected to be used for showing a service status page and not to serve the actual content. Note that the app will return ANAME record for an APP record at zone apex.\n\nSet 'allowTxtStatus' to 'true' in your APP record data to allow checking health status by querying for TXT record."; } }
|
||||
{ get { return "Returns CNAME record for primary domain name with a continous health check as configured in the app config. When the primary domain name is unhealthy, the app returns one of the secondary domain names in the given order of preference that is healthy. When none of the primary and secondary domain names are healthy, the app returns the server down domain name. The server down feature is expected to be used for showing a service status page and not to serve the actual content. Note that the app will return ANAME record for an APP record at zone apex.\n\nWhen an URL is not provided in 'healthCheckUrl' parameter for 'http' or 'https' type health check, the domain name of the APP record will be used to auto generate an URL.\n\nSet 'allowTxtStatus' parameter to 'true' in your APP record data to allow checking health status by querying for TXT record."; } }
|
||||
|
||||
public string ApplicationRecordDataTemplate
|
||||
{
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace Failover
|
||||
Unknown = 0,
|
||||
Ping = 1,
|
||||
Tcp = 2,
|
||||
Http = 3
|
||||
Http = 3,
|
||||
Https = 4
|
||||
}
|
||||
|
||||
class HealthCheck : IDisposable
|
||||
@@ -111,25 +112,14 @@ namespace Failover
|
||||
|
||||
private void ConditionalHttpReload()
|
||||
{
|
||||
if (_type == HealthCheckType.Http)
|
||||
switch (_type)
|
||||
{
|
||||
bool handlerChanged = false;
|
||||
NetProxy proxy = _service.DnsServer.Proxy;
|
||||
case HealthCheckType.Http:
|
||||
case HealthCheckType.Https:
|
||||
bool handlerChanged = false;
|
||||
NetProxy proxy = _service.DnsServer.Proxy;
|
||||
|
||||
if (_httpHandler is null)
|
||||
{
|
||||
SocketsHttpHandler httpHandler = new SocketsHttpHandler();
|
||||
httpHandler.ConnectTimeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
httpHandler.Proxy = proxy;
|
||||
httpHandler.AllowAutoRedirect = true;
|
||||
httpHandler.MaxAutomaticRedirections = 10;
|
||||
|
||||
_httpHandler = httpHandler;
|
||||
handlerChanged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_httpHandler.ConnectTimeout.TotalMilliseconds != _timeout) || (_httpHandler.Proxy != proxy))
|
||||
if (_httpHandler is null)
|
||||
{
|
||||
SocketsHttpHandler httpHandler = new SocketsHttpHandler();
|
||||
httpHandler.ConnectTimeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
@@ -137,50 +127,64 @@ namespace Failover
|
||||
httpHandler.AllowAutoRedirect = true;
|
||||
httpHandler.MaxAutomaticRedirections = 10;
|
||||
|
||||
SocketsHttpHandler oldHttpHandler = _httpHandler;
|
||||
_httpHandler = httpHandler;
|
||||
handlerChanged = true;
|
||||
|
||||
oldHttpHandler.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((_httpHandler.ConnectTimeout.TotalMilliseconds != _timeout) || (_httpHandler.Proxy != proxy))
|
||||
{
|
||||
SocketsHttpHandler httpHandler = new SocketsHttpHandler();
|
||||
httpHandler.ConnectTimeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
httpHandler.Proxy = proxy;
|
||||
httpHandler.AllowAutoRedirect = true;
|
||||
httpHandler.MaxAutomaticRedirections = 10;
|
||||
|
||||
if (_httpClient is null)
|
||||
{
|
||||
HttpClient httpClient = new HttpClient(_httpHandler);
|
||||
httpClient.Timeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(HTTP_HEALTH_CHECK_USER_AGENT);
|
||||
SocketsHttpHandler oldHttpHandler = _httpHandler;
|
||||
_httpHandler = httpHandler;
|
||||
handlerChanged = true;
|
||||
|
||||
_httpClient = httpClient;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handlerChanged || (_httpClient.Timeout.TotalMilliseconds != _timeout))
|
||||
oldHttpHandler.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
if (_httpClient is null)
|
||||
{
|
||||
HttpClient httpClient = new HttpClient(_httpHandler);
|
||||
httpClient.Timeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(HTTP_HEALTH_CHECK_USER_AGENT);
|
||||
|
||||
HttpClient oldHttpClient = _httpClient;
|
||||
_httpClient = httpClient;
|
||||
|
||||
oldHttpClient.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_httpClient != null)
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
_httpClient = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (handlerChanged || (_httpClient.Timeout.TotalMilliseconds != _timeout))
|
||||
{
|
||||
HttpClient httpClient = new HttpClient(_httpHandler);
|
||||
httpClient.Timeout = TimeSpan.FromMilliseconds(_timeout);
|
||||
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(HTTP_HEALTH_CHECK_USER_AGENT);
|
||||
|
||||
if (_httpHandler != null)
|
||||
{
|
||||
_httpHandler.Dispose();
|
||||
_httpHandler = null;
|
||||
}
|
||||
HttpClient oldHttpClient = _httpClient;
|
||||
_httpClient = httpClient;
|
||||
|
||||
oldHttpClient.Dispose();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (_httpClient != null)
|
||||
{
|
||||
_httpClient.Dispose();
|
||||
_httpClient = null;
|
||||
}
|
||||
|
||||
if (_httpHandler != null)
|
||||
{
|
||||
_httpHandler.Dispose();
|
||||
_httpHandler = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,6 +390,7 @@ namespace Failover
|
||||
}
|
||||
|
||||
case HealthCheckType.Http:
|
||||
case HealthCheckType.Https:
|
||||
{
|
||||
ConditionalHttpReload();
|
||||
|
||||
@@ -397,12 +402,23 @@ namespace Failover
|
||||
try
|
||||
{
|
||||
Uri url = healthCheckUrl;
|
||||
|
||||
if (url is null)
|
||||
{
|
||||
url = _url;
|
||||
if (url is null)
|
||||
return new HealthCheckStatus(false, "Missing health check URL in APP record as well as in app config.");
|
||||
}
|
||||
|
||||
if (url is null)
|
||||
return new HealthCheckStatus(false, "Missing health check URL in APP record as well as in app config.");
|
||||
if (_type == HealthCheckType.Http)
|
||||
{
|
||||
if (url.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase))
|
||||
url = new Uri("http://" + url.Host + (url.IsDefaultPort ? "" : ":" + url.Port) + url.PathAndQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (url.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
|
||||
url = new Uri("https://" + url.Host + (url.IsDefaultPort ? "" : ":" + url.Port) + url.PathAndQuery);
|
||||
}
|
||||
|
||||
IPEndPoint ep = new IPEndPoint(address, url.Port);
|
||||
Uri queryUri = new Uri(url.Scheme + "://" + ep.ToString() + url.PathAndQuery);
|
||||
|
||||
@@ -30,13 +30,23 @@
|
||||
"interval": 60,
|
||||
"retries": 3,
|
||||
"timeout": 10,
|
||||
"url": null,
|
||||
"emailAlert": "default",
|
||||
"webHook": "default",
|
||||
"comments": "The APP record data must contain 'healthCheckUrl' property with an url when no url is configured for a 'http' type health check."
|
||||
"webHook": "default"
|
||||
},
|
||||
{
|
||||
"name": "https",
|
||||
"type": "https",
|
||||
"interval": 60,
|
||||
"retries": 3,
|
||||
"timeout": 10,
|
||||
"url": null,
|
||||
"emailAlert": "default",
|
||||
"webHook": "default"
|
||||
},
|
||||
{
|
||||
"name": "www.example.com",
|
||||
"type": "http",
|
||||
"type": "https",
|
||||
"interval": 60,
|
||||
"retries": 3,
|
||||
"timeout": 10,
|
||||
|
||||
Reference in New Issue
Block a user