markus / MarkusAutoUpdate / src / NetSparkle / Downloaders / WebRequestAppCastDataDownloader.cs @ d8f5045e
이력 | 보기 | 이력해설 | 다운로드 (5.42 KB)
1 |
using NetSparkleUpdater.Interfaces; |
---|---|
2 |
using System; |
3 |
using System.Collections.Generic; |
4 |
using System.IO; |
5 |
using System.Net; |
6 |
using System.Net.Security; |
7 |
using System.Security.Cryptography.X509Certificates; |
8 |
using System.Text; |
9 |
|
10 |
namespace NetSparkleUpdater.Downloaders |
11 |
{ |
12 |
/// <summary> |
13 |
/// Class that takes care of downloading data for an app cast. Allows |
14 |
/// you to send extra JSON with your request for the app cast information. |
15 |
/// </summary> |
16 |
public class WebRequestAppCastDataDownloader : IAppCastDataDownloader |
17 |
{ |
18 |
private string _appcastUrl = ""; |
19 |
|
20 |
/// <summary> |
21 |
/// Default constructor for the app cast data downloader. Basically |
22 |
/// does nothing. :) |
23 |
/// </summary> |
24 |
public WebRequestAppCastDataDownloader() |
25 |
{ |
26 |
} |
27 |
|
28 |
/// <summary> |
29 |
/// If true, don't check the validity of SSL certificates |
30 |
/// </summary> |
31 |
public bool TrustEverySSLConnection { get; set; } = false; |
32 |
|
33 |
/// <summary> |
34 |
/// If not "", sends extra JSON via POST to server with the web request for update information and for the DSA signature. |
35 |
/// </summary> |
36 |
public string ExtraJsonData { get; set; } = ""; |
37 |
|
38 |
/// <inheritdoc/> |
39 |
public string DownloadAndGetAppCastData(string url) |
40 |
{ |
41 |
_appcastUrl = url; |
42 |
// configure ssl cert link |
43 |
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate; |
44 |
var response = GetWebContentResponse(url); |
45 |
if (response != null) |
46 |
{ |
47 |
try |
48 |
{ |
49 |
using (StreamReader reader = new StreamReader(response.GetResponseStream(), GetAppCastEncoding())) |
50 |
{ |
51 |
return reader.ReadToEnd(); |
52 |
} |
53 |
} |
54 |
catch |
55 |
{ |
56 |
|
57 |
} |
58 |
} |
59 |
ServicePointManager.ServerCertificateValidationCallback -= ValidateRemoteCertificate; |
60 |
return null; |
61 |
} |
62 |
|
63 |
/// <inheritdoc/> |
64 |
public Encoding GetAppCastEncoding() |
65 |
{ |
66 |
return Encoding.UTF8; |
67 |
} |
68 |
|
69 |
/// <summary> |
70 |
/// Download the app cast from the given URL. |
71 |
/// Performs a GET request by default. If ExtraJsonData is set, |
72 |
/// uses a POST request and sends the JSON data along with the |
73 |
/// request. |
74 |
/// </summary> |
75 |
/// <param name="url">the URL to download the app cast from</param> |
76 |
/// <returns>the response from the web server if creating the request |
77 |
/// succeeded; null otherwise. The response is not guaranteed to have |
78 |
/// succeeded!</returns> |
79 |
public WebResponse GetWebContentResponse(string url) |
80 |
{ |
81 |
WebRequest request = WebRequest.Create(url); |
82 |
if (request != null) |
83 |
{ |
84 |
if (request is FileWebRequest) |
85 |
{ |
86 |
var fileRequest = request as FileWebRequest; |
87 |
if (fileRequest != null) |
88 |
{ |
89 |
return request.GetResponse(); |
90 |
} |
91 |
} |
92 |
|
93 |
if (request is HttpWebRequest) |
94 |
{ |
95 |
HttpWebRequest httpRequest = request as HttpWebRequest; |
96 |
httpRequest.UseDefaultCredentials = true; |
97 |
httpRequest.Proxy.Credentials = CredentialCache.DefaultNetworkCredentials; |
98 |
if (TrustEverySSLConnection) |
99 |
{ |
100 |
httpRequest.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true; |
101 |
} |
102 |
|
103 |
// http://stackoverflow.com/a/10027534/3938401 |
104 |
if (!string.IsNullOrWhiteSpace(ExtraJsonData)) |
105 |
{ |
106 |
httpRequest.ContentType = "application/json"; |
107 |
httpRequest.Method = "POST"; |
108 |
|
109 |
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream())) |
110 |
{ |
111 |
streamWriter.Write(ExtraJsonData); |
112 |
streamWriter.Flush(); |
113 |
streamWriter.Close(); |
114 |
} |
115 |
} |
116 |
|
117 |
// request the cast and build the stream |
118 |
return httpRequest.GetResponse(); |
119 |
} |
120 |
} |
121 |
return null; |
122 |
} |
123 |
|
124 |
/// <summary> |
125 |
/// Determine if the remote X509 certificate is valid |
126 |
/// </summary> |
127 |
/// <param name="sender">the web request</param> |
128 |
/// <param name="certificate">the certificate</param> |
129 |
/// <param name="chain">the chain</param> |
130 |
/// <param name="sslPolicyErrors">how to handle policy errors</param> |
131 |
/// <returns><c>true</c> if the cert is valid</returns> |
132 |
private bool ValidateRemoteCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) |
133 |
{ |
134 |
if (TrustEverySSLConnection) |
135 |
{ |
136 |
// verify if we talk about our app cast dll |
137 |
if (sender is HttpWebRequest req && req.RequestUri.Equals(new Uri(_appcastUrl))) |
138 |
{ |
139 |
return true; |
140 |
} |
141 |
} |
142 |
|
143 |
// check our cert |
144 |
return sslPolicyErrors == SslPolicyErrors.None && certificate is X509Certificate2 cert2 && cert2.Verify(); |
145 |
} |
146 |
} |
147 |
} |