-
Notifications
You must be signed in to change notification settings - Fork 386
Expand file tree
/
Copy pathHTTPSValidator.cs
More file actions
84 lines (75 loc) · 2.75 KB
/
HTTPSValidator.cs
File metadata and controls
84 lines (75 loc) · 2.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
namespace SourceGit.Models
{
public static class HTTPSValidator
{
public static void Add(string host)
{
lock (_syncLock)
{
// Already checked
if (_hosts.ContainsKey(host))
return;
// Temporarily mark as supported to avoid duplicate checks
_hosts.Add(host, true);
// Well-known hosts always support HTTPS
if (host.Contains("github.com", StringComparison.Ordinal) ||
host.Contains("gitlab", StringComparison.Ordinal) ||
host.Contains("azure.com", StringComparison.Ordinal) ||
host.Equals("gitee.com", StringComparison.Ordinal) ||
host.Equals("bitbucket.org", StringComparison.Ordinal) ||
host.Equals("gitea.org", StringComparison.Ordinal) ||
host.Equals("gitcode.com", StringComparison.Ordinal))
return;
}
Task.Run(() =>
{
var supported = false;
try
{
using (var client = new TcpClient())
{
client.ConnectAsync(host, 443).Wait(3000);
if (!client.Connected)
{
client.ConnectAsync(host, 80).Wait(3000);
supported = !client.Connected; // If the network is not available, assume HTTPS is supported
}
else
{
using (var ssl = new SslStream(client.GetStream(), false, (s, cert, chain, errs) => true))
{
ssl.AuthenticateAsClient(host);
supported = ssl.IsAuthenticated; // Hand-shake succeeded
}
}
}
}
catch
{
// Ignore exceptions
}
lock (_syncLock)
{
_hosts[host] = supported;
}
});
}
public static bool IsSupported(string host)
{
lock (_syncLock)
{
if (_hosts.TryGetValue(host, out var supported))
return supported;
return false;
}
}
private static Lock _syncLock = new();
private static Dictionary<string, bool> _hosts = new();
}
}