Refactor download/update/speedtest

pull/2192/head
2dust 2022-04-11 15:26:32 +08:00
parent 1c5cc190c5
commit 815826c856
12 changed files with 478 additions and 423 deletions

View File

@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
namespace v2rayN.Base
{
/// <summary>
/// </summary>
public class HttpClientHelper
{
private static HttpClientHelper httpClientHelper = null;
private HttpClient httpClient;
private int progressPercentage = -1;
/// <summary>
/// </summary>
private HttpClientHelper() { }
/// <summary>
/// </summary>
/// <returns></returns>
public static HttpClientHelper GetInstance()
{
if (httpClientHelper != null)
{
return httpClientHelper;
}
else
{
HttpClientHelper httpClientHelper = new HttpClientHelper();
HttpClientHandler handler = new HttpClientHandler() { UseCookies = false };
httpClientHelper.httpClient = new HttpClient(handler);
return httpClientHelper;
}
}
public async Task<string> GetAsync(string url)
{
if (string.IsNullOrEmpty(url))
{
return null;
}
try
{
HttpResponseMessage response = await httpClient.GetAsync(url);
return await response.Content.ReadAsStringAsync();
}
catch
{
}
return null;
}
public async Task<string> GetAsync(HttpClient client, string url)
{
if (string.IsNullOrEmpty(url))
{
return null;
}
try
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
HttpResponseMessage response = await client.GetAsync(url, cts.Token);
return await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
Utils.SaveLog("GetAsync", ex);
}
return null;
}
public async Task PutAsync(string url, Dictionary<string, string> headers)
{
var myContent = Utils.ToJson(headers);
var buffer = System.Text.Encoding.UTF8.GetBytes(myContent);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var result = await httpClient.PutAsync(url, byteContent);
}
public async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double> progress, CancellationToken token)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
if (string.IsNullOrEmpty(fileName))
{
throw new ArgumentNullException("fileName");
}
if (File.Exists(fileName))
{
File.Delete(fileName);
}
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode)
{
throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode));
}
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
var canReportProgress = total != -1 && progress != null;
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var file = File.Create(fileName))
{
var totalRead = 0L;
var buffer = new byte[1024 * 1024];
var isMoreToRead = true;
progressPercentage = -1;
do
{
token.ThrowIfCancellationRequested();
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
if (read == 0)
{
isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
// TODO: put here the code to write the file to disk
file.Write(data, 0, read);
totalRead += read;
if (canReportProgress)
{
var percent = Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
if (progressPercentage != percent && percent % 10 == 0)
{
progressPercentage = percent;
progress.Report(percent);
}
}
}
} while (isMoreToRead);
file.Close();
if (canReportProgress)
{
progress.Report(101);
}
}
}
}
public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress<double> progress, CancellationToken token)
{
if (string.IsNullOrEmpty(url))
{
throw new ArgumentNullException("url");
}
var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);
if (!response.IsSuccessStatusCode)
{
throw new Exception(string.Format("The request returned with HTTP status code {0}", response.StatusCode));
}
var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;
var canReportProgress = total != -1 && progress != null;
using (var stream = await response.Content.ReadAsStreamAsync())
{
var totalRead = 0L;
var buffer = new byte[1024 * 1024];
var isMoreToRead = true;
progressPercentage = -1;
DateTime totalDatetime = DateTime.Now;
do
{
token.ThrowIfCancellationRequested();
var read = await stream.ReadAsync(buffer, 0, buffer.Length, token);
if (read == 0)
{
isMoreToRead = false;
}
else
{
var data = new byte[read];
buffer.ToList().CopyTo(0, data, 0, read);
// TODO:
totalRead += read;
if (canReportProgress)
{
TimeSpan ts = (DateTime.Now - totalDatetime);
var speed = totalRead * 1d / ts.TotalMilliseconds / 1000;
var percent = Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);
if (progressPercentage != percent && percent % 5 == 0)
{
progressPercentage = percent;
progress.Report(speed);
}
}
}
} while (isMoreToRead);
}
}
}
}

View File

@ -1,37 +0,0 @@
using System;
using System.Net;
namespace v2rayN.Base
{
class WebClientEx : WebClient
{
public int Timeout
{
get; set;
}
public WebClientEx(int timeout = 3000)
{
Timeout = timeout;
}
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request;
request = (HttpWebRequest)base.GetWebRequest(address);
request.Timeout = Timeout;
request.ReadWriteTimeout = Timeout;
//request.AllowAutoRedirect = false;
//request.AllowWriteStreamBuffering = true;
request.ServicePoint.BindIPEndPointDelegate = (servicePoint, remoteEndPoint, retryCount) =>
{
if (remoteEndPoint.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
return new IPEndPoint(IPAddress.IPv6Any, 0);
else
return new IPEndPoint(IPAddress.Any, 0);
};
return request;
}
}
}

View File

