Settings: Saving proxy fails silently
[TortoiseGit.git] / src / TortoiseProc / Settings / SetProxyPage.cpp
blob4fb9f7a6c5bb0a8008109599b7bb92bc22246106
1 // TortoiseGit - a Windows shell extension for easy version control
3 // Copyright (C) 2010-2017 - TortoiseGit
4 // Copyright (C) 2003-2007 - TortoiseSVN
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software Foundation,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "stdafx.h"
21 #include "TortoiseProc.h"
22 #include "SetProxyPage.h"
23 #include "AppUtils.h"
24 #include "StringUtils.h"
25 #include "Git.h"
26 #include "SetProxyPage.h"
28 IMPLEMENT_DYNAMIC(CSetProxyPage, ISettingsPropPage)
29 CSetProxyPage::CSetProxyPage()
30 : ISettingsPropPage(CSetProxyPage::IDD)
31 , m_serverport(0)
32 , m_isEnabled(FALSE)
34 m_regServeraddress = CRegString(L"Software\\TortoiseGit\\Git\\Servers\\global\\http-proxy-host", L"");
35 m_regServerport = CRegString(L"Software\\TortoiseGit\\Git\\Servers\\global\\http-proxy-port", L"");
36 m_regUsername = CRegString(L"Software\\TortoiseGit\\Git\\Servers\\global\\http-proxy-username", L"");
37 m_regPassword = CRegString(L"Software\\TortoiseGit\\Git\\Servers\\global\\http-proxy-password", L"");
38 m_regSSHClient = CRegString(L"Software\\TortoiseGit\\SSH");
39 m_SSHClient = m_regSSHClient;
42 CSetProxyPage::~CSetProxyPage()
46 void CSetProxyPage::DoDataExchange(CDataExchange* pDX)
48 ISettingsPropPage::DoDataExchange(pDX);
49 DDX_Text(pDX, IDC_SERVERADDRESS, m_serveraddress);
50 DDX_Text(pDX, IDC_SERVERPORT, m_serverport);
51 DDX_Text(pDX, IDC_USERNAME, m_username);
52 DDX_Text(pDX, IDC_PASSWORD, m_password);
53 DDX_Check(pDX, IDC_ENABLE, m_isEnabled);
54 DDX_Text(pDX, IDC_SSHCLIENT, m_SSHClient);
55 DDX_Control(pDX, IDC_SSHCLIENT, m_cSSHClientEdit);
59 BEGIN_MESSAGE_MAP(CSetProxyPage, ISettingsPropPage)
60 ON_EN_CHANGE(IDC_SERVERADDRESS, OnChange)
61 ON_EN_CHANGE(IDC_SERVERPORT, OnChange)
62 ON_EN_CHANGE(IDC_USERNAME, OnChange)
63 ON_EN_CHANGE(IDC_PASSWORD, OnChange)
64 ON_EN_CHANGE(IDC_SSHCLIENT, OnChange)
65 ON_BN_CLICKED(IDC_ENABLE, OnBnClickedEnable)
66 ON_BN_CLICKED(IDC_SSHBROWSE, OnBnClickedSshbrowse)
67 END_MESSAGE_MAP()
69 HRESULT StringEscape(const CString& str_in, CString* escaped_string) {
70 // http://tools.ietf.org/html/rfc3986#section-3.2.1
71 if (!escaped_string)
72 return E_INVALIDARG;
74 DWORD buf_len = INTERNET_MAX_URL_LENGTH + 1;
75 HRESULT hr = ::UrlEscape(str_in, CStrBuf(*escaped_string, buf_len), &buf_len, URL_ESCAPE_PERCENT | URL_ESCAPE_SEGMENT_ONLY);
77 escaped_string->Replace(L"@", L"%40");
78 escaped_string->Replace(L":", L"%3a");
80 return hr;
83 HRESULT StringUnescape(const CString& str_in, CString* unescaped_string) {
84 if (!unescaped_string)
85 return E_INVALIDARG;
87 DWORD buf_len = INTERNET_MAX_URL_LENGTH + 1;
88 ATL::CComBSTR temp(str_in);
89 return ::UrlUnescape(temp, CStrBuf(*unescaped_string, buf_len), &buf_len, 0);
92 BOOL CSetProxyPage::OnInitDialog()
94 ISettingsPropPage::OnInitDialog();
96 AdjustControlSize(IDC_ENABLE);
98 m_tooltips.AddTool(IDC_SERVERADDRESS, IDS_SETTINGS_PROXYSERVER_TT);
100 CString proxy = g_Git.GetConfigValue(L"http.proxy");
102 m_SSHClient = m_regSSHClient;
103 if (m_SSHClient.IsEmpty())
104 m_SSHClient = CRegString(L"Software\\TortoiseGit\\SSH", L"", FALSE, HKEY_LOCAL_MACHINE);
105 if (m_SSHClient.IsEmpty())
107 TCHAR sPlink[MAX_PATH] = {0};
108 GetModuleFileName(nullptr, sPlink, _countof(sPlink));
109 LPTSTR ptr = wcsrchr(sPlink, L'\\');
110 if (ptr)
112 wcscpy_s(ptr + 1, _countof(sPlink) - (ptr - sPlink + 1), L"TortoiseGitPlink.exe");
113 m_SSHClient = CString(sPlink);
116 m_serveraddress = m_regServeraddress;
117 m_serverport = _wtoi((LPCTSTR)(CString)m_regServerport);
118 m_username = m_regUsername;
119 m_password = m_regPassword;
121 if (proxy.IsEmpty())
123 m_isEnabled = FALSE;
124 EnableGroup(FALSE);
126 else
128 int start=0;
129 start = proxy.Find(L"://", start);
130 if(start<0)
131 start =0;
132 else
133 start+=3;
135 int at = proxy.Find(L'@');
136 int port;
138 if(at<0)
140 m_username.Empty();
141 m_password.Empty();
142 port = proxy.Find(L':', start);
143 if(port<0)
144 m_serveraddress = proxy.Mid(start);
145 else
146 m_serveraddress = proxy.Mid(start, port-start);
149 else
151 int username;
152 username = proxy.Find(L':', start);
153 if(username<=0 || username >at)
155 StringUnescape(proxy.Mid(start, at - start), &m_username);
156 m_password.Empty();
158 else if(username < at)
160 StringUnescape(proxy.Mid(start, username - start), &m_username);
161 StringUnescape(proxy.Mid(username + 1, at - username - 1), &m_password);
164 port = proxy.Find(L':', at);
165 if(port<0)
166 m_serveraddress = proxy.Mid(at+1);
167 else
168 m_serveraddress = proxy.Mid(at+1, port-at-1);
171 if(port<0)
172 m_serverport= 0;
173 else
174 m_serverport = _wtoi(proxy.Mid(port + 1));
176 m_isEnabled = TRUE;
177 EnableGroup(TRUE);
180 SHAutoComplete(::GetDlgItem(m_hWnd, IDC_SSHCLIENT), SHACF_FILESYSTEM | SHACF_FILESYS_ONLY);
182 UpdateData(FALSE);
184 return TRUE;
187 void CSetProxyPage::OnBnClickedEnable()
189 UpdateData();
190 if (m_isEnabled)
191 EnableGroup(TRUE);
192 else
193 EnableGroup(FALSE);
194 SetModified();
197 void CSetProxyPage::EnableGroup(BOOL b)
199 GetDlgItem(IDC_SERVERADDRESS)->EnableWindow(b);
200 GetDlgItem(IDC_SERVERPORT)->EnableWindow(b);
201 GetDlgItem(IDC_USERNAME)->EnableWindow(b);
202 GetDlgItem(IDC_PASSWORD)->EnableWindow(b);
203 GetDlgItem(IDC_PROXYLABEL1)->EnableWindow(b);
204 GetDlgItem(IDC_PROXYLABEL2)->EnableWindow(b);
205 GetDlgItem(IDC_PROXYLABEL3)->EnableWindow(b);
206 GetDlgItem(IDC_PROXYLABEL6)->EnableWindow(b);
209 void CSetProxyPage::OnChange()
211 SetModified();
214 BOOL CSetProxyPage::OnApply()
216 UpdateData();
218 CString temp;
219 Store(m_serveraddress, m_regServeraddress);
220 temp.Format(L"%u", m_serverport);
221 Store(temp, m_regServerport);
222 Store(m_username, m_regUsername);
223 Store(m_password, m_regPassword);
226 CString http_proxy;
227 if(!m_serveraddress.IsEmpty())
229 if (m_serveraddress.Find(L"://") == -1)
230 http_proxy = L"http://";
232 if(!m_username.IsEmpty())
234 CString escapedUsername;
236 if (FAILED(StringEscape(m_username, &escapedUsername)))
238 ::MessageBox(nullptr, L"Could not encode username.", L"TortoiseGit", MB_ICONERROR);
239 return FALSE;
242 http_proxy += escapedUsername;
244 if(!m_password.IsEmpty())
246 CString escapedPassword;
247 if (FAILED(StringEscape(m_password, &escapedPassword)))
249 ::MessageBox(nullptr, L"Could not encode password.", L"TortoiseGit", MB_ICONERROR);
250 return FALSE;
252 http_proxy += L':' + escapedPassword;
255 http_proxy += L'@';
257 http_proxy+=m_serveraddress;
259 if(m_serverport)
261 http_proxy += L':';
262 http_proxy.AppendFormat(L"%u", m_serverport);
266 if (m_isEnabled)
268 if (g_Git.SetConfigValue(L"http.proxy",http_proxy,CONFIG_GLOBAL))
269 return FALSE;
271 else
272 g_Git.UnsetConfigValue(L"http.proxy", CONFIG_GLOBAL);
273 m_regSSHClient = m_SSHClient;
274 SetModified(FALSE);
275 return ISettingsPropPage::OnApply();
278 void CSetProxyPage::OnBnClickedSshbrowse()
280 UpdateData();
281 CString filename = m_SSHClient;
282 if (!PathFileExists(filename))
283 filename.Empty();
284 if (CAppUtils::FileOpenSave(filename, nullptr, IDS_SETTINGS_SELECTSSH, IDS_PROGRAMSFILEFILTER, true, m_hWnd))
286 m_SSHClient = filename;
287 UpdateData(FALSE);
288 SetModified();