diff --git a/CHANGELOG.md b/CHANGELOG.md index 6425c33..b493b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ * `get_object_function` should contain the Python path to a function that takes a request object and returns an object matching the ActivityPub ID for the request or `None`. * `process_payload_function` should contain the Python path to a function that takes in a request object. It should return `True` if successful (or placed in queue for processing later) or `False` in case of any errors. +* Added network utility `network.fetch_host_ip` to fetch IP by hostname. + ### Changed * **Backwards incompatible.** Lowest compatible Python version is now 3.6. diff --git a/federation/tests/utils/test_network.py b/federation/tests/utils/test_network.py index 7c4543b..95bca46 100644 --- a/federation/tests/utils/test_network.py +++ b/federation/tests/utils/test_network.py @@ -5,7 +5,7 @@ from requests import HTTPError from requests.exceptions import SSLError, RequestException from federation.utils.network import ( - fetch_document, USER_AGENT, send_document, fetch_country_by_ip, fetch_host_ip_and_country) + fetch_document, USER_AGENT, send_document, fetch_country_by_ip, fetch_host_ip_and_country, fetch_host_ip) @patch('federation.utils.network.ipdata', autospec=True) @@ -98,10 +98,18 @@ class TestFetchDocument: assert exc.__class__ == RequestException -class TestHostIpAndCountry: +class TestFetchHostIp: @patch('federation.utils.network.socket.gethostbyname', autospec=True, return_value='127.0.0.1') + def test_calls(self, mock_get_ip): + result = fetch_host_ip('domain.local') + assert result == '127.0.0.1' + mock_get_ip.assert_called_once_with('domain.local') + + +class TestFetchHostIpAndCountry: @patch('federation.utils.network.fetch_country_by_ip', autospec=True, return_value='FI') - def test_calls(self, mock_fetch_country, mock_get_ip): + @patch('federation.utils.network.fetch_host_ip', autospec=True, return_value='127.0.0.1') + def test_calls(self, mock_get_ip, mock_fetch_country): result = fetch_host_ip_and_country('domain.local') assert result == ('127.0.0.1', 'FI') mock_get_ip.assert_called_once_with('domain.local') diff --git a/federation/utils/network.py b/federation/utils/network.py index 367a2c2..dfe4cb2 100644 --- a/federation/utils/network.py +++ b/federation/utils/network.py @@ -1,5 +1,6 @@ import logging import socket +from typing import Tuple import requests from ipdata import ipdata @@ -95,13 +96,24 @@ def fetch_document(url=None, host=None, path="/", timeout=10, raise_ssl_errors=T return None, None, ex -def fetch_host_ip_and_country(host): +def fetch_host_ip(host: str) -> str: """ - Fetch ip and country by host + Fetch ip by host """ try: ip = socket.gethostbyname(host) except socket.gaierror: + return '' + + return ip + + +def fetch_host_ip_and_country(host: str) -> Tuple: + """ + Fetch ip and country by host + """ + ip = fetch_host_ip(host) + if not host: return '', '' country = fetch_country_by_ip(ip)