When i set proxy settings in the system my Electron application gets it automatically for common requests (axios package), but not for websockets (socket.io-client package). If i provide proxy settings manually then websockets starts to work too, but i want to try to avoid manual configuration, because it may be tricky to the real app's users. So i'm looking any way to get proxy settings from electron and transfer them to the websockets.
I have tried to use login event for my browserWindow in the both main and renderer process, but it doesn't trigger at all. Is there any way to get proxy settings that electron uses?
I've found the solution. It's possible to take proxy-settings inside the main process.
mainWindow = new BrowserWindow({})
const ses = mainWindow.webContents.session;
ses.resolveProxy('url_you_need_to_achieve', (proxy) => {
// do whatever you want with proxy string, that contains proxy-setting
});
Related
I would like to set different proxies while the application is running. However, it seems that the first request after setting a new proxy uses the old proxy settings! Subsequent requests use the new proxy settings...
How am I supposed to set a new proxy?
Things I have tried:
1)
Setting the new proxy via different methods:
QNetworkProxy::setApplicationProxy(networkProxy);
or
QNetworkProxyFactory::setApplicationProxyFactory(networkProxyFactory);
// then later:
networkProxyFactory.setNewProxy(hostname, port);
Making sure that the previous page stops loading before setting a new proxy:
QWebEnginePage::triggerAction(QWebEnginePage::Stop, true);
Making sure that the event loop runs between setting the new proxy and sending the request:
//set new proxy via the above methods
QCoreApplication::processEvents();
QCoreApplication::postEvent(..., Qt::LowEventPriority);
// now the event loop can run, in case changing the proxy
// needs to process some events,
// our event is set to low prio,
// so that it does not preemt a possible proxy-events
QWebEnginePage::event(QEvent *e) {
loadRequest();
}
None of these works. The proxies work fine, but a new proxy is only effective after the second request after setting a new proxy.
setInitialProxy(proxy1); // this works from the get-go
app.exec()
setNewProxy(proxy2);
QWebEnginePage::load(requestA); // uses proxy1
QWebEnginePage::load(requestB); // uses proxy2
Is it even possible to change proxies after app.exec(), or is it just some blind luck that it works this much? I would assume, if a browser is built around WebEngine, the user should be able to change the proxy settings...
Will the application automatically detect which environment that it is in or do you need to tell it?
The API is the same for both client and server side modes. To initialize your application for server side mode, you initialize your TTAPIOptions instance as follows:
// Add your app secret Key here. It looks like: 00000000-0000-0000-0000-000000000000:00000000-0000-0000-0000-000000000000
string appSecretKey = “Your App Key”;
//Set the environment the app needs to run in here
tt_net_sdk.ServiceEnvironment environment = tt_net_sdk.ServiceEnvironment.UatCert;
tt_net_sdk.TTAPIOptions apiConfig = new tt_net_sdk.TTAPIOptions(
tt_net_sdk.TTAPIOptions.SDKMode.Server,
environment,
appSecretKey,
5000);
I'm doing a tiny offline-able web app / PWA. It's meant to be opened from a home screen icon and mimic a regular app by loading entirely from a cache when offline.
The app is written using Vue and to accomplish the above I'm just using their PWA template and whatever it generates. To the best of my knowledge what this does is set up workbox using the GenerateSW plugin to precache everything in the Webpack build, and registers it using register-service-worker. That is, I have fairly little control out of the box over the fine details, it's meant to be a turnkey solution.
That said, I'm not sure how to actually load a new build of the application when it's available. The above can detect this - the generated SW registration file with my changes looks like this:
import debug from 'debug';
import { register } from 'register-service-worker';
if (process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready(...args) {
log('App is being served from cache by a service worker.\n', ...args);
},
cached(...args) {
log('Content has been cached for offline use.', ...args);
},
updated(...args) {
log('New content is available; please refresh.', ...args);
},
offline(...args) {
log('No internet connection found. App is running in offline mode.', ...args);
},
error(error, ...args) {
log('Error during service worker registration:', error, ...args);
}
});
}
When I make a new build of the application, and I refresh the app in a browser, the updated() callback is executed, but nothing else is done. When I tried adding:
window.location.reload(true);
which should be a forced refresh, I just get a refresh loop. I'm assuming this is because the service worker cache is completely independent from the browser cache and unaffected by things like the above or Ctrl+F5. (Which makes the "please refresh" rather misleading.)
Since this is going to mimic a native app, and it's supposed to be a simple line-of-business tool, I don't really need to do anything more complicated than immediately reload to the new version of the app when an update is available. How can I achieve this?
Okay so the behaviour I've observed is that the update does happen automatically, it's just not obvious as to what the exact sequence of events is. I'll try to describe my best understanding of how the generated service worker works in the installed PWA scenario. I'll speak in terms of "app versions" for simplicity, because the mental model behind this is closer to how apps, not webpages work:
You deploy v1 of your application to a server, install / precache it on a device, and run it for the first time.
When you suspend and resume your app, it does not hit your servers at all.
The app will check for an update when it's either cold-started, or you reload the page, i.e. using the pull down gesture on Android.
(Possibly also periodically as the cached version goes stale, but I haven't checked this.)
Say you've deployed v2 of your app in the meantime. Reloading an instance of v1 of the app will find this update, and precache it.
(One reason why prompting the user to reload doesn't seem to make sense. Whatever the reloading is meant to accomplish has already happened.)
Reloading an instance of v1 again does absolutely nothing. The app remains running between reloads, and you'll just get v1 afterwards.
(Reason number two why prompting the user to reload is pointless - it's not what causes a new version of an app to load.)
However, next time you cold start your app - e.g. nuke it from the task switcher and reopen - v2 of your app will be loaded and I'm guessing v1 will get cleaned out. That is, your app must fully shut down so an update will load.
In short, for an application to be updated from v1 to v2, the following steps need to occur:
Deploy v2 to server
Refresh instance of v1 on device, or shut down and reopen the app.
Shut down and reopen the app (again).
I am writing a bdd test for a component that will startup phantomjs and hit a specific route on my site and do processing on that. Because the component is fundamentally about automating a phantom instance there is no way to easily stub out the http requests.
So I want to stub out a self-hosted endpoint that will stub out the data I'm after. Because this is a unit test I think its really important for it to run in isolation so I do something like this:
async Task can_render_html_for_slide_async() {
var config = new HttpSelfHostConfiguration("http://localhost:54331");
config.Routes.MapHttpRoute("Controller", "{controller}", new {});
using (var server = new HttpSelfHostServer(config)) {
server.OpenAsync().Wait();
var client = new HttpClient();
var resp = await client.GetStringAsync(config.BaseAddress+"/Stub");
Console.WriteLine(resp);
}
}
public class StubController : ApiController
{
public string Get() {
return "Booyah";
}
}
Which gets me
AddressAccessDeniedException : HTTP could not register URL http://+:54331/
I understand that netsh or Admin mode is required for this but I don't understand why. Nodejs for example runs perfectly fine on windows but has no such requirement.
Also using OWIN directly needs no netsh-ing. So....what's going on?
I wrote an article about it on codeproject, it was done to make it possible for multiple application to share the same port.
You can have both, IIS and Apache (or OWIN in your case) listenening port 80. The routing to the right application is done thanks to the path of the url.
IIS and Apache both would use this driver (http.sys). But you need permission to "reserve" a path.
Administrators are always authorized. For other users, use netsh or my GUI tool HttpSysManager to set ACL.
Any method that requires giving permission via netsh uses a Windows kernel driver to provide http access.
If a library opens a socket itself and handles the http communication that way, no netsh use is needed.
So to answer your question, some methods are using the kernel driver and some are handling the protocol themselves.
Is there any way to dynamically change the proxy being used by Firefox when using selenium webdriver?
Currently I have proxy support using a proxy profile but is there a way to change the proxy when the browser is alive and running?
My current code:
proxy = Proxy({
'proxyType': 'MANUAL',
'httpProxy': proxy_ip,
'ftpProxy': proxy_ip,
'sslProxy': proxy_ip,
'noProxy': '' # set this value as desired
})
browser = webdriver.Firefox(proxy=proxy)
Thanks in advance.
This is a slightly old question.
But it is actually possible to change the proxies dynamically thru a "hacky way"
I am going to use Selenium JS with Firefox but you can follow thru in the language you want.
Step 1: Visiting "about:config"
driver.get("about:config");
Step 2 : Run script that changes proxy
var setupScript=`var prefs = Components.classes["#mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
prefs.setIntPref("network.proxy.type", 1);
prefs.setCharPref("network.proxy.http", "${proxyUsed.host}");
prefs.setIntPref("network.proxy.http_port", "${proxyUsed.port}");
prefs.setCharPref("network.proxy.ssl", "${proxyUsed.host}");
prefs.setIntPref("network.proxy.ssl_port", "${proxyUsed.port}");
prefs.setCharPref("network.proxy.ftp", "${proxyUsed.host}");
prefs.setIntPref("network.proxy.ftp_port", "${proxyUsed.port}");
`;
//running script below
driver.executeScript(setupScript);
//sleep for 1 sec
driver.sleep(1000);
Where use ${abcd} is where you put your variables, in the above example I am using ES6 which handles concatenation as shown, you can use other concatenation methods of your choice , depending on your language.
Step 3: : Visit your site
driver.get("http://whatismyip.com");
Explanation:the above code takes advantage of Firefox's API to change the preferences using JavaScript code.
As far as I know there are only two ways to change the proxy setting, one via a profile (which you are using) and the other using the capabilities of a driver when you instantiate it as per here. Sadly neither of these methods do what you want as they both happen before as you create your driver.
I have to ask, why is it you want to change your proxy settings? The only solution I can easily think of is to point firefox to a proxy that you can change at runtime. I am not sure but that might be possible with browsermob-proxy.
One possible solution is to close the webdriver instance and create it again after each operation by passing a new configuration in the browser profile
Have a try selenium-wire, It can even override header field
from seleniumwire import webdriver
options = {
'proxy': {
"http": "http://" + IP_PORT,
"https": "http://" + IP_PORT,
'custom_authorization':AUTH
},
'connection_keep_alive': True,
'connection_timeout': 30,
'verify_ssl': False
}
# Create a new instance of the Firefox driver
driver = webdriver.Firefox(seleniumwire_options=options)
driver.header_overrides = {
'Proxy-Authorization': AUTH
}
# Go to the Google home page
driver.get("http://whatismyip.com")
driver.close()