@ -126,8 +126,7 @@
this.tsbCheckUpdateCore = new System.Windows.Forms.ToolStripMenuItem(); this.tsbCheckUpdateCore = new System.Windows.Forms.ToolStripMenuItem();
this.tsbCheckUpdateXrayCore = new System.Windows.Forms.ToolStripMenuItem(); this.tsbCheckUpdateXrayCore = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator15 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator15 = new System.Windows.Forms.ToolStripSeparator();
this.tsbCheckUpdateGeoSite = new System.Windows.Forms.ToolStripMenuItem(); this.tsbCheckUpdateGeo = new System.Windows.Forms.ToolStripMenuItem();
this.tsbCheckUpdateGeoIP = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
this.tsbHelp = new System.Windows.Forms.ToolStripDropDownButton(); this.tsbHelp = new System.Windows.Forms.ToolStripDropDownButton();
this.tsbAbout = new System.Windows.Forms.ToolStripMenuItem(); this.tsbAbout = new System.Windows.Forms.ToolStripMenuItem();
@ -831,8 +830,7 @@
this.tsbCheckUpdateCore, this.tsbCheckUpdateCore,
this.tsbCheckUpdateXrayCore, this.tsbCheckUpdateXrayCore,
this.toolStripSeparator15, this.toolStripSeparator15,
this.tsbCheckUpdateGeoSite, this.tsbCheckUpdateGeo});
this.tsbCheckUpdateGeoIP});
this.tsbCheckUpdate.Image = global::v2rayN.Properties.Resources.checkupdate; this.tsbCheckUpdate.Image = global::v2rayN.Properties.Resources.checkupdate;
resources.ApplyResources(this.tsbCheckUpdate, "tsbCheckUpdate"); resources.ApplyResources(this.tsbCheckUpdate, "tsbCheckUpdate");
this.tsbCheckUpdate.Name = "tsbCheckUpdate"; this.tsbCheckUpdate.Name = "tsbCheckUpdate";
@ -860,17 +858,11 @@
this.toolStripSeparator15.Name = "toolStripSeparator15"; this.toolStripSeparator15.Name = "toolStripSeparator15";
resources.ApplyResources(this.toolStripSeparator15, "toolStripSeparator15"); resources.ApplyResources(this.toolStripSeparator15, "toolStripSeparator15");
// //
// tsbCheckUpdateGeoSite // tsbCheckUpdateGeo
// //
this.tsbCheckUpdateGeoSite.Name = "tsbCheckUpdateGeoSite"; this.tsbCheckUpdateGeo.Name = "tsbCheckUpdateGeo";
resources.ApplyResources(this.tsbCheckUpdateGeoSite, "tsbCheckUpdateGeoSite"); resources.ApplyResources(this.tsbCheckUpdateGeo, "tsbCheckUpdateGeo");
this.tsbCheckUpdateGeoSite.Click += new System.EventHandler(this.tsbCheckUpdateGeoSite_Click); this.tsbCheckUpdateGeo.Click += new System.EventHandler(this.tsbCheckUpdateGeo_Click);
//
// tsbCheckUpdateGeoIP
//
this.tsbCheckUpdateGeoIP.Name = "tsbCheckUpdateGeoIP";
resources.ApplyResources(this.tsbCheckUpdateGeoIP, "tsbCheckUpdateGeoIP");
this.tsbCheckUpdateGeoIP.Click += new System.EventHandler(this.tsbCheckUpdateGeoIP_Click);
// //
// toolStripSeparator10 // toolStripSeparator10
// //
@ -1071,8 +1063,7 @@
private System.Windows.Forms.ToolStripSeparator toolStripSeparator14; private System.Windows.Forms.ToolStripSeparator toolStripSeparator14;
private System.Windows.Forms.ToolStripMenuItem tsbBackupGuiNConfig; private System.Windows.Forms.ToolStripMenuItem tsbBackupGuiNConfig;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator15; private System.Windows.Forms.ToolStripSeparator toolStripSeparator15;
private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdateGeoSite; private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdateGeo;
private System.Windows.Forms.ToolStripMenuItem tsbCheckUpdateGeoIP;
private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.ToolStripMenuItem menuMsgBoxFilter; private System.Windows.Forms.ToolStripMenuItem menuMsgBoxFilter;
private System.Windows.Forms.ToolStripStatusLabel toolSslInboundInfo; private System.Windows.Forms.ToolStripStatusLabel toolSslInboundInfo;

View File

@ -413,7 +413,7 @@ namespace v2rayN.Forms
} }
private void lvServers_SelectedIndexChanged(object sender, EventArgs e) private void lvServers_SelectedIndexChanged(object sender, EventArgs e)
{ {
} }
private void ssMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e) private void ssMain_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
@ -781,13 +781,12 @@ namespace v2rayN.Forms
{ {
if (GetLvSelectedIndex() < 0) return; if (GetLvSelectedIndex() < 0) return;
ClearTestResult(); ClearTestResult();
SpeedtestHandler statistics = new SpeedtestHandler(ref config, v2rayHandler, lstSelecteds, actionType, UpdateSpeedtestHandler); SpeedtestHandler statistics = new SpeedtestHandler(config, v2rayHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);
} }
private void tsbTestMe_Click(object sender, EventArgs e) private void tsbTestMe_Click(object sender, EventArgs e)
{ {
SpeedtestHandler statistics = new SpeedtestHandler(ref config); string result = (new DownloadHandle()).RunAvailabilityCheck(null) + "ms";
string result = statistics.RunAvailabilityCheck() + "ms";
AppendText(false, string.Format(ResUI.TestMeOutput, result)); AppendText(false, string.Format(ResUI.TestMeOutput, result));
} }
@ -1197,6 +1196,10 @@ namespace v2rayN.Forms
lstVmess[k].testResult = txt; lstVmess[k].testResult = txt;
lvServers.Items[k].SubItems["testResult"].Text = txt; lvServers.Items[k].SubItems["testResult"].Text = txt;
} }
else
{
AppendText(false, txt);
}
} }
private void SetTestResult(int k, string txt) private void SetTestResult(int k, string txt)
{ {
@ -1248,7 +1251,7 @@ namespace v2rayN.Forms
lvServers.EndUpdate(); lvServers.EndUpdate();
}); });
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -1418,31 +1421,16 @@ namespace v2rayN.Forms
(new UpdateHandle()).CheckUpdateCore(type, config, _updateUI); (new UpdateHandle()).CheckUpdateCore(type, config, _updateUI);
} }
private void tsbCheckUpdateGeoSite_Click(object sender, EventArgs e) private void tsbCheckUpdateGeo_Click(object sender, EventArgs e)
{ {
(new UpdateHandle()).UpdateGeoFile("geosite", config, (bool success, string msg) => Task.Run(() =>
{ {
AppendText(false, msg); var updateHandle = new UpdateHandle();
if (success) updateHandle.UpdateGeoFile("geosite", config, UpdateTaskHandler);
{ updateHandle.UpdateGeoFile("geoip", config, UpdateTaskHandler);
Global.reloadV2ray = true;
_ = LoadV2ray();
}
}); });
} }
private void tsbCheckUpdateGeoIP_Click(object sender, EventArgs e)
{
(new UpdateHandle()).UpdateGeoFile("geoip", config, (bool success, string msg) =>
{
AppendText(false, msg);
if (success)
{
Global.reloadV2ray = true;
_ = LoadV2ray();
}
});
}
#endregion #endregion
#region Help #region Help

View File

@ -321,7 +321,7 @@
<value>ImageAboveText</value> <value>ImageAboveText</value>
</data> </data>
<data name="cmsLv.Size" type="System.Drawing.Size, System.Drawing"> <data name="cmsLv.Size" type="System.Drawing.Size, System.Drawing">
<value>356, 666</value> <value>356, 644</value>
</data> </data>
<data name="&gt;&gt;cmsLv.Name" xml:space="preserve"> <data name="&gt;&gt;cmsLv.Name" xml:space="preserve">
<value>cmsLv</value> <value>cmsLv</value>
@ -750,19 +750,19 @@
<value>Do not change system proxy</value> <value>Do not change system proxy</value>
</data> </data>
<data name="menuSysAgentMode.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuSysAgentMode.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuSysAgentMode.Text" xml:space="preserve"> <data name="menuSysAgentMode.Text" xml:space="preserve">
<value>System proxy</value> <value>System proxy</value>
</data> </data>
<data name="menuRoutings.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuRoutings.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuRoutings.Text" xml:space="preserve"> <data name="menuRoutings.Text" xml:space="preserve">
<value>Routing</value> <value>Routing</value>
</data> </data>
<data name="menuServers.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuServers.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuServers.Text" xml:space="preserve"> <data name="menuServers.Text" xml:space="preserve">
<value>Server</value> <value>Server</value>
@ -780,43 +780,43 @@
<value>Server</value> <value>Server</value>
</data> </data>
<data name="toolStripSeparator13.Size" type="System.Drawing.Size, System.Drawing"> <data name="toolStripSeparator13.Size" type="System.Drawing.Size, System.Drawing">
<value>261, 6</value> <value>274, 6</value>
</data> </data>
<data name="menuAddServers2.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuAddServers2.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuAddServers2.Text" xml:space="preserve"> <data name="menuAddServers2.Text" xml:space="preserve">
<value>Import bulk URL from clipboard</value> <value>Import bulk URL from clipboard</value>
</data> </data>
<data name="menuScanScreen2.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuScanScreen2.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuScanScreen2.Text" xml:space="preserve"> <data name="menuScanScreen2.Text" xml:space="preserve">
<value>Scan QR code on the screen</value> <value>Scan QR code on the screen</value>
</data> </data>
<data name="menuUpdateSubscriptions.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuUpdateSubscriptions.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuUpdateSubscriptions.Text" xml:space="preserve"> <data name="menuUpdateSubscriptions.Text" xml:space="preserve">
<value>Update subscription without proxy</value> <value>Update subscription without proxy</value>
</data> </data>
<data name="menuUpdateSubViaProxy.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuUpdateSubViaProxy.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuUpdateSubViaProxy.Text" xml:space="preserve"> <data name="menuUpdateSubViaProxy.Text" xml:space="preserve">
<value>Update subscriptions via proxy</value> <value>Update subscriptions via proxy</value>
</data> </data>
<data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing"> <data name="toolStripSeparator2.Size" type="System.Drawing.Size, System.Drawing">
<value>261, 6</value> <value>274, 6</value>
</data> </data>
<data name="menuExit.Size" type="System.Drawing.Size, System.Drawing"> <data name="menuExit.Size" type="System.Drawing.Size, System.Drawing">
<value>264, 22</value> <value>277, 22</value>
</data> </data>
<data name="menuExit.Text" xml:space="preserve"> <data name="menuExit.Text" xml:space="preserve">
<value>Exit</value> <value>Exit</value>
</data> </data>
<data name="cmsMain.Size" type="System.Drawing.Size, System.Drawing"> <data name="cmsMain.Size" type="System.Drawing.Size, System.Drawing">
<value>265, 221</value> <value>278, 221</value>
</data> </data>
<data name="&gt;&gt;cmsMain.Name" xml:space="preserve"> <data name="&gt;&gt;cmsMain.Name" xml:space="preserve">
<value>cmsMain</value> <value>cmsMain</value>
@ -861,19 +861,19 @@
<value>6, 56</value> <value>6, 56</value>
</data> </data>
<data name="tsbSubSetting.Size" type="System.Drawing.Size, System.Drawing"> <data name="tsbSubSetting.Size" type="System.Drawing.Size, System.Drawing">
<value>182, 22</value> <value>277, 22</value>
</data> </data>
<data name="tsbSubSetting.Text" xml:space="preserve"> <data name="tsbSubSetting.Text" xml:space="preserve">
<value>Settings</value> <value>Settings</value>
</data> </data>
<data name="tsbSubUpdate.Size" type="System.Drawing.Size, System.Drawing"> <data name="tsbSubUpdate.Size" type="System.Drawing.Size, System.Drawing">
<value>182, 22</value> <value>277, 22</value>
</data> </data>
<data name="tsbSubUpdate.Text" xml:space="preserve"> <data name="tsbSubUpdate.Text" xml:space="preserve">
<value>Update subscription without proxy</value> <value>Update subscription without proxy</value>
</data> </data>
<data name="tsbSubUpdateViaProxy.Size" type="System.Drawing.Size, System.Drawing"> <data name="tsbSubUpdateViaProxy.Size" type="System.Drawing.Size, System.Drawing">
<value>182, 22</value> <value>277, 22</value>
</data> </data>
<data name="tsbSubUpdateViaProxy.Text" xml:space="preserve"> <data name="tsbSubUpdateViaProxy.Text" xml:space="preserve">
<value>Update subscription with proxy</value> <value>Update subscription with proxy</value>
@ -995,17 +995,11 @@
<data name="toolStripSeparator15.Size" type="System.Drawing.Size, System.Drawing"> <data name="toolStripSeparator15.Size" type="System.Drawing.Size, System.Drawing">
<value>200, 6</value> <value>200, 6</value>
</data> </data>
<data name="tsbCheckUpdateGeoSite.Size" type="System.Drawing.Size, System.Drawing"> <data name="tsbCheckUpdateGeo.Size" type="System.Drawing.Size, System.Drawing">
<value>203, 22</value> <value>203, 22</value>
</data> </data>
<data name="tsbCheckUpdateGeoSite.Text" xml:space="preserve"> <data name="tsbCheckUpdateGeo.Text" xml:space="preserve">
<value>Update GeoSite</value> <value>Update Geo files</value>
</data>
<data name="tsbCheckUpdateGeoIP.Size" type="System.Drawing.Size, System.Drawing">
<value>203, 22</value>
</data>
<data name="tsbCheckUpdateGeoIP.Text" xml:space="preserve">
<value>Update GeoIP</value>
</data> </data>
<data name="tsbCheckUpdate.ImageTransparentColor" type="System.Drawing.Color, System.Drawing"> <data name="tsbCheckUpdate.ImageTransparentColor" type="System.Drawing.Color, System.Drawing">
<value>Magenta</value> <value>Magenta</value>
@ -1619,16 +1613,10 @@
<data name="&gt;&gt;toolStripSeparator15.Type" xml:space="preserve"> <data name="&gt;&gt;toolStripSeparator15.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Windows.Forms.ToolStripSeparator, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="&gt;&gt;tsbCheckUpdateGeoSite.Name" xml:space="preserve"> <data name="&gt;&gt;tsbCheckUpdateGeo.Name" xml:space="preserve">
<value>tsbCheckUpdateGeoSite</value> <value>tsbCheckUpdateGeo</value>
</data> </data>
<data name="&gt;&gt;tsbCheckUpdateGeoSite.Type" xml:space="preserve"> <data name="&gt;&gt;tsbCheckUpdateGeo.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;tsbCheckUpdateGeoIP.Name" xml:space="preserve">
<value>tsbCheckUpdateGeoIP</value>
</data>
<data name="&gt;&gt;tsbCheckUpdateGeoIP.Type" xml:space="preserve">
<value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="&gt;&gt;toolStripSeparator10.Name" xml:space="preserve"> <data name="&gt;&gt;toolStripSeparator10.Name" xml:space="preserve">

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Handler; using v2rayN.Handler;
@ -345,13 +346,17 @@ namespace v2rayN.Forms
UI.Show(ResUI.MsgNeedUrl); UI.Show(ResUI.MsgNeedUrl);
return; return;
} }
DownloadHandle downloadHandle = new DownloadHandle();
string clipboardData = downloadHandle.WebDownloadStringSync(url); Task.Run(async () =>
if (AddBatchRoutingRules(ref routingItem, clipboardData) == 0)
{ {
RefreshRoutingsView(); DownloadHandle downloadHandle = new DownloadHandle();
UI.Show(ResUI.OperationSuccess); string result = await downloadHandle.DownloadStringAsync(url, false, "");
} if (AddBatchRoutingRules(ref routingItem, result) == 0)
{
RefreshRoutingsView();
UI.Show(ResUI.OperationSuccess);
}
});
} }
private int AddBatchRoutingRules(ref RoutingItem routingItem, string clipboardData) private int AddBatchRoutingRules(ref RoutingItem routingItem, string clipboardData)
{ {
@ -363,8 +368,6 @@ namespace v2rayN.Forms
return ConfigHandler.AddBatchRoutingRules(ref routingItem, clipboardData, blReplace); return ConfigHandler.AddBatchRoutingRules(ref routingItem, clipboardData, blReplace);
} }
#endregion #endregion
} }

