SeleniumHQ / selenium

A browser automation framework and ecosystem.
https://selenium.dev
Apache License 2.0
30.5k stars 8.15k forks source link

Add resolve_ip option to remote WebDriver #9238

Closed federicoparroni closed 3 years ago

federicoparroni commented 3 years ago

🚀 Feature Proposal

The resolve_ip param should be added to the remote WebDriver class.

class WebDriver(object):
    # ...
    def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub',
                 desired_capabilities=None, browser_profile=None, proxy=None,
                 keep_alive=False, file_detector=None, options=None, resolve_ip=True):
        """
        Create a new driver that will issue commands using the wire protocol.

        :Args:
         - command_executor - Either a string representing URL of the remote server or a custom
             remote_connection.RemoteConnection object. Defaults to 'http://127.0.0.1:4444/wd/hub'.
         - desired_capabilities - A dictionary of capabilities to request when
             starting the browser session. Required parameter.
         - browser_profile - A selenium.webdriver.firefox.firefox_profile.FirefoxProfile object.
             Only used if Firefox is requested. Optional.
         - proxy - A selenium.webdriver.common.proxy.Proxy object. The browser session will
             be started with given proxy settings, if possible. Optional.
         - keep_alive - Whether to configure remote_connection.RemoteConnection to use
             HTTP keep-alive. Defaults to False.
         - file_detector - Pass custom file detector object during instantiation. If None,
             then default LocalFileDetector() will be used.
         - options - instance of a driver options.Options class
         - resolve_ip - specify whether the remote server hostname should be resolved to an IP
             address. Defaults to True.
        """
        # ...
        if type(self.command_executor) is bytes or isinstance(self.command_executor, str):
            self.command_executor = RemoteConnection(command_executor, keep_alive=keep_alive, resolve_ip=resolve_ip)
        # ...

Motivation

I am using the Remote Webdriver to attach to a Selenium grid cluster running on Kubernetes. Since I am using an Nginx ingress, there is an issue with the resolve IP functionality of the RemoteConnection class.

driver = webdriver.Remote(
    command_executor='http://myseleniumgrid.it/wd/hub',
    ...
)

This code throws an exception since the hostname is resolved to the default backend IP. That IP is then used as the "Host" header value. Since Nginx does not know that virtualhost, the default backend response is returned: "default backend - 404".

Example

driver = webdriver.Remote(
    command_executor='http://myseleniumgrid.it/wd/hub',
    ...,
    resolve_ip=False
)
isaulv commented 3 years ago

According to these docs in urllib3 this is how to disable Name resolution for a given host name: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#custom-sni-hostname

Generally one should set up your environment to do the right thing (such as pointing to the right name server), but there are specific instances where this doesn’t work or may be beyond the skill set of the user.

I think rather than reintroduce resolve_ip as a keyword option we should expose a method to change the RemoteConnection. we currently have a way to change timeouts so we can do something similar.

isaulv commented 3 years ago

The real solution is to define your own RemoteConnection class that uses the custom SNI hostname and pass that in the webdriver class browser = Webdriver(command_executor=MyCustomRemoteConnection, ...) This has been a thing for a while, I found out recently.

federicoparroni commented 3 years ago

Thank you so much @isaulv. I solved using the RemoteConnection class as you suggested:

from selenium.webdriver.remote.remote_connection import RemoteConnection

driver = webdriver.Remote(
    command_executor=RemoteConnection('http://seleniumgrid.eng.aruba.it/wd/hub', resolve_ip=False),
    ...
)
AutomatedTester commented 3 years ago

closing this as the correct way to do it has been used.

github-actions[bot] commented 3 years ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.