def test_ssl_via_non_ssl_proxy(insecure_server, auth):
    proxy_user, proxy_pass = auth
    with HttpClient(
        "localhost",
        1,
        proxy_scheme="http",
        proxy_host="localhost",
        proxy_port=insecure_server.port,
        proxy_user=proxy_user,
        proxy_pass=proxy_pass,
        disable_certificate_validation=True,
    ) as client:
        try:
            client.send_request()
        except Exception:
            pass

    try:
        if proxy_user:
            auth_expected = proxy_user
            if proxy_pass:
                auth_expected = auth_expected + ":" + proxy_pass
            auth_expected = "Basic " + base64.b64encode(
                auth_expected.encode("utf-8")
            ).decode("utf-8")
            assert (
                insecure_server.httpd.connect_headers["proxy-authorization"]
                == auth_expected
            )
        else:
            assert "proxy-authorization" not in insecure_server.httpd.connect_headers
        assert insecure_server.httpd.connect_host == "localhost"
        assert insecure_server.httpd.connect_port == "1"
    finally:
        insecure_server.reset()
def test_default_cert_path(monkeypatch, system_certs_available):
    if system_certs_available:
        cert_file = "foo"
    else:
        cert_file = None

    class DefaultVerifyPaths(object):
        cafile = cert_file

        def __init__(self, *args, **kwargs):
            pass

    monkeypatch.setattr(ssl, "DefaultVerifyPaths", DefaultVerifyPaths)
    internal_metrics = CustomMetrics()
    with InternalTraceContext(internal_metrics):
        client = HttpClient("localhost", ca_bundle_path=None)

    internal_metrics = dict(internal_metrics.metrics())
    cert_metric = "Supportability/Python/Certificate/BundleRequired"
    if system_certs_available:
        assert "ca_certs" not in client._connection_kwargs
        assert cert_metric not in internal_metrics
    else:
        assert client._connection_kwargs["ca_certs"] == certs.where()
        assert internal_metrics[cert_metric][-3:-1] == [1, 1]
def test_http_no_payload(server, method):
    with HttpClient(
        "localhost", server.port, disable_certificate_validation=True
    ) as client:
        connection = client._connection_attr
        status, data = client.send_request(method=method, headers={"foo": "bar"})

    assert status == 200
    data = ensure_str(data)
    data = data.split("\n")

    # Verify connection has been closed
    assert client._connection_attr is None
    assert connection.pool is None

    # Verify request line
    assert data[0].startswith(method + " /agent_listener/invoke_raw_method ")

    # Verify headers
    user_agent_header = ""
    foo_header = ""

    for header in data[1:-1]:
        if header.lower().startswith("user-agent:"):
            _, value = header.split(":", 1)
            value = value.strip()
            user_agent_header = value
        elif header.startswith("foo:"):
            _, value = header.split(":", 1)
            value = value.strip()
            foo_header = value

    assert user_agent_header.startswith("NewRelic-PythonAgent/")
    assert foo_header == "bar"
def test_http_close_connection(server):
    client = HttpClient("localhost", server.port, disable_certificate_validation=True,)

    status, _ = client.send_request()
    assert status == 200

    connection = client._connection_attr
    client.close_connection()
    assert client._connection_attr is None
    assert connection.pool is None

    # Verify that subsequent calls to close_connection don't crash
    client.close_connection()
def test_ssl_via_ssl_proxy(server, auth):
    proxy_user, proxy_pass = auth
    with HttpClient(
        "localhost",
        1,
        proxy_scheme="https",
        proxy_host="localhost",
        proxy_port=server.port,
        proxy_user=proxy_user,
        proxy_pass=proxy_pass,
        disable_certificate_validation=True,
    ) as client:
        status, data = client.send_request()

    assert status == 200
    data = data.decode("utf-8")
    data = data.split("\n")
    assert data[0].startswith(
        "POST https://localhost:1/agent_listener/invoke_raw_method "
    )

    proxy_auth = None
    for header in data[1:-1]:
        if header.lower().startswith("proxy-authorization"):
            _, proxy_auth = header.split(":", 1)
            proxy_auth = proxy_auth.strip()
            break

    if proxy_user:
        auth_expected = proxy_user
        if proxy_pass:
            auth_expected = auth_expected + ":" + proxy_pass
        auth_expected = "Basic " + base64.b64encode(
            auth_expected.encode("utf-8")
        ).decode("utf-8")
        assert proxy_auth == auth_expected
    else:
        assert not proxy_auth

    assert server.httpd.connect_host is None
def test_closed_connection():
    with HttpClient("localhost", MockExternalHTTPServer.get_open_port()) as client:
        with pytest.raises(NetworkInterfaceException):
            client.send_request()
def test_cert_path(server):
    with HttpClient("localhost", server.port, ca_bundle_path=SERVER_CERT) as client:
        status, data = client.send_request()
def test_http_close_connection_in_context_manager():
    client = HttpClient("localhost", 1000)
    with client:
        client.close_connection()
def test_proxy_parsing(scheme, host, port, username, password, expected):
    assert HttpClient._parse_proxy(scheme, host, port, username, password) == expected