Skip to content

[py] Add support for http proxy authentication to remote_connection#10358

Merged
AutomatedTester merged 3 commits intoSeleniumHQ:trunkfrom
luispflamminger:feature-py-remote-proxy-authentication
Feb 28, 2022
Merged

[py] Add support for http proxy authentication to remote_connection#10358
AutomatedTester merged 3 commits intoSeleniumHQ:trunkfrom
luispflamminger:feature-py-remote-proxy-authentication

Conversation

@luispflamminger
Copy link
Copy Markdown
Contributor

Description

Currently, urllib3.ProxyManager is used when connecting to a Selenium Server via http proxy.
The proxy url is read from environment variables.

Some http proxies require authentication. Credentials are usually passed in the url like this:
http://username:[email protected]:8080

When specifying a url like this and passing it into the ProxyManager's proxy_url attribute,
the ProxyManager is not able to authenticate to the proxy and a ProxyError is thrown:
ProxyError('Cannot connect to proxy.', OSError('Tunnel connection failed: 407 Proxy Authentication Required'))

Instead ProxyManager uses a proxy_header field for authentication, which can take a proxy-authorization header
that is then used to authenticate to the http proxy.

This PR implements support for this header.
If credentials are specified in the proxy url like shown above, they are seperated out.
They are then used to create a HTTP basic proxy-authorization header
using the urllib3.util.make_headers method provided by urllib3.
The credentials are removed from the url and the ProxyManager object is created using the
url without credentials and the authorization header.

If a regular url is passed in without credentials, no auth header is specified and the ProxyManager is created as it was before.

Motivation and Context

It is currently not possible to connect to a Selenium Server behind an http proxy that requires authentication using the Python Remote Webdriver.
This problem is solved here, as credentials can now be specified in the proxy url using the following standardized format:
http://username:[email protected]:8080
This feature is already present in other Selenium implementations (I tested it in Ruby), and this adds support for Python as well.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

(This is my first ever open source contribution, so if there is anything I can improve, please let me know!)

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 11, 2022

CLA assistant check
All committers have signed the CLA.

@AutomatedTester
Copy link
Copy Markdown
Member

Hey, thanks for the PR. Could you please check the github actions failures

@luispflamminger
Copy link
Copy Markdown
Contributor Author

Hi David,
I fixed the flake8 violations.
The failed unit test at py/test/unit/selenium/webdriver/firefox/firefox_options_tests.py:145 tests the firefox webdrivers FirefoxProfile and Options classes.
Unfortunately, I can't replicate the failure locally.
I looked at the code a bit and also don't really see, how my changes to the remote webdriver would have any impact on a test regarding the firefox webdriver options.
Maybe you could have a quick look at it if the problem persists after the next workflow run, as I have no experience with the firefox driver.

Currently, urllib3.ProxyManager is used when connecting to a Selenium
Server via http proxy. The proxy url is read from environment variables.

When using a proxy which requires authentication, credentials are
usually passed in the url like this:
'http://username:[email protected]:8080'
urllib3.ProxyManager does not support this, but instead provides a
proxy_header field which takes a basic auth header for authentication.

This commit implements support for this.
If credentials are given in the proxy url, they are seperated out.
Then, the url without credentials and a proxy authentication header,
which is created from the url credentials, are used to create the
ProxyManager instance.
@luispflamminger luispflamminger force-pushed the feature-py-remote-proxy-authentication branch from 4ef6282 to 35eadf1 Compare February 17, 2022 15:04
@luispflamminger
Copy link
Copy Markdown
Contributor Author

I rebased my feature branch, maybe that fixes the issue.

@sonarqubecloud
Copy link
Copy Markdown

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@AutomatedTester AutomatedTester merged commit fe1ec64 into SeleniumHQ:trunk Feb 28, 2022
elgatov pushed a commit to elgatov/selenium that referenced this pull request Jun 27, 2022
…eleniumHQ#10358)

* Add support for proxy authentication to remote_connection

Currently, urllib3.ProxyManager is used when connecting to a Selenium
Server via http proxy. The proxy url is read from environment variables.

When using a proxy which requires authentication, credentials are
usually passed in the url like this:
'http://username:[email protected]:8080'
urllib3.ProxyManager does not support this, but instead provides a
proxy_header field which takes a basic auth header for authentication.

This commit implements support for this.
If credentials are given in the proxy url, they are seperated out.
Then, the url without credentials and a proxy authentication header,
which is created from the url credentials, are used to create the
ProxyManager instance.

* Fix flake8 style violations

Co-authored-by: David Burns <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants