Frage: Über welchen Proxy geht der Traffic eines Robot-Tests mit der Browser Library (Playwright),
wenn ein RCC-Proxyprofil bzw. HTTP(S)_PROXY/NO_PROXY gesetzt sind? Und was passiert, wenn
NO_PROXY fehlt oder der Proxy Benutzer/Passwort verlangt?
Getestet wird ausschließlich Browser Library 20.6.0. Ältere Versionen (vor 20.4.0) hatten einen Fehler,
durch den die interne gRPC-Kommunikation ohne NO_PROXY=localhost nicht mehr funktionierte
(robotframework-browser#1037).
| Komponente | Beschreibung |
|---|---|
| Proxy A | mitmdump auf localhost:3128, wird per RCC-Profil bzw. HTTP(S)_PROXY gesetzt |
| Proxy B | mitmdump auf localhost:3129, wird nur explizit im Test gesetzt: New Browser … proxy= und RequestsLibrary GET … proxies= |
proxy.robot |
loggt die Proxy-Variablen, macht einen Python-Kontrollrequest (RequestsLibrary GET) und öffnet http://example.com + https://example.org im Browser |
resources/noproxy.resource |
New Browser ohne proxy, GET ohne proxies |
resources/proxyB.resource |
New Browser mit proxy={"server": "http://localhost:3129", "bypass": "localhost,127.0.0.1"}, bei ${PROXY_USER} zusätzlich username/password; GET mit proxies={"http": …, "https": …} auf Proxy B, bei ${PROXY_USER} mit Zugangsdaten in der URL |
robot.yaml / conda.yaml |
Browser Library 20.6.0 |
profiles/ |
von den Skripten erzeugte RCC-Profile (proxytest-a[-auth][-nonoproxy].yaml) |
mitmproxy/ |
rcc-Environment und Addon für die Proxies unter Windows (ohne Docker) |
mitmdump bricht TLS auf, damit auch HTTPS-Requests im Log erscheinen. Im Browser ist deshalb ignoreHTTPSErrors=True gesetzt.
Beide Skripte setzen rcc voraus: rcc baut und aktiviert das Environment (Browser Library 20.6.0), und robot
läuft immer über rcc task script. Die Modi unterscheiden sich nur darin, woher die Proxy-Variablen für
Proxy A kommen:
| Modus | Proxy A kommt aus | Zweck |
|---|---|---|
profile (Default) |
RCC-Proxyprofil (rcc config import/switch) |
der Robotmk-Weg |
env |
HTTP(S)_PROXY/NO_PROXY in der Umgebung des Aufrufers, kein RCC-Profil; rcc task script vererbt sie |
Gegenprobe: Wirkt das Profil nur über diese Variablen? |
./run_scenarios.sh # Szenarien 1-4, Proxy A per RCC-Profil
./run_scenarios.sh --proxy-from env # Proxy A per Variablen des Aufrufers, ohne Profil
./run_scenarios.sh --auth # Proxies mit Benutzer/Passwort
./run_scenarios.sh --fail # zusätzlich Szenario 5 (NO_PROXY fehlt)
./run_scenarios.sh --proxy-from env --auth --fail 5 # kombinierbar, Nummern wählen einzelne Szenarienprofile: Das Skript erzeugt das passende Profil unterprofiles/, importiert und aktiviert es. Am Ende wird das vorher aktive Profil wiederhergestellt.env: Kein Profil aktiv (rcc config switch -n). Das Skript setztHTTP_PROXY,HTTPS_PROXY,http_proxy,https_proxyund ggf.NO_PROXY/no_proxy(dieselben Variablen, die rcc mit dem Profil setzt) für den rcc-Prozess.--auth: Beide Proxies verlangenproxyuser:s3cr3t. Proxy A bekommt die Zugangsdaten über die URL (http://proxyuser:s3cr3t@localhost:3128, im RCC-Profil bzw. in den Variablen), der Browser für Proxy B überusername/passwordimproxy-Dictionary.- Vor dem ersten Szenario baut bzw. prüft das Skript das Environment (
rcc ht varsohne Profil). - Die Proxy-Variablen der aufrufenden Shell werden vorher entfernt (siehe Erkenntnis 5).
- Jeder robot-Lauf wird nach
TIMEOUTSekunden (Default 120) samt Kindprozessen beendet.
Ergebnisse: results/<profile|env>[-auth]/scenarioN/ und results/<profile|env>[-auth]/summary.txt. Pro Szenario:
robot-Logs, Proxy-Logs, caller_env.txt (vom Skript gesetzte Variablen), rcc_profile.txt und htvars.txt
(rcc ht vars mit derselben Umgebung wie der Test).
.\run_scenarios.ps1 # Szenarien 1-4, Proxy A per RCC-Profil
.\run_scenarios.ps1 -ProxyFrom env -Auth
.\run_scenarios.ps1 -Fail 5
.\run_scenarios.ps1 -SystemProxy -Fail # WinINET-Proxy des Benutzers zeigt auf Proxy A- Optionen wie oben:
-ProxyFrom profile|env,-Auth,-Fail, Szenarionummern,-Timeout. - Die Proxies sind
mitmdump-Prozesse aus einem eigenen rcc-Environment (mitmproxy/robot.yaml). - Das Addon
mitmproxy/block_loopback.pyweist Ziele auf127.0.0.1/localhostmit 502 ab. So verhält sich der lokale Proxy wie ein Firmen-Proxy auf einem anderen Host (unter Docker ergibt sich das von selbst, weil127.0.0.1im Container der Container ist). -SystemProxy: setzt für die Dauer des Laufs den WinINET-Proxy des Benutzers (HKCU, Internetoptionen) auflocalhost:3128mit Ausnahme<local>und stellt danach den vorherigen Zustand wieder her. Damit lässt sich messen, welchem Proxy Chromium ohneproxy=folgt. Nicht mit-Authkombinierbar. Während des Laufs geht auch anderer WinINET-Traffic des Benutzers über Proxy A.- Die Zusammenfassung enthält die Windows-Proxy-Einstellungen (WinINET des Benutzers und WinHTTP).
- Ergebnisse unter
results/windows-<profile|env>[-auth][-sysproxy]/.
Alle Szenarien mit Browser Library 20.6.0:
| # | Proxy A (Env/RCC) | NO_PROXY |
Proxy B explizit (proxy=/proxies=) |
Erwartung |
|---|---|---|---|---|
| 1 | ja | localhost,127.0.0.1 |
– | PASS |
| 2 | ja | localhost,127.0.0.1 |
ja | PASS |
| 3 | nein | – | – | PASS |
| 4 | nein | – | ja | PASS |
5 (--fail) |
ja | fehlt | – | PASS (vor 20.4.0: FAIL) |
Browser Library 20.6.0 (Playwright 1.63), rcc v17.29.1. Neun Läufe mit je fünf Szenarien (--fail), 45 von 45 PASS:
| Plattform | Läufe |
|---|---|
| macOS, kein System-Proxy | profile, env, profile-auth, env-auth |
| Windows Server 2022 (Administrator), kein System-Proxy | windows-profile, windows-env, windows-profile-auth, windows-env-auth |
| Windows Server 2022, WinINET-Proxy → Proxy A | windows-profile-sysproxy |
profile und env liefern identische Zusammenfassungen, ebenso profile-auth und env-auth, auf beiden Plattformen.
| # | Proxy A | NO_PROXY |
Proxy B explizit | Env im Test | RequestsLibrary | Browser-Traffic |
|---|---|---|---|---|---|---|
| 1 | ja | gesetzt | – | HTTP(S)_PROXY=…:3128 |
Proxy A | direkt (weder A noch B) |
| 2 | ja | gesetzt | ja | HTTP(S)_PROXY=…:3128 |
Proxy B | Proxy B |
| 3 | nein | – | – | nicht gesetzt | direkt | direkt |
| 4 | nein | – | ja | nicht gesetzt | Proxy B | Proxy B |
| 5 | ja | fehlt | – | HTTP(S)_PROXY=…:3128 |
Proxy A | direkt, Test läuft |
Mit --auth: identische Wege. requests schickt die Zugangsdaten aus der Proxy-URL gleich mit (Umgebungsvariable wie proxies=, 0× 407),
Chromium bekommt beim ersten Request an Proxy B einmal 407 und authentifiziert sich dann mit username/password.
htvars.txt (rcc ht vars mit derselben Umgebung wie der Test) enthält die Proxy-Variablen nur in den
profile-Läufen, in den env-Läufen nicht, obwohl sie dort im Test ankommen (siehe Erkenntnis 5).
Die Logs zeigen z. B. für Szenario 1 (Variablen auf Proxy A, nichts explizit):
Proxy A: http://example.com/?via=python-requests
Proxy B: – (Browser ging direkt)
WinINET (HKCU): ProxyEnable=1, ProxyServer=localhost:3128, Ausnahme <local>.
| # | Proxy A (Profil) | New Browser |
Python-Request | Browser-Traffic |
|---|---|---|---|---|
| 1 | ja | ohne proxy |
Proxy A | direkt |
| 2 | ja | Proxy B | Proxy A | Proxy B |
| 3 | nein | ohne proxy |
Proxy A (Registry) | direkt |
| 4 | nein | Proxy B | Proxy A (Registry) | Proxy B |
| 5 | ja, ohne NO_PROXY |
ohne proxy |
Proxy A | direkt |
Der System-Proxy war wirksam: Python ging in Szenario 3 und 4 ohne Profil und ohne Variablen über Proxy A, und im
Log von Proxy A erscheint auch Traffic anderer Programme des Benutzers (VS Code). Chromium (headless=True) ging
trotzdem direkt. Playwright setzt ohne proxy= kein Proxy-Flag; warum Chromium den WinINET-Proxy nicht nutzt,
ist nicht geklärt (Vermutung: headless shell, nicht geprüft).
- RCC setzt
HTTP_PROXY/HTTPS_PROXY/NO_PROXY(groß und klein) in die Umgebung des Robot-Prozesses. Python (requests bzw. RequestsLibrary) nutzt den RCC-Proxy daher automatisch (Kontrollrequest in A). Das RCC-Profil wirkt ausschließlich über diese Variablen: Mit denselben Variablen ohne rcc ist das Verhalten identisch (results/env=results/profile). - Der Browser ignoriert diese Variablen. Playwright gibt Chromium nur dann
--proxy-server=…mit, wennNew Browsereinenproxybekommt. Ohneproxyging Chromium in allen Messungen direkt, unter Windows auch bei gesetztem WinINET-Proxy (gemessen mitheadless=True). proxyinNew Browserhat immer Vorrang, egal was im RCC-Profil oder im System steht (Szenario 2 = Szenario 4). Zugangsdaten gehören dort inusername/password.- Der RCC-Proxy wirkt beim Browser nur indirekt: beim Bauen des Environments (conda/pip-Downloads,
rfbrowser initlädt Node-Pakete und Browser-Binaries über den Proxy). rcc task scriptvererbt die Umgebung des aufrufenden Prozesses. Ohne Profil setzt RCC keine Proxy-Variablen, entfernt aber auch keine bereits vorhandenen. SindHTTP(S)_PROXYin der Shell (bzw. beim Robotmk-Scheduler/Dienst oder systemweit) gesetzt, landen sie im Test, obwohlrcc ht varsnichts davon zeigt (es listet nur die von RCC selbst gesetzten Variablen).- Fehlendes
NO_PROXYbricht die Browser Library seit 20.4.0 nicht mehr. Die Library spricht per gRPC mit ihrem eigenen Node-Prozess auf127.0.0.1:<port>. grpc-python schickt auch diese lokale Verbindung überhttp_proxy/https_proxy, sofernno_proxysie nicht ausnimmt. Vor 20.4.0 endete das mitCould not connect to the playwright process(#1037). Seit dem Fix in 20.4.0 nimmt die Library lokale gRPC-Kanäle vom Proxy aus; in 20.6.0 setztgrpc_channel_options(Browser/playwright.py) dafürgrpc.enable_http_proxy=0. Szenario 5 läuft deshalb durch.NO_PROXY=localhost,127.0.0.1bleibt trotzdem sinnvoll, z. B. für Python-Requests an lokale Dienste und für ältere Environments. - Proxy-Authentifizierung über die URL funktioniert in RCC-Profil und Env-Variablen
(
http://user:pass@host:port); rcc reicht sie unverändert durch. Für den Browser gilt das nicht, er brauchtusername/passwordimproxy-Dictionary.
Soll der Browser über einen Proxy gehen, ihn immer explizit setzen und sich nicht auf das RCC-Profil verlassen:
&{proxy}= Create Dictionary server=http://proxy.example:3128 bypass=localhost,127.0.0.1
... username=${PROXY_USER} password=${PROXY_PASS}
New Browser chromium proxy=${proxy}Browser Library mindestens 20.4.0 verwenden (getestet: 20.6.0) und im RCC-Profil trotzdem no-proxy mit
mindestens localhost,127.0.0.1 pflegen.
- Gemessen als normaler Benutzer bzw. Administrator, nicht als SYSTEM. WinINET-Einstellungen gelten pro Benutzer; läuft der Robotmk-Scheduler als SYSTEM, gelten dessen Einstellungen (für Python relevant, siehe oben).
- Der System-Proxy-Lauf nutzt
headless=True. Ob ein sichtbarer Browser (headless=False) oderchannel=chromedem WinINET-Proxy folgt, ist nicht gemessen. PAC-Dateien ebenfalls nicht. - Linux ohne Desktop-Umgebung: Chromium liest dort möglicherweise
http_proxy/https_proxyaus der Umgebung. Nicht gemessen; ein weiterer Grund,proxyexplizit zu setzen.