idna-ssl
The `idna-ssl` library provides a patch for Python's standard `ssl.match_hostname` function to correctly support Unicode (IDNA) domains. It aims to offer backward compatibility for older Python versions (pre-3.7) where `ssl.match_hostname` had significant issues with internationalized domain names, and to address lingering IDNA2008 compliance problems even in later Python releases. The library's current version is 1.1.0, released in July 2018. The project's GitHub repository has been archived and is read-only since October 2020, indicating it is no longer actively maintained.
Warnings
- breaking The library applies a global monkey-patch to `ssl.match_hostname`. This can lead to unexpected behavior or conflicts if other libraries also attempt to modify `ssl.match_hostname` or rely on its unpatched behavior. Ensure compatibility with other dependencies.
- deprecated The GitHub repository for `idna-ssl` was archived on October 22, 2020, making it read-only. This indicates the project is no longer actively maintained, and no further updates, bug fixes, or security patches will be provided. Users should be aware of the risks associated with using unmaintained software.
- gotcha While Python 3.7 and later versions generally improved IDNA handling in `ssl.match_hostname`, the `idna-ssl` library's motivation states that 'IDNA2008 is still broken' even in Python 3.7. This suggests that `idna-ssl` specifically addresses IDNA2008 compliance beyond what the standard library provides, which can be a subtle distinction.
- gotcha The functionality of `ssl.match_hostname` itself has evolved, particularly concerning wildcard certificate matching, with security fixes (e.g., CVE-2013-7440). Relying on a globally patched version might obscure further security updates to the underlying `ssl` module in newer Python releases.
Install
-
pip install idna-ssl
Imports
- patch_match_hostname
from idna_ssl import patch_match_hostname
Quickstart
from idna_ssl import patch_match_hostname
import asyncio
import aiohttp
# Apply the patch globally as early as possible in your application
patch_match_hostname()
# Example usage with aiohttp accessing an IDNA domain
URL = 'https://цфоут.мвд.рф/news/item/8065038/'
async def main():
async with aiohttp.ClientSession() as session:
async with session.get(URL) as response:
print(f"Status: {response.status}")
print(f"Content-Type: {response.headers.get('Content-Type')}")
if __name__ == '__main__':
# This example requires Python 3.7+ for asyncio.run()
# For older Python versions, use loop = asyncio.get_event_loop(); loop.run_until_complete(main())
try:
asyncio.run(main())
except RuntimeError:
loop = asyncio.get_event_loop()
loop.run_until_complete(main())