markus / MarkusAutoUpdate / src / NetSparkle / Downloaders / WebRequestAppCastDataDownloader.cs @ d8f5045e
이력 | 보기 | 이력해설 | 다운로드 (5.42 KB)
1 | d8f5045e | taeseongkim | 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 | } |