View File

@ -1,7 +1,12 @@
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Net; using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Resx; using v2rayN.Resx;
@ -29,97 +34,71 @@ namespace v2rayN.Handler
} }
} }
private int progressPercentage = -1; public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout)
private long totalBytesToReceive = 0;
private DateTime totalDatetime = new DateTime();
private int DownloadTimeout = -1;
public WebClientEx DownloadFileAsync(string url, WebProxy webProxy, int downloadTimeout)
{ {
WebClientEx ws = new WebClientEx();
try try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13); Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading)); UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
progressPercentage = -1; var client = new HttpClient(new WebRequestHandler()
totalBytesToReceive = 0;
//WebClientEx ws = new WebClientEx();
DownloadTimeout = downloadTimeout;
if (webProxy != null)
{ {
ws.Proxy = webProxy;// new WebProxy(Global.Loopback, Global.httpPort); Proxy = webProxy
} });
ws.DownloadFileCompleted += ws_DownloadFileCompleted; var progress = new Progress<double>();
ws.DownloadProgressChanged += ws_DownloadProgressChanged; progress.ProgressChanged += (sender, value) =>
ws.DownloadFileAsync(new Uri(url), Utils.GetPath(Utils.GetDownloadFileName(url))); {
if (UpdateCompleted != null)
{
string msg = string.Format("{0} M/s", value.ToString("#0.0"));
UpdateCompleted(this, new ResultEventArgs(false, msg));
}
};
var cancellationToken = new CancellationTokenSource();
cancellationToken.CancelAfter(downloadTimeout * 1000);
await HttpClientHelper.GetInstance().DownloadDataAsync4Speed(client,
url,
progress,
cancellationToken.Token);
} }
catch (Exception ex) catch (Exception ex)
{ {
Utils.SaveLog(ex.Message, ex); //Utils.SaveLog(ex.Message, ex);
Error?.Invoke(this, new ErrorEventArgs(ex)); Error?.Invoke(this, new ErrorEventArgs(ex));
} }
return ws; return 0;
} }
void ws_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e) public void DownloadFileAsync(string url, bool blProxy, int downloadTimeout)
{
if (UpdateCompleted != null)
{
if (totalBytesToReceive == 0)
{
totalDatetime = DateTime.Now;
totalBytesToReceive = e.BytesReceived;
return;
}
totalBytesToReceive = e.BytesReceived;
if (DownloadTimeout != -1)
{
if ((DateTime.Now - totalDatetime).TotalSeconds > DownloadTimeout)
{
((WebClientEx)sender).CancelAsync();
}
}
if (progressPercentage != e.ProgressPercentage && e.ProgressPercentage % 10 == 0)
{
progressPercentage = e.ProgressPercentage;
string msg = string.Format("...{0}%", e.ProgressPercentage);
UpdateCompleted(this, new ResultEventArgs(false, msg));
}
}
}
void ws_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{ {
try try
{ {
if (UpdateCompleted != null) Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
{ UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
if (e.Cancelled)
{
((WebClientEx)sender).Dispose();
TimeSpan ts = (DateTime.Now - totalDatetime);
string speed = string.Format("{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.0"));
UpdateCompleted(this, new ResultEventArgs(true, speed.PadLeft(8, ' ')));
return;
}
if (e.Error == null var client = new HttpClient(new WebRequestHandler()
|| Utils.IsNullOrEmpty(e.Error.ToString())) {
Proxy = GetWebProxy(blProxy)
});
var progress = new Progress<double>();
progress.ProgressChanged += (sender, value) =>
{
if (UpdateCompleted != null)
{ {
((WebClientEx)sender).Dispose(); string msg = string.Format("...{0}%", value);
TimeSpan ts = (DateTime.Now - totalDatetime); UpdateCompleted(this, new ResultEventArgs(value > 100 ? true : false, msg));
string speed = string.Format("{0} M/s", (totalBytesToReceive / ts.TotalMilliseconds / 1000).ToString("#0.0"));
UpdateCompleted(this, new ResultEventArgs(true, speed.PadLeft(8, ' ')));
} }
else };
{
throw e.Error; var cancellationToken = new CancellationTokenSource();
} _ = HttpClientHelper.GetInstance().DownloadFileAsync(client,
} url,
Utils.GetPath(Utils.GetDownloadFileName(url)),
progress,
cancellationToken.Token);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -129,115 +108,143 @@ namespace v2rayN.Handler
} }
} }
public async Task<string> UrlRedirectAsync(string url, bool blProxy)
{
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
WebRequestHandler webRequestHandler = new WebRequestHandler
{
AllowAutoRedirect = false,
Proxy = GetWebProxy(blProxy)
};
HttpClient client = new HttpClient(webRequestHandler);
HttpResponseMessage response = await client.GetAsync(url);
if (response.StatusCode.ToString() == "Redirect")
{
return response.Headers.Location.ToString();
}
else
{
Utils.SaveLog("StatusCode error: " + url);
return null;
}
}
/// <summary> /// <summary>
/// DownloadString /// DownloadString
/// </summary> /// </summary>
/// <param name="url"></param> /// <param name="url"></param>
public void WebDownloadString(string url, WebProxy webProxy, string userAgent) public async Task<string> DownloadStringAsync(string url, bool blProxy, string userAgent)
{ {
string source = string.Empty;
try try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13); Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
var client = new HttpClient(new WebRequestHandler()
WebClientEx ws = new WebClientEx();
ws.Encoding = Encoding.UTF8;
if (webProxy != null)
{ {
ws.Proxy = webProxy; Proxy = GetWebProxy(blProxy)
} });
if (Utils.IsNullOrEmpty(userAgent)) if (Utils.IsNullOrEmpty(userAgent))
{ {
userAgent = $"{Utils.GetVersion(false)}"; userAgent = $"{Utils.GetVersion(false)}";
} }
ws.Headers.Add("user-agent", userAgent); client.DefaultRequestHeaders.UserAgent.TryParseAdd(userAgent);
Uri uri = new Uri(url); Uri uri = new Uri(url);
//Authorization Header //Authorization Header
if (!Utils.IsNullOrEmpty(uri.UserInfo)) if (!Utils.IsNullOrEmpty(uri.UserInfo))
{ {
ws.Headers.Add(HttpRequestHeader.Authorization, "Basic " + Utils.Base64Encode(uri.UserInfo)); client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Utils.Base64Encode(uri.UserInfo));
} }
var result = await HttpClientHelper.GetInstance().GetAsync(client, url);
ws.DownloadStringCompleted += Ws_DownloadStringCompleted; return result;
ws.DownloadStringAsync(uri);
} }
catch (Exception ex) catch (Exception ex)
{ {
Utils.SaveLog(ex.Message, ex); Utils.SaveLog(ex.Message, ex);
} }
return null;
} }
private void Ws_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) public int RunAvailabilityCheck(WebProxy webProxy)
{ {
try try
{ {
if (e.Error == null if (webProxy == null)
|| Utils.IsNullOrEmpty(e.Error.ToString()))
{ {
string source = e.Result; var httpPort = LazyConfig.Instance.GetConfig().GetLocalPort(Global.InboundHttp2);
UpdateCompleted?.Invoke(this, new ResultEventArgs(true, source)); webProxy = new WebProxy(Global.Loopback, httpPort);
} }
else
Task<int> t = Task.Run(() =>
{ {
throw e.Error; try
} {
string status = GetRealPingTime(Global.SpeedPingTestUrl, webProxy, out int responseTime);
bool noError = Utils.IsNullOrEmpty(status);
return noError ? responseTime : -1;
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
return -1;
}
});
return t.Result;
} }
catch (Exception ex) catch (Exception ex)
{ {
Utils.SaveLog(ex.Message, ex); Utils.SaveLog(ex.Message, ex);
return -1;
Error?.Invoke(this, new ErrorEventArgs(ex));
} }
} }
public string WebDownloadStringSync(string url) public string GetRealPingTime(string url, WebProxy webProxy, out int responseTime)
{ {
string source = string.Empty; string msg = string.Empty;
responseTime = -1;
try try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13); HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
myHttpWebRequest.Timeout = 5000;
myHttpWebRequest.Proxy = webProxy;
WebClientEx ws = new WebClientEx(); Stopwatch timer = new Stopwatch();
ws.Encoding = Encoding.UTF8; timer.Start();
return ws.DownloadString(new Uri(url));
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
if (myHttpWebResponse.StatusCode != HttpStatusCode.OK
&& myHttpWebResponse.StatusCode != HttpStatusCode.NoContent)
{
msg = myHttpWebResponse.StatusDescription;
}
timer.Stop();
responseTime = timer.Elapsed.Milliseconds;
myHttpWebResponse.Close();
} }
catch (Exception ex) catch (Exception ex)
{ {
Utils.SaveLog(ex.Message, ex); Utils.SaveLog(ex.Message, ex);
return string.Empty; msg = ex.Message;
} }
return msg;
} }
public WebClientEx DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout) private WebProxy GetWebProxy(bool blProxy)
{ {
WebClientEx ws = new WebClientEx(); if (!blProxy)
try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13); return null;
UpdateCompleted?.Invoke(this, new ResultEventArgs(false, ResUI.Downloading));
progressPercentage = -1;
totalBytesToReceive = 0;
DownloadTimeout = downloadTimeout;
if (webProxy != null)
{
ws.Proxy = webProxy;
}
ws.DownloadProgressChanged += ws_DownloadProgressChanged;
ws.DownloadDataCompleted += ws_DownloadFileCompleted;
ws.DownloadDataAsync(new Uri(url));
} }
catch (Exception ex) var httpPort = LazyConfig.Instance.GetConfig().GetLocalPort(Global.InboundHttp2);
var webProxy = new WebProxy(Global.Loopback, httpPort);
if (RunAvailabilityCheck(webProxy) > 0)
{ {
Utils.SaveLog(ex.Message, ex); return webProxy;
Error?.Invoke(this, new ErrorEventArgs(ex));
} }
return ws;
return null;
} }
} }
} }

