HTTPListRedirects

List the redirects for a given URL.

python · Common Scripts

Details

IDHTTPListRedirects
Languagepython
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10404775
TagsUtility

README

List the redirects for a given URL

Script Data


Name Description
Script Type python2
Tags Utility
Cortex XSOAR Version 5.0.0

Inputs


Argument Name Description
url The URL to follow
useHead Should we use HEAD instead of GET. Safer but might not be the same response.
use_system_proxy Use system proxy settings
trust_any_certificate Trust any certificate (not secure)

Outputs


Path Description Type
URL.Data The URL redirects from the given URL Unknown
import pytest
import requests
import requests_mock

MOCK_ADDR = "mock://"


def custom_matcher(request: requests.Request) -> requests.Response | None:
    if request.url == f"{MOCK_ADDR}http://example.com":
        first_history = requests.Response()
        first_history.url = "http://example.com/"
        first_history.status_code = 301

        second_history = requests.Response()
        second_history.url = "https://example.com/"
        second_history.status_code = 301

        resp = requests.Response()
        resp.status_code = 200
        resp.url = "https://www.example.org/"
        resp.history = [first_history, second_history]
        return resp
    return None


REDIRECTED_URL_CASES = [
    (
        {"url": "http://example.com", "useHead": "true"},
        [
            {"Data": "http://example.com/", "Status": 301},
            {"Data": "https://example.com/", "Status": 301},
            {"Data": "https://www.example.org/", "Status": 200},
        ],
    ),
    (
        {"url": "http://example.com", "useHead": "false"},
        [
            {"Data": "http://example.com/", "Status": 301},
            {"Data": "https://example.com/", "Status": 301},
            {"Data": "https://www.example.org/", "Status": 200},
        ],
    ),
]


@pytest.mark.parametrize("params, expected_results", REDIRECTED_URL_CASES)
def test_valid_response_history(params, expected_results):
    """
    Given:
        - A url and whether to use requests.head or requests.get

    When:
        - Running function get_response_history to retrieve the response's history

    Then:
        - Validating the structure of the returned array

    """
    from HTTPListRedirects import get_response_history

    url = params["url"]
    use_head = params["useHead"]
    request_using_head = use_head == "true"

    adapter = requests_mock.Adapter()
    adapter.add_matcher(custom_matcher)
    session = requests.Session()
    session.mount(prefix=MOCK_ADDR, adapter=adapter)
    if request_using_head:
        response = session.head(f"{MOCK_ADDR}{url}")
    else:
        response = session.get(f"{MOCK_ADDR}{url}")
    urls = get_response_history(response=response)
    assert urls == expected_results


HISTORY_URLS_CASES = [
    (
        [
            {"Data": "http://example.com/", "Status": 301},
            {"Data": "https://example.com/", "Status": 301},
            {"Data": "https://www.example.org/", "Status": 200},
        ]
    )
]


@pytest.mark.parametrize("history_urls", HISTORY_URLS_CASES)
def test_valid_command_result(history_urls):
    """
    Given:
        - A valid parsed response history

    When:
        - Running the function create_command_result to create the output for the command

    Then:
        - Validating the structure of the returned result to the user

    """
    from CommonServerPython import entryTypes, formats, tableToMarkdown
    from HTTPListRedirects import create_command_result

    ec = {"URL(val.Data == obj.Data)": [{"Data": history_url["Data"]} for history_url in history_urls]}
    expected_command_result = {
        "ContentsFormat": formats["json"],
        "Type": entryTypes["note"],
        "Contents": history_urls,
        "ReadableContentsFormat": formats["markdown"],
        "HumanReadable": tableToMarkdown("URLs", history_urls, ["Data", "Status"]),
        "EntryContext": ec,
    }
    command_result = create_command_result(history_urls=history_urls)
    assert command_result == expected_command_result


SYSTEM_PROXY_CASES = [({"use_system_proxy": "false"})]


@pytest.mark.parametrize("params", SYSTEM_PROXY_CASES)
def test_environment_variables(params):
    """
    Given:
        - The condition where we don't want to use the system's proxy

    When:
        - Running the function delete_environment_variables to delete specific environment variables

    Then:
        - Validating that the specific environment variables got deleted

    """
    import os

    from HTTPListRedirects import delete_environment_variables

    use_system_proxy = params["use_system_proxy"]
    delete_environment_variables(use_system_proxy=use_system_proxy)
    env_variables = ["HTTP_PROXY", "HTTPS_PROXY", "http_proxy", "https_proxy"]
    for env_var in env_variables:
        with pytest.raises(KeyError):
            os.environ[env_var]


USE_HEAD_CASES = [({"useHead": "false"}), ({"useHead": "true"})]


@pytest.mark.parametrize("params", USE_HEAD_CASES)
def test_use_head_variable(requests_mock, params):
    """
    Given:
        - The argument that states if we want to use requests.head or requests.get

    When:
        - Running the function get_response to retrieve the response of a url

    Then:
        - Validating that the request used was requests.head if useHead is true and requests.get otherwise

    """
    from HTTPListRedirects import get_response

    use_head = params["useHead"]
    requests_mock.get("http://examples.test.com")
    requests_mock.head("http://examples.test.com")
    get_response(url="http://examples.test.com", use_head=use_head, verify_ssl=False)
    assert (
        requests_mock.request_history[0].method == "HEAD"
        if use_head == "true"
        else requests_mock.request_history[0].method == "GET"
    )