diff --git a/include/wx/gtk/webview_webkit.h b/include/wx/gtk/webview_webkit.h index 824e55dd1d..c4d5487e86 100644 --- a/include/wx/gtk/webview_webkit.h +++ b/include/wx/gtk/webview_webkit.h @@ -79,6 +79,7 @@ public: virtual void EnableAccessToDevTools(bool enable = true) override; virtual bool IsAccessToDevToolsEnabled() const override; virtual bool SetUserAgent(const wxString& userAgent) override; + virtual bool SetProxy(const wxString& proxy) override; #endif void SetZoomType(wxWebViewZoomType) override; diff --git a/include/wx/msw/webview_edge.h b/include/wx/msw/webview_edge.h index 3e4d476599..3683a168de 100644 --- a/include/wx/msw/webview_edge.h +++ b/include/wx/msw/webview_edge.h @@ -94,6 +94,8 @@ public: virtual bool SetUserAgent(const wxString& userAgent) override; virtual wxString GetUserAgent() const override; + virtual bool SetProxy(const wxString& proxy) override; + virtual bool RunScript(const wxString& javascript, wxString* output = nullptr) const override; virtual void RunScriptAsync(const wxString& javascript, void* clientData = nullptr) const override; virtual bool AddScriptMessageHandler(const wxString& name) override; diff --git a/include/wx/webview.h b/include/wx/webview.h index 2fa343cb54..4209e82685 100644 --- a/include/wx/webview.h +++ b/include/wx/webview.h @@ -251,6 +251,7 @@ public: virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0; virtual bool SetUserAgent(const wxString& userAgent) { wxUnusedVar(userAgent); return false; } virtual wxString GetUserAgent() const; + virtual bool SetProxy(const wxString& proxy) { wxUnusedVar(proxy); return false; } // Script virtual bool RunScript(const wxString& javascript, wxString* output = nullptr) const; diff --git a/interface/wx/webview.h b/interface/wx/webview.h index 4674d919bc..da27d946c3 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -1211,6 +1211,20 @@ public: */ virtual wxString GetUserAgent() const; + /** + Set the proxy to use for all requests. + + The @a proxy string must be a valid proxy specification, e.g. @c + http://my.local.proxy.corp:8080 + + @note Currently this function is only implemented in WebKit2 and Edge + backends and must be called before Create() for the latter one. + + @return @true if proxy was set successfully or @false if it failed, + e.g. because this is not supported by the currently used backend. + */ + virtual bool SetProxy(const wxString& proxy); + /** @name Scripting */ diff --git a/samples/webview/webview.cpp b/samples/webview/webview.cpp index 6b2b7e593f..c9c134bfb3 100644 --- a/samples/webview/webview.cpp +++ b/samples/webview/webview.cpp @@ -161,6 +161,7 @@ public: void OnRunScriptCustom(wxCommandEvent& evt); void OnAddUserScript(wxCommandEvent& evt); void OnSetCustomUserAgent(wxCommandEvent& evt); + void OnSetProxy(wxCommandEvent& evt); void OnClearSelection(wxCommandEvent& evt); void OnDeleteSelection(wxCommandEvent& evt); void OnSelectAll(wxCommandEvent& evt); @@ -422,6 +423,17 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowFeatures* wi #endif // Create the webview m_browser = (windowFeatures) ? windowFeatures->GetChildWebView() : wxWebView::New(); + + // With several backends the proxy can only be set before creation, so do + // it here if the standard environment variable is defined. + wxString proxy; + if ( wxGetEnv("http_proxy", &proxy) ) + { + if ( m_browser->SetProxy(proxy) ) + wxLogMessage("Using proxy \"%s\"", proxy); + //else: error message should have been already given by wxWebView itself + } + #ifdef __WXMAC__ if (m_isMainFrame) { @@ -548,6 +560,7 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowFeatures* wi m_tools_menu->AppendSubMenu(script_menu, _("Run Script")); wxMenuItem* addUserScript = m_tools_menu->Append(wxID_ANY, _("Add user script")); wxMenuItem* setCustomUserAgent = m_tools_menu->Append(wxID_ANY, _("Set custom user agent")); + wxMenuItem* setProxy = m_tools_menu->Append(wxID_ANY, _("Set proxy")); //Selection menu wxMenu* selection = new wxMenu(); @@ -657,6 +670,7 @@ WebFrame::WebFrame(const wxString& url, bool isMain, wxWebViewWindowFeatures* wi Bind(wxEVT_MENU, &WebFrame::OnRunScriptAsync, this, m_script_async->GetId()); Bind(wxEVT_MENU, &WebFrame::OnAddUserScript, this, addUserScript->GetId()); Bind(wxEVT_MENU, &WebFrame::OnSetCustomUserAgent, this, setCustomUserAgent->GetId()); + Bind(wxEVT_MENU, &WebFrame::OnSetProxy, this, setProxy->GetId()); Bind(wxEVT_MENU, &WebFrame::OnClearSelection, this, m_selection_clear->GetId()); Bind(wxEVT_MENU, &WebFrame::OnDeleteSelection, this, m_selection_delete->GetId()); Bind(wxEVT_MENU, &WebFrame::OnSelectAll, this, selectall->GetId()); @@ -1374,6 +1388,29 @@ void WebFrame::OnSetCustomUserAgent(wxCommandEvent& WXUNUSED(evt)) wxLogError("Could not set custom user agent"); } +void WebFrame::OnSetProxy(wxCommandEvent& WXUNUSED(evt)) +{ + static wxString s_proxy; + if ( s_proxy.empty() ) + wxGetEnv("http_proxy", &s_proxy); + + const auto proxy = wxGetTextFromUser + ( + "Enter the proxy to use", + wxGetTextFromUserPromptStr, + s_proxy, + this + ); + + if (proxy.empty()) + return; + + s_proxy = proxy; + + if (!m_browser->SetProxy(s_proxy)) + wxLogError("Could not set proxy"); +} + void WebFrame::OnClearSelection(wxCommandEvent& WXUNUSED(evt)) { m_browser->ClearSelection(); diff --git a/src/gtk/webview_webkit2.cpp b/src/gtk/webview_webkit2.cpp index a50525dedd..ee015a0efa 100644 --- a/src/gtk/webview_webkit2.cpp +++ b/src/gtk/webview_webkit2.cpp @@ -994,6 +994,46 @@ bool wxWebViewWebKit::SetUserAgent(const wxString& userAgent) return true; } +bool wxWebViewWebKit::SetProxy(const wxString& proxy) +{ +#if WEBKIT_CHECK_VERSION(2, 16, 0) + if (wx_check_webkit_version(2, 16, 0)) + { + const auto context = static_cast(m_config.GetNativeConfiguration()); + wxCHECK_MSG( context, false, "no context?" ); + + const auto data_manager = webkit_web_context_get_website_data_manager(context); + wxCHECK_MSG( data_manager, false, "no data manager?" ); + + const auto proxy_settings = webkit_network_proxy_settings_new( + proxy.utf8_str(), + nullptr // no hosts to ignore + ); + wxCHECK_MSG( proxy_settings, false, "failed to create proxy settings" ); + + webkit_website_data_manager_set_network_proxy_settings( + data_manager, + WEBKIT_NETWORK_PROXY_MODE_CUSTOM, + proxy_settings + ); + + webkit_network_proxy_settings_free(proxy_settings); + + return true; + } + + wxLogError(_("Setting proxy is not supported by WebKit, at least version 2.16 is required.")); + + return false; +#else // WebKit < 2.16 doesn't support setting proxy + wxUnusedVar(proxy); + + wxLogError(_("This program was compiled without support for setting WebKit proxy.")); + + return false; +#endif // WebKit 2.16+ +} + void wxWebViewWebKit::Stop() { webkit_web_view_stop_loading(m_web_view); diff --git a/src/msw/webview_edge.cpp b/src/msw/webview_edge.cpp index 1dae4dc9c8..adaaefb1e0 100644 --- a/src/msw/webview_edge.cpp +++ b/src/msw/webview_edge.cpp @@ -268,6 +268,22 @@ public: #endif } + bool SetProxy(const wxString& proxy) + { +#ifdef __VISUALC__ + m_webViewEnvironmentOptions->put_AdditionalBrowserArguments( + wxString::Format("--proxy-server=\"%s\"", proxy).wc_str() + ); + return true; +#else + wxUnusedVar(proxy); + + wxLogError(_("This program was compiled without support for setting Edge proxy.")); + + return false; +#endif + } + virtual void* GetNativeConfiguration() const override { return m_webViewEnvironmentOptions; @@ -1358,6 +1374,16 @@ wxString wxWebViewEdge::GetUserAgent() const } +bool wxWebViewEdge::SetProxy(const wxString& proxy) +{ + wxCHECK_MSG(!m_impl->m_webViewController, false, + "Proxy must be set before calling Create()"); + + auto configImpl = static_cast(m_impl->m_config.GetImpl()); + + return configImpl->SetProxy(proxy); +} + void* wxWebViewEdge::GetNativeBackend() const { return m_impl->m_webView;