View File

@ -71,8 +71,8 @@ namespace v2rayN.Handler
coreType = ECoreType.v2fly, coreType = ECoreType.v2fly,
coreExes = new List<string> { "wv2ray", "v2ray" }, coreExes = new List<string> { "wv2ray", "v2ray" },
arguments = "", arguments = "",
coreUrl = Global.v2flyCoreUrl coreUrl = Global.v2flyCoreUrl,
match = "V2Ray"
}); });
coreInfos.Add(new CoreInfo coreInfos.Add(new CoreInfo
@ -80,7 +80,8 @@ namespace v2rayN.Handler
coreType = ECoreType.Xray, coreType = ECoreType.Xray,
coreExes = new List<string> { "xray" }, coreExes = new List<string> { "xray" },
arguments = "", arguments = "",
coreUrl = Global.xrayCoreUrl coreUrl = Global.xrayCoreUrl,
match = "Xray"
}); });
coreInfos.Add(new CoreInfo coreInfos.Add(new CoreInfo

View File

@ -17,12 +17,12 @@ namespace v2rayN.Handler
private List<ServerTestItem> _selecteds; private List<ServerTestItem> _selecteds;
Action<string, string> _updateFunc; Action<string, string> _updateFunc;
public SpeedtestHandler(ref Config config) public SpeedtestHandler(Config config)
{ {
_config = config; _config = config;
} }
public SpeedtestHandler(ref Config config, V2rayHandler v2rayHandler, List<VmessItem> selecteds, ESpeedActionType actionType, Action<string, string> update) public SpeedtestHandler(Config config, V2rayHandler v2rayHandler, List<VmessItem> selecteds, ESpeedActionType actionType, Action<string, string> update)
{ {
_config = config; _config = config;
_v2rayHandler = v2rayHandler; _v2rayHandler = v2rayHandler;
@ -55,7 +55,7 @@ namespace v2rayN.Handler
} }
else if (actionType == ESpeedActionType.Speedtest) else if (actionType == ESpeedActionType.Speedtest)
{ {
Task.Run(() => RunSpeedTest()); Task.Run(() => RunSpeedTestAsync());
} }
} }
@ -71,7 +71,7 @@ namespace v2rayN.Handler
} }
try try
{ {
updateFun(it); Task.Run(() => updateFun(it));
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -122,6 +122,7 @@ namespace v2rayN.Handler
return; return;
} }
DownloadHandle downloadHandle = new DownloadHandle();
//Thread.Sleep(5000); //Thread.Sleep(5000);
List<Task> tasks = new List<Task>(); List<Task> tasks = new List<Task>();
foreach (var it in _selecteds) foreach (var it in _selecteds)
@ -140,7 +141,7 @@ namespace v2rayN.Handler
{ {
WebProxy webProxy = new WebProxy(Global.Loopback, it.port); WebProxy webProxy = new WebProxy(Global.Loopback, it.port);
int responseTime = -1; int responseTime = -1;
string status = GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, out responseTime); string status = downloadHandle.GetRealPingTime(_config.constItem.speedPingTestUrl, webProxy, out responseTime);
string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status; string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, "ms") : status;
_config.GetVmessItem(it.indexId)?.SetTestResult(output); _config.GetVmessItem(it.indexId)?.SetTestResult(output);
@ -165,38 +166,7 @@ namespace v2rayN.Handler
} }
} }
public int RunAvailabilityCheck() // alias: isLive private async Task RunSpeedTestAsync()
{
try
{
int httpPort = _config.GetLocalPort(Global.InboundHttp2);
Task<int> t = Task.Run(() =>
{
try
{
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
int responseTime = -1;
string status = GetRealPingTime(Global.SpeedPingTestUrl, webProxy, out responseTime);
bool noError = Utils.IsNullOrEmpty(status);
return noError ? responseTime : -1;
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
return -1;
}
});
return t.Result;
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
return -1;
}
}
private void RunSpeedTest()
{ {
string testIndexId = string.Empty; string testIndexId = string.Empty;
int pid = -1; int pid = -1;
@ -217,10 +187,10 @@ namespace v2rayN.Handler
}; };
downloadHandle2.Error += (sender2, args) => downloadHandle2.Error += (sender2, args) =>
{ {
_updateFunc(testIndexId, args.GetException().Message); _updateFunc("", args.GetException().Message);
}; };
var timeout = 10; var timeout = 8;
foreach (var it in _selecteds) foreach (var it in _selecteds)
{ {
if (!it.allowTest) if (!it.allowTest)
@ -235,15 +205,9 @@ namespace v2rayN.Handler
if (_config.FindIndexId(it.indexId) < 0) continue; if (_config.FindIndexId(it.indexId) < 0) continue;
WebProxy webProxy = new WebProxy(Global.Loopback, it.port); WebProxy webProxy = new WebProxy(Global.Loopback, it.port);
var ws = downloadHandle2.DownloadDataAsync(url, webProxy, timeout - 2); await downloadHandle2.DownloadDataAsync(url, webProxy, timeout);
Thread.Sleep(1000 * timeout);
ws.CancelAsync();
ws.Dispose();
Thread.Sleep(1000 * 2);
} }
if (pid > 0) _v2rayHandler.V2rayStopPid(pid); if (pid > 0) _v2rayHandler.V2rayStopPid(pid);
} }
@ -282,37 +246,6 @@ namespace v2rayN.Handler
return responseTime; return responseTime;
} }
private string GetRealPingTime(string url, WebProxy webProxy, out int responseTime)
{
string msg = string.Empty;
responseTime = -1;
try
{
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(url);
myHttpWebRequest.Timeout = 5000;
myHttpWebRequest.Proxy = webProxy;//new WebProxy(Global.Loopback, Global.httpPort);
Stopwatch timer = new Stopwatch();
timer.Start();
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();
if (myHttpWebResponse.StatusCode != HttpStatusCode.OK
&& myHttpWebResponse.StatusCode != HttpStatusCode.NoContent)
{
msg = myHttpWebResponse.StatusDescription;
}
timer.Stop();
responseTime = timer.Elapsed.Milliseconds;
myHttpWebResponse.Close();
}
catch (Exception ex)
{
Utils.SaveLog(ex.Message, ex);
msg = ex.Message;
}
return msg;
}
private string FormatOut(object time, string unit) private string FormatOut(object time, string unit)
{ {
if (time.ToString().Equals("-1")) if (time.ToString().Equals("-1"))

View File

@ -1,10 +1,9 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net;
using System.Net.Http;
using System.Text; using System.Text;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.Mode; using v2rayN.Mode;
@ -177,67 +176,49 @@ namespace v2rayN.Handler
return; return;
} }
for (int k = 1; k <= config.subItem.Count; k++) Task.Run(async () =>
{ {
string id = config.subItem[k - 1].id.TrimEx(); foreach (var item in config.subItem)
string url = config.subItem[k - 1].url.TrimEx();
string userAgent = config.subItem[k - 1].userAgent.TrimEx();
string groupId = config.subItem[k - 1].groupId.TrimEx();
string hashCode = $"{k}){config.subItem[k - 1].remarks}->";
if (config.subItem[k - 1].enabled == false)
{ {
continue; if (item.enabled == false)
}
if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url))
{
_updateFunc(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
continue;
}
DownloadHandle downloadHandle3 = new DownloadHandle();
downloadHandle3.UpdateCompleted += (sender2, args) =>
{
if (args.Success)
{ {
_updateFunc(false, $"{hashCode}{ResUI.MsgGetSubscriptionSuccessfully}"); continue;
//string result = Utils.Base64Decode(args.Msg); }
string result = args.Msg; string id = item.id.TrimEx();
if (Utils.IsNullOrEmpty(result)) string url = item.url.TrimEx();
{ string userAgent = item.userAgent.TrimEx();
_updateFunc(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}"); string groupId = item.groupId.TrimEx();
return; string hashCode = $"{item.remarks}->";
} if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url))
{
//_updateFunc(false, $"{hashCode}{ResUI.MsgNoValidSubscription}");
continue;
}
//ConfigHandler.RemoveServerViaSubid(ref config, id); _updateFunc(false, $"{hashCode}{ResUI.MsgStartGettingSubscriptions}");
//_updateFunc(false, $"{hashCode}{ResUI.MsgClearSubscription")}"); var result = await (new DownloadHandle()).DownloadStringAsync(url, blProxy, userAgent);
// RefreshServers();
_updateFunc(false, $"{hashCode}{ResUI.MsgGetSubscriptionSuccessfully}");
if (Utils.IsNullOrEmpty(result))
{
_updateFunc(false, $"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}");
}
else
{
int ret = ConfigHandler.AddBatchServers(ref config, result, id, groupId); int ret = ConfigHandler.AddBatchServers(ref config, result, id, groupId);
if (ret > 0) if (ret > 0)
{ {
// RefreshServers(); _updateFunc(false, $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}");
} }
else else
{ {
_updateFunc(false, $"{hashCode}{ResUI.MsgFailedImportSubscription}"); _updateFunc(false, $"{hashCode}{ResUI.MsgFailedImportSubscription}");
} }
_updateFunc(true, $"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}");
} }
else _updateFunc(false, $"-------------------------------------------------------");
{ }
_updateFunc(false, args.Msg); _updateFunc(true, $"{ResUI.MsgUpdateSubscriptionEnd}");
} });
};
downloadHandle3.Error += (sender2, args) =>
{
_updateFunc(false, args.GetException().Message);
};
WebProxy webProxy = blProxy ? new WebProxy(Global.Loopback, _config.GetLocalPort(Global.InboundHttp2)) : null;
downloadHandle3.WebDownloadString(url, webProxy, userAgent);
_updateFunc(false, $"{hashCode}{ResUI.MsgStartGettingSubscriptions}");
}
} }
@ -269,8 +250,8 @@ namespace v2rayN.Handler
File.Delete(targetPath); File.Delete(targetPath);
} }
File.Move(fileName, targetPath); File.Move(fileName, targetPath);
_updateFunc(true, ""); //_updateFunc(true, "");
} }
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -287,8 +268,8 @@ namespace v2rayN.Handler
_updateFunc(false, args.GetException().Message); _updateFunc(false, args.GetException().Message);
}; };
} }
askToDownload(downloadHandle, url, false); askToDownload(downloadHandle, url, false);
} }
#region private #region private
@ -297,19 +278,6 @@ namespace v2rayN.Handler
{ {
try try
{ {
Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().enableSecurityProtocolTls13);
WebRequestHandler webRequestHandler = new WebRequestHandler
{
AllowAutoRedirect = false
};
if (httpProxyTest() > 0)
{
int httpPort = _config.GetLocalPort(Global.InboundHttp2);
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
webRequestHandler.Proxy = webProxy;
}
HttpClient httpClient = new HttpClient(webRequestHandler);
string url; string url;
if (type == ECoreType.v2fly) if (type == ECoreType.v2fly)
{ {
@ -327,10 +295,11 @@ namespace v2rayN.Handler
{ {
throw new ArgumentException("Type"); throw new ArgumentException("Type");
} }
HttpResponseMessage response = await httpClient.GetAsync(url);
if (response.StatusCode.ToString() == "Redirect") var result = await (new DownloadHandle()).UrlRedirectAsync(url, true);
if (!Utils.IsNullOrEmpty(result))
{ {
responseHandler(type, response.Headers.Location.ToString()); responseHandler(type, result);
} }
else else
{ {
@ -352,19 +321,20 @@ namespace v2rayN.Handler
{ {
try try
{ {
var core = string.Empty;
var match = string.Empty; var coreInfo = LazyConfig.Instance.GetCoreInfo(type);
if (type == ECoreType.v2fly) string filePath = string.Empty;
foreach (string name in coreInfo.coreExes)
{ {
core = "v2ray.exe"; string vName = string.Format("{0}.exe", name);
match = "V2Ray"; vName = Utils.GetPath(vName);
if (File.Exists(vName))
{
filePath = vName;
break;
}
} }
else if (type == ECoreType.Xray)
{
core = "xray.exe";
match = "Xray";
}
string filePath = Utils.GetPath(core);
if (!File.Exists(filePath)) if (!File.Exists(filePath))
{ {
string msg = string.Format(ResUI.NotFoundCore, @""); string msg = string.Format(ResUI.NotFoundCore, @"");
@ -383,7 +353,7 @@ namespace v2rayN.Handler
p.Start(); p.Start();
p.WaitForExit(5000); p.WaitForExit(5000);
string echo = p.StandardOutput.ReadToEnd(); string echo = p.StandardOutput.ReadToEnd();
string version = Regex.Match(echo, $"{match} ([0-9.]+) \\(").Groups[1].Value; string version = Regex.Match(echo, $"{coreInfo.match} ([0-9.]+) \\(").Groups[1].Value;
return version; return version;
} }
catch (Exception ex) catch (Exception ex)
@ -458,24 +428,9 @@ namespace v2rayN.Handler
} }
if (blDownload) if (blDownload)
{ {
if (httpProxyTest() > 0) downloadHandle.DownloadFileAsync(url, true, 600);
{
int httpPort = _config.GetLocalPort(Global.InboundHttp2);
WebProxy webProxy = new WebProxy(Global.Loopback, httpPort);
downloadHandle.DownloadFileAsync(url, webProxy, 600);
}
else
{
downloadHandle.DownloadFileAsync(url, null, 600);
}
} }
} }
private int httpProxyTest()
{
SpeedtestHandler statistics = new SpeedtestHandler(ref _config);
return statistics.RunAvailabilityCheck();
}
#endregion #endregion
} }
} }

View File

@ -13,5 +13,7 @@ namespace v2rayN.Mode
public string arguments { get; set; } public string arguments { get; set; }
public string coreUrl { get; set; } public string coreUrl { get; set; }
public string match { get; set; }
} }
} }

View File

@ -99,6 +99,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Base\HttpClientHelper.cs" />
<Compile Include="Base\ListViewFlickerFree.cs"> <Compile Include="Base\ListViewFlickerFree.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
@ -195,9 +196,6 @@
<Compile Include="Handler\StatisticsHandler.cs" /> <Compile Include="Handler\StatisticsHandler.cs" />
<Compile Include="Handler\DownloadHandle.cs" /> <Compile Include="Handler\DownloadHandle.cs" />
<Compile Include="Handler\ProxySetting.cs" /> <Compile Include="Handler\ProxySetting.cs" />
<Compile Include="Base\WebClientEx.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Handler\SysProxyHandle.cs" /> <Compile Include="Handler\SysProxyHandle.cs" />
<Compile Include="Mode\ESpeedActionType.cs" /> <Compile Include="Mode\ESpeedActionType.cs" />
<Compile Include="Mode\EGlobalHotkey.cs" /> <Compile Include="Mode\EGlobalHotkey.cs" />