From 8f78c8aaaccdff9566b7df57ea3ad3bd576918e4 Mon Sep 17 00:00:00 2001 From: ImSavsis Date: Sun, 19 Jul 2026 23:23:04 +0500 Subject: [PATCH] docs: quickstart, api reference, faq --- README.md | 6 +++++ docs/api.md | 38 ++++++++++++++++++++++++++++ docs/faq.md | 25 ++++++++++++++++++ docs/quickstart.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 132 insertions(+) create mode 100644 docs/api.md create mode 100644 docs/faq.md create mode 100644 docs/quickstart.md diff --git a/README.md b/README.md index cec63cc..a8cc2ed 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,12 @@ import pydoh pydoh.patch_socket() ``` +## документация + +- [quickstart](docs/quickstart.md) — установка, базовое использование, свой провайдер +- [api](docs/api.md) — все функции с параметрами +- [faq](docs/faq.md) — зачем это надо, что делать если cloudflare забанят, законно ли + ## фичи - zero deps, только stdlib diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..347f7b6 --- /dev/null +++ b/docs/api.md @@ -0,0 +1,38 @@ +# api + +## `resolve(hostname, record_type=1, providers=None, timeout=3.0, use_cache=True) -> list[str]` + +резолвит хост, возвращает список IP строками. кидает `ResolveError` если все провайдеры упали. + +- `record_type` — `1` для A (по умолчанию), `28` для AAAA +- `providers` — список `Provider`, по умолчанию `pydoh.providers.DEFAULT_PROVIDERS` (cloudflare, google, quad9 по порядку) +- `timeout` — секунды на один HTTPS-запрос к одному провайдеру +- `use_cache` — читать/писать во внутренний кэш по TTL из ответа + +## `resolve4(hostname, **kwargs) -> list[str]` + +то же самое что `resolve(hostname, record_type=1, **kwargs)`. + +## `resolve6(hostname, **kwargs) -> list[str]` + +то же самое что `resolve(hostname, record_type=28, **kwargs)`. + +## `patch_socket() -> None` + +подменяет `socket.getaddrinfo` на версию через `resolve()`. IP-литералы (`127.0.0.1` и т.п.) пропускает мимо DoH напрямую. идемпотентно — повторный вызов ничего не ломает. + +## `unpatch_socket() -> None` + +возвращает оригинальный `socket.getaddrinfo`. + +## `ResolveError` + +исключение, вылетает из `resolve()`/`resolve4()`/`resolve6()` если ни один провайдер не ответил валидно. + +## `pydoh.providers.Provider` + +```python +Provider(name: str, host: str, path: str) +``` + +именованный tuple, описывает DoH-эндпоинт. готовые: `pydoh.CLOUDFLARE`, `pydoh.GOOGLE`, `pydoh.QUAD9`. diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..658fe80 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,25 @@ +# faq + +## зачем это вообще + +обычный DNS — незашифрованный UDP-пакет к резолверу провайдера, кто угодно на пути видит какой домен ты спрашиваешь. в РФ это самый дешёвый способ блокировки — провайдер просто не отвечает на запрос про заблокированный домен. DoH заворачивает тот же запрос в HTTPS, провайдер видит только "коннект к 1.1.1.1", а не имя домена. + +## cloudflare тоже забанен, что делать + +сам cloudflare (его IP-диапазоны) массово не блокируют — через него живёт куча обычных сайтов, задеть его целиком означает положить половину интернета. а вот конкретно `cloudflare-dns.com` как известный анти-цензурный эндпоинт — уже могут таргетить точечно по SNI. + +если это произошло — `pydoh` сам едет на `dns.google`, потом на `dns.quad9.net` (см. `DEFAULT_PROVIDERS`), без твоего участия. + +если и туда достанут — тогда нужен свой DoH-эндпоинт на домене, которого нет в блок-листах, см. [quickstart.md](quickstart.md#свой-doh-провайдер). + +## а это законно + +`pydoh` просто шлёт DNS-запросы другим транспортом (HTTPS вместо UDP). это тот же протокол, который сейчас включён по умолчанию в Firefox/Chrome для миллионов пользователей. + +## почему не requests/httpx + +zero deps — библиотека не тянет вообще ничего кроме stdlib. весь HTTPS через `http.client`+`ssl`, которые уже есть в питоне из коробки. + +## поддерживает DNSSEC? + +нет. и не планируется — это резолвер для обхода блокировок и приватности, а не для валидации подписей. diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..1fbc846 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,63 @@ +# quickstart + +## установка + +``` +pip install pydoh +``` + +## разовый резолвинг + +```python +import pydoh + +ips = pydoh.resolve("example.com") +print(ips) # ['93.184.216.34'] +``` + +`resolve()` возвращает список строк-адресов, первый обычно и есть тот, что нужен. + +## ipv6 + +```python +ips = pydoh.resolve6("example.com") +``` + +или через параметр: + +```python +pydoh.resolve("example.com", record_type=28) +``` + +## подменить резолвинг во всём приложении + +самый частый кейс — не переписывать код, а просто подменить как питон резолвит домены: + +```python +import pydoh +pydoh.patch_socket() + +import requests +requests.get("https://example.com") # уже через DoH, без изменений в коде requests +``` + +ставь `patch_socket()` в самом начале скрипта, до импорта/использования сетевых библиотек. + +вернуть как было: + +```python +pydoh.unpatch_socket() +``` + +## свой DoH-провайдер + +если хочешь резолвить через свой сервер, а не через cloudflare/google/quad9: + +```python +from pydoh.providers import Provider + +my_provider = Provider(name="mine", host="doh.example.com", path="/dns-query") +ips = pydoh.resolve("example.com", providers=[my_provider]) +``` + +сервер должен поддерживать [RFC 8484](https://www.rfc-editor.org/rfc/rfc8484) (`POST` с телом `application/dns-message`).