Compare commits

...
11 Commits
Author SHA1 Message Date
noisyfox efc486c733 Update CHANGES and bump version 2016-12-13 21:08:32 +11:00
noisyfox b7b92a4af9 Very rarely used regex, do not compile 2016-12-13 20:47:39 +11:00
noisyfox a447feece2 Adjust qrcode display 2016-12-13 20:43:51 +11:00
noisyfox 2a0dd88525 Add import URL from clipboard 2016-12-13 02:52:58 +11:00
noisyfox 5650b1d847 Use compiled regex 2016-12-13 02:42:08 +11:00
noisyfox b972cb250b Don't zoom QRCode 2016-12-13 02:31:01 +11:00
noisyfox f363b94fd6 Show ss URL in QRCode form 2016-12-13 02:22:37 +11:00
noisyfox a08993519f Handle request line correctlly
This coudl fix #937
2016-12-12 23:53:15 +11:00
noisyfox 8a68a3515b Check server url before saving it
Don't clear the textbox, focus it instead. We want the user to see the wrong input instead of a blank textbox.
2016-12-10 01:50:28 +11:00
noisyfox 76fbd808e3 Add menu item to copy local pac url 2016-12-10 01:26:40 +11:00
noisyfox 557c797a9a Refine code 2016-12-10 00:59:57 +11:00
14 changed files with 139 additions and 47 deletions
+7
View File
@@ -1,3 +1,10 @@
3.4.1 (pre-release) 2016-12-13
- Fix crash if user input an invaild server address. (#933)
- Fix ERR_TOO_MANY_REDIRECTS with http proxy. (#937)
- Show SS URL in QRCode form.
- Add import URL from clipboard.
- Bug fixes and improvements.
3.4.0 (pre-release) 2016-12-9
- Replace Privoxy with built-in http proxy.
- Try fix system proxy settings on windows 10 insider preview.
@@ -64,7 +64,7 @@ namespace Shadowsocks.Controller.Service
Close();
}
private static readonly Regex HttpRequestHeaderRegex = new Regex(@"^([A-Z]+?) ([^\s]+) HTTP/1\.\d$");
private static readonly Regex HttpRequestHeaderRegex = new Regex(@"^(?<method>[A-Z]+?) (?<path>[^\s]+) (?<tail>HTTP/1\.\d)$", RegexOptions.Compiled);
private int _requestLineCount = 0;
private bool _isConnect = false;
@@ -101,31 +101,57 @@ namespace Shadowsocks.Controller.Service
Logging.Debug(line);
if (!line.StartsWith("Proxy-"))
{
_headers.Enqueue(line);
}
if (_requestLineCount == 0)
{
var m = HttpRequestHeaderRegex.Match(line);
if (m.Success)
{
var method = m.Groups[1].Value;
var method = m.Groups["method"].Value;
var path = m.Groups["path"].Value;
if (method == "CONNECT")
{
_isConnect = true;
if (!ParseHost(m.Groups[2].Value))
if (!ParseHost(path))
{
throw new Exception("Bad http header: " + line);
}
}
else
{
var targetUrl = new Uri(path);
if (!ParseHost(targetUrl.Authority))
{
throw new Exception("Bad http header: " + line);
}
var newRequestLine = $"{method} {targetUrl.PathAndQuery} {m.Groups["tail"].Value}";
_headers.Enqueue(newRequestLine);
}
}
else
{
throw new FormatException("Not a vaild request line");
}
}
else
{
// Handle Proxy-x Headers
if (!line.StartsWith("Proxy-"))
{
_headers.Enqueue(line);
}
else
{
if (line.StartsWith("Proxy-Connection: "))
{
_headers.Enqueue(line.Substring(6));
}
}
if (line.IsNullOrEmpty())
{
return true;
@@ -18,7 +18,9 @@ namespace Shadowsocks.Controller
public const string USER_RULE_FILE = "user-rule.txt";
public const string USER_ABP_FILE = "abp.txt";
public string PacSecret { get; private set; } = "";
private string PacSecret { get; set; } = "";
public string PacUrl { get; private set; } = "";
FileSystemWatcher PACFileWatcher;
FileSystemWatcher UserRuleFileWatcher;
@@ -47,6 +49,14 @@ namespace Shadowsocks.Controller
{
PacSecret = "";
}
PacUrl = $"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{PacSecret}";
}
private static string GetTimestamp(DateTime value)
{
return value.ToString("yyyyMMddHHmmssfff");
}
public override bool Handle(byte[] firstPacket, int length, Socket socket, object state)
@@ -24,7 +24,7 @@ namespace Shadowsocks.Controller
public string LatestVersionLocalName;
public event EventHandler CheckUpdateCompleted;
public const string Version = "3.4.0";
public const string Version = "3.4.1";
private class CheckUpdateTimer : System.Timers.Timer
{
@@ -176,10 +176,10 @@ namespace Shadowsocks.Controller
private void SortByVersions(List<Asset> asserts)
{
asserts.Sort(new VersionComparer());
asserts.Sort();
}
public class Asset
public class Asset : IComparable<Asset>
{
public bool prerelease;
public string name;
@@ -243,14 +243,10 @@ namespace Shadowsocks.Controller
}
return 0;
}
}
class VersionComparer : IComparer<Asset>
{
// Calls CaseInsensitiveComparer.Compare with the parameters reversed.
public int Compare(Asset x, Asset y)
public int CompareTo(Asset other)
{
return Asset.CompareVersion(x.version, y.version);
return CompareVersion(version, other.version);
}
}
}
@@ -6,6 +6,7 @@ using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Web;
using System.Windows.Forms;
using Newtonsoft.Json;
using Shadowsocks.Controller.Service;
using Shadowsocks.Controller.Strategy;
@@ -575,6 +576,11 @@ namespace Shadowsocks.Controller
File.WriteAllText(PACServer.PAC_FILE, abpContent, Encoding.UTF8);
}
public void CopyPacUrl()
{
Clipboard.SetDataObject(_pacServer.PacUrl);
}
#region Memory Management
private void StartReleasingMemory()
@@ -38,8 +38,7 @@ namespace Shadowsocks.Controller
}
else
{
pacUrl =
$"http://127.0.0.1:{config.localPort}/pac?t={GetTimestamp(DateTime.Now)}{pacSrv.PacSecret}";
pacUrl = pacSrv.PacUrl;
}
Sysproxy.SetIEProxy(true, false, "", pacUrl);
}
+5 -2
View File
@@ -20,8 +20,10 @@ Edit Local PAC File...=编辑本地 PAC 文件...
Update Local PAC from GFWList=从 GFWList 更新本地 PAC
Edit User Rule for GFWList...=编辑 GFWList 的用户规则...
Secure Local PAC=保护本地 PAC
Show QRCode...=显示二维码...
Copy Local PAC URL=复制本地 PAC 网址
Share Server Config...=分享服务器配置...
Scan QRCode from Screen...=扫描屏幕上的二维码...
Import URL from Clipboard...=从剪贴板导入URL...
Availability Statistics=统计可用性
Show Logs...=显示日志...
Verbose Logging=详细记录日志
@@ -82,7 +84,7 @@ Outbound=出站
# QRCode Form
QRCode=二维码
QRCode and URL=二维码与 URL
# PAC Url Form
@@ -104,6 +106,7 @@ Reg All=注册全部热键
Shadowsocks Error: {0}=Shadowsocks 错误: {0}
Port already in use=端口已被占用
Invalid server address=非法服务器地址
Illegal port number format=非法端口格式
Illegal timeout format=非法超时格式
Please add at least one server=请添加至少一个服务器
+5 -2
View File
@@ -20,8 +20,10 @@ Edit Local PAC File...=編輯本地 PAC 文件...
Update Local PAC from GFWList=從 GFWList 更新本地 PAC
Edit User Rule for GFWList...=編輯 GFWList 的用戶規則...
Secure Local PAC=保護本地 PAC
Show QRCode...=顯示 QR 碼...
Copy Local PAC URL=複製本地 PAC 網址
Share Server Config...=分享伺服器配置...
Scan QRCode from Screen...=掃描螢幕上的 QR 碼...
Import URL from Clipboard...=從剪貼板導入URL...
Availability Statistics=統計可用性
Show Logs...=顯示日誌...
Verbose Logging=詳細記錄日誌
@@ -82,7 +84,7 @@ Outbound=出站
# QRCode Form
QRCode=QR 碼
QRCode and URL=QR 碼与 URL
# PAC Url Form
@@ -104,6 +106,7 @@ Reg All=註冊全部捷徑鍵
Shadowsocks Error: {0}=Shadowsocks 錯誤: {0}
Port already in use=連接埠號碼已被占用
Invalid server address=非法伺服器位址
Illegal port number format=非法連接埠號碼格式
Illegal timeout format=非法超時格式
Please add at least one server=請新增至少一個伺服器
+1 -1
View File
@@ -165,7 +165,7 @@ namespace Shadowsocks.ForwardProxy
st.innerState.ex = ex;
}
private static readonly Regex HttpRespondHeaderRegex = new Regex(@"^(HTTP/1\.\d) (\d{3}) (.+)$");
private static readonly Regex HttpRespondHeaderRegex = new Regex(@"^(HTTP/1\.\d) (\d{3}) (.+)$", RegexOptions.Compiled);
private int _respondLineCount = 0;
private bool _established = false;
+2 -3
View File
@@ -10,10 +10,9 @@ namespace Shadowsocks.Model
public class Server
{
public static readonly Regex
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
UrlFinder = new Regex("^(?i)ss://([A-Za-z0-9+-/=_]+)(#(.+))?$", RegexOptions.IgnoreCase),
DetailsParser = new Regex("^((?<method>.+?)(?<auth>-auth)??:(?<password>.*)@(?<hostname>.+?)" +
":(?<port>\\d+?))$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
":(?<port>\\d+?))$", RegexOptions.IgnoreCase);
private const int DefaultServerTimeoutSec = 5;
public const int MaxServerTimeoutSec = 20;
+9 -11
View File
@@ -80,28 +80,26 @@ namespace Shadowsocks.View
return true;
}
Server server = new Server();
server.server = IPTextBox.Text.Trim();
try
if (Uri.CheckHostName(server.server = IPTextBox.Text.Trim()) == UriHostNameType.Unknown)
{
server.server_port = int.Parse(ServerPortTextBox.Text);
MessageBox.Show(I18N.GetString("Invalid server address"));
IPTextBox.Focus();
return false;
}
catch (FormatException)
if (!int.TryParse(ServerPortTextBox.Text, out server.server_port))
{
MessageBox.Show(I18N.GetString("Illegal port number format"));
ServerPortTextBox.Clear();
ServerPortTextBox.Focus();
return false;
}
server.password = PasswordTextBox.Text;
server.method = EncryptionSelect.Text;
server.remarks = RemarksTextBox.Text;
try
{
server.timeout = int.Parse(TimeoutTextBox.Text);
}
catch (FormatException)
if (!int.TryParse(TimeoutTextBox.Text, out server.timeout))
{
MessageBox.Show(I18N.GetString("Illegal timeout format"));
TimeoutTextBox.Clear();
TimeoutTextBox.Focus();
return false;
}
server.auth = OneTimeAuth.Checked;
+20 -3
View File
@@ -261,8 +261,10 @@ namespace Shadowsocks.View
this.SeperatorItem = new MenuItem("-"),
this.ConfigItem = CreateMenuItem("Edit Servers...", new EventHandler(this.Config_Click)),
CreateMenuItem("Statistics Config...", StatisticsConfigItem_Click),
CreateMenuItem("Show QRCode...", new EventHandler(this.QRCodeItem_Click)),
CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click))
new MenuItem("-"),
CreateMenuItem("Share Server Config...", new EventHandler(this.QRCodeItem_Click)),
CreateMenuItem("Scan QRCode from Screen...", new EventHandler(this.ScanQRCodeItem_Click)),
CreateMenuItem("Import URL from Clipboard...", new EventHandler(this.ImportURLItem_Click))
}),
CreateMenuGroup("PAC ", new MenuItem[] {
this.localPACItem = CreateMenuItem("Local PAC", new EventHandler(this.LocalPACItem_Click)),
@@ -271,8 +273,9 @@ namespace Shadowsocks.View
this.editLocalPACItem = CreateMenuItem("Edit Local PAC File...", new EventHandler(this.EditPACFileItem_Click)),
this.updateFromGFWListItem = CreateMenuItem("Update Local PAC from GFWList", new EventHandler(this.UpdatePACFromGFWListItem_Click)),
this.editGFWUserRuleItem = CreateMenuItem("Edit User Rule for GFWList...", new EventHandler(this.EditUserRuleFileForGFWListItem_Click)),
this.editOnlinePACItem = CreateMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)),
this.secureLocalPacUrlToggleItem = CreateMenuItem("Secure Local PAC", new EventHandler(this.SecureLocalPacUrlToggleItem_Click)),
CreateMenuItem("Copy Local PAC URL", new EventHandler(this.CopyLocalPacUrlItem_Click)),
this.editOnlinePACItem = CreateMenuItem("Edit Online PAC URL...", new EventHandler(this.UpdateOnlinePACURLItem_Click)),
}),
this.proxyItem = CreateMenuItem("Forward Proxy...", new EventHandler(this.proxyItem_Click)),
new MenuItem("-"),
@@ -738,6 +741,15 @@ namespace Shadowsocks.View
MessageBox.Show(I18N.GetString("No QRCode found. Try to zoom in or move it to the center of the screen."));
}
private void ImportURLItem_Click(object sender, EventArgs e)
{
var success = controller.AddServerBySSURL(Clipboard.GetText(TextDataFormat.Text));
if (success)
{
ShowConfigForm();
}
}
void splash_FormClosed(object sender, FormClosedEventArgs e)
{
ShowConfigForm();
@@ -805,6 +817,11 @@ namespace Shadowsocks.View
controller.ToggleSecureLocalPac(!configuration.secureLocalPac);
}
private void CopyLocalPacUrlItem_Click(object sender, EventArgs e)
{
controller.CopyPacUrl();
}
private void UpdatePACItemsEnabledStatus()
{
if (this.localPACItem.Checked)
+16 -3
View File
@@ -30,6 +30,7 @@
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.textBoxURL = new System.Windows.Forms.TextBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
@@ -39,7 +40,7 @@
this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(210, 210);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.CenterImage;
this.pictureBox1.TabIndex = 1;
this.pictureBox1.TabStop = false;
//
@@ -56,6 +57,15 @@
this.listBox1.ValueMember = "Key";
this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
// textBoxURL
//
this.textBoxURL.Location = new System.Drawing.Point(10, 227);
this.textBoxURL.Name = "textBoxURL";
this.textBoxURL.ReadOnly = true;
this.textBoxURL.Size = new System.Drawing.Size(441, 21);
this.textBoxURL.TabIndex = 3;
this.textBoxURL.Click += new System.EventHandler(this.textBoxURL_Click);
//
// QRCodeForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@@ -63,7 +73,8 @@
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(457, 228);
this.ClientSize = new System.Drawing.Size(457, 257);
this.Controls.Add(this.textBoxURL);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.pictureBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
@@ -72,10 +83,11 @@
this.Name = "QRCodeForm";
this.Padding = new System.Windows.Forms.Padding(10);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "QRCode";
this.Text = "QRCode and URL";
this.Load += new System.EventHandler(this.QRCodeForm_Load);
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
@@ -83,5 +95,6 @@
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TextBox textBoxURL;
}
}
+17 -2
View File
@@ -24,7 +24,7 @@ namespace Shadowsocks.View
this.code = code;
InitializeComponent();
this.Icon = Icon.FromHandle(Resources.ssw128.GetHicon());
this.Text = I18N.GetString("QRCode");
this.Text = I18N.GetString("QRCode and URL");
}
private void GenQR(string ssconfig)
@@ -33,6 +33,14 @@ namespace Shadowsocks.View
QRCode code = ZXing.QrCode.Internal.Encoder.encode(qrText, ErrorCorrectionLevel.M);
ByteMatrix m = code.Matrix;
int blockSize = Math.Max(pictureBox1.Height/m.Height, 1);
var qrWidth = m.Width*blockSize;
var qrHeight = m.Height*blockSize;
var dWidth = pictureBox1.Width - qrWidth;
var dHeight = pictureBox1.Height - qrHeight;
var maxD = Math.Max(dWidth, dHeight);
pictureBox1.SizeMode = maxD >= 7*blockSize ? PictureBoxSizeMode.Zoom : PictureBoxSizeMode.CenterImage;
Bitmap drawArea = new Bitmap((m.Width*blockSize), (m.Height*blockSize));
using (Graphics g = Graphics.FromImage(drawArea))
{
@@ -69,7 +77,14 @@ namespace Shadowsocks.View
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
GenQR((sender as ListBox)?.SelectedValue.ToString());
var url = (sender as ListBox)?.SelectedValue.ToString();
GenQR(url);
textBoxURL.Text = url;
}
private void textBoxURL_Click(object sender, EventArgs e)
{
textBoxURL.SelectAll();
}
}
}