Mantid
Loading...
Searching...
No Matches
NetworkProxyWin.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7// Only compile on windows.
8#if defined(_WIN32) || defined(_WIN64)
9
12// std
13#include <sstream>
14// windows
15#include <Winhttp.h>
16#include <windows.h>
17
18namespace Mantid {
19namespace Kernel {
20
21bool get_proxy_configuration_win(const std::string &target_url, std::string &proxy_str, std::string &err_msg) {
22 HINTERNET hSession = NULL;
23 std::wstring proxy;
24 std::wstring wtarget_url;
25 if (target_url.find("http://") == std::string::npos) {
26 wtarget_url = L"http://";
27 }
28 wtarget_url += std::wstring(target_url.begin(), target_url.end());
29 bool fail = false;
30 std::stringstream info;
31 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy;
32 WINHTTP_AUTOPROXY_OPTIONS proxy_options;
33 WINHTTP_PROXY_INFO proxy_info;
34 ZeroMemory(&proxy_options, sizeof(proxy_options));
35 ZeroMemory(&ie_proxy, sizeof(ie_proxy));
36 ZeroMemory(&proxy_info, sizeof(proxy_info));
37
38 // the loop is just to allow us to go out of this session whenever we want
39 while (true) {
40 // Use WinHttpOpen to obtain a session handle.
41 hSession = WinHttpOpen(L"NetworkProxyWin FindingProxy/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
42 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
43 if (!hSession) {
44 fail = true;
45 info << "Failed to create the session (Error Code: " << GetLastError() << ").";
46 break;
47 }
48 // get the configuration of the web browser
49 if (!WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy)) {
50 fail = true;
51 info << "Could not find the proxy settings (Error code :" << GetLastError();
52 break;
53 }
54
55 if (ie_proxy.lpszProxy) {
56 // the proxy was already given,
57 // it is not necessary to query the system for the auto proxy
58 proxy = ie_proxy.lpszProxy;
59 break;
60 }
61
62 if (ie_proxy.fAutoDetect) {
63 // if auto detect, than setup the proxy to auto detect
64 proxy_options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
65 proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A;
66 }
67
68 if (ie_proxy.lpszAutoConfigUrl) {
69 // configure to auto proxy
70 proxy_options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
71 proxy_options.lpszAutoConfigUrl = ie_proxy.lpszAutoConfigUrl;
72 }
73
74 if (!WinHttpGetProxyForUrl(hSession, wtarget_url.c_str(), &proxy_options, &proxy_info)) {
75 info << "Could not find the proxy for this url (Error code :" << GetLastError() << ").";
76 fail = true;
77 break;
78 }
79
80 // std::cout << "get proxy for url passed" << std::endl;
81 if (proxy_info.dwAccessType == WINHTTP_ACCESS_TYPE_NO_PROXY) {
82 // no proxy (return an empty proxy)
83 break;
84 }
85
86 if (proxy_info.lpszProxy) {
87 // proxy found. Get it.
88 proxy = proxy_info.lpszProxy;
89 break;
90 }
91 break; // loop finished
92 }
93
94 // free memory of all possibly allocated objects
95 // ie_proxy
96 if (ie_proxy.lpszAutoConfigUrl)
97 GlobalFree(ie_proxy.lpszAutoConfigUrl);
98 if (ie_proxy.lpszProxy)
99 GlobalFree(ie_proxy.lpszProxy);
100 if (ie_proxy.lpszProxyBypass)
101 GlobalFree(ie_proxy.lpszProxyBypass);
102 // proxy_info
103 if (proxy_info.lpszProxyBypass)
104 GlobalFree(proxy_info.lpszProxyBypass);
105 if (proxy_info.lpszProxy)
106 GlobalFree(proxy_info.lpszProxy);
107
108 // hSession
109 if (hSession)
110 WinHttpCloseHandle(hSession);
111
112 if (fail) {
113 err_msg = info.str();
114 }
115 MSVC_DIAG_OFF(4244)
116 proxy_str = std::string(proxy.begin(), proxy.end());
117 MSVC_DIAG_ON(4244)
118 return !fail;
119}
120
121//----------------------------------------------------------------------------------------------
124NetworkProxy::NetworkProxy() : m_logger("network_proxy_logger_win") {}
125
131ProxyInfo NetworkProxy::getHttpProxy(const std::string &targetURLString) {
132
133 ProxyInfo proxyInfo; // No proxy
134 std::string errmsg, proxy_option;
135 m_logger.debug() << "Attempt to get the windows proxy configuration for this connection" << std::endl;
136 if (get_proxy_configuration_win(targetURLString, proxy_option, errmsg)) {
137 std::string proxyServer;
138 int proxyPort = 0;
139 if (!proxy_option.empty()) {
140 size_t pos = proxy_option.rfind(':');
141 if (pos != std::string::npos) {
142 if (pos == 4 || pos == 5) // means it found http(s):
143 {
144 proxyServer = proxy_option;
145 proxyPort = 8080; // default port for proxy
146 } else {
147 proxyServer = std::string(proxy_option.begin(), proxy_option.begin() + pos);
148 std::stringstream port_str;
149 port_str << std::string(proxy_option.begin() + pos + 1, proxy_option.end());
150 port_str >> proxyPort;
151 }
152 } else {
153 proxyServer = proxy_option;
154 proxyPort = 8080;
155 }
156 }
157 proxyInfo = ProxyInfo(proxyServer, proxyPort, true);
158 } else {
159 m_logger.information() << "NetworkProxyWin failed to find the proxy "
160 "information. It will attempt without proxy. "
161 << errmsg << std::endl;
162 }
163
164 return proxyInfo;
165}
166
167} // namespace Kernel
168} // namespace Mantid
169
170#endif
#define MSVC_DIAG_ON(x)
#define MSVC_DIAG_OFF(x)
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
void information(const std::string &msg)
Logs at information level.
Definition: Logger.cpp:105
ProxyInfo getHttpProxy(const std::string &targetURLString)
Get http proxy information.
Mantid::Kernel::Logger m_logger
Logger object.
Definition: NetworkProxy.h:31
Helper class which provides the Collimation Length for SANS instruments.
STL namespace.