Spec-Zone.ru › Python 3.7

http.cookiejar — Обработка файлов cookie для HTTP-клиентов

Исходный код: Lib/http/cookiejar.py

Модуль http.cookiejar определяет классы для автоматической обработки файлов cookie HTTP. Он полезен для доступа к веб-сайтам, которые требуют установки небольших фрагментов данных — файлов cookie — на клиентском компьютере в ответ HTTP-запроса от веб-сервера, а затем возвращения их на сервер в последующих HTTP-запросах.

Обрабатываются как стандартный протокол файлов cookie Netscape, так и протокол, определенный в RFC 2965. Обработка RFC 2965 отключена по умолчанию. Файлы cookie RFC 2109 парсятся как файлы cookie Netscape и впоследствии обрабатываются как файлы cookie Netscape или RFC 2965 в соответствии с действующей «политикой». Обратите внимание, что подавляющее большинство файлов cookie в Интернете — это файлы cookie Netscape. http.cookiejar пытается следовать фактическому протоколу файлов cookie Netscape (который существенно отличается от спецификации Netscape), включая учет max-age и port атрибутов файлов cookie, введенных в RFC 2965.

Примечание

Различные именованные параметры, встречающиеся в заголовках Set-Cookie и Set-Cookie2 (например, domain и expires) обычно называются атрибутами. Чтобы отличать их от атрибутов Python, в документации этого модуля используется термин атрибут файла cookie вместо.

Модуль определяет следующую исключительную ситуацию:

exception http.cookiejar.LoadError

Экземпляры FileCookieJar генерируют это исключение при неудачной загрузке файлов cookie из файла. LoadError является подклассом OSError.

Изменено в версии 3.3: LoadError был переведён в подкласс OSError вместо IOError.

Предоставляются следующие классы:

class http.cookiejar.CookieJar(policy=None)

policy — объект, реализующий интерфейс CookiePolicy.

Класс CookieJar хранит HTTP-файлы cookie. Он извлекает файлы cookie из HTTP-запросов и возвращает их в HTTP-ответах. Экземпляры CookieJar автоматически удаляют истекшие файлы cookie при необходимости. Подклассы также отвечают за хранение и извлечение файлов cookie из файла или базы данных.

class http.cookiejar.FileCookieJar(filename, delayload=None, policy=None)

policy — объект, реализующий интерфейс CookiePolicy. Для других аргументов см. документацию соответствующих атрибутов.

Объект CookieJar, который может загружать файлы cookie из файла на диске и, возможно, сохранять их в нем. Файлы cookie НЕ загружаются из указанного файла до тех пор, пока не будет вызван метод load() или revert(). Подклассы этого класса описаны в разделе Подклассы FileCookieJar и взаимодействие с веб-браузерами.

class http.cookiejar.CookiePolicy

Этот класс отвечает за принятие решения о том, следует ли принимать каждый файл cookie от/возвращать его на сервер.

class http.cookiejar.DefaultCookiePolicy(blocked_domains=None, allowed_domains=None, netscape=True, rfc2965=False, rfc2109_as_netscape=None, hide_cookie2=False, strict_domain=False, strict_rfc2965_unverifiable=True, strict_ns_unverifiable=False, strict_ns_domain=DefaultCookiePolicy.DomainLiberal, strict_ns_set_initial_dollar=False, strict_ns_set_path=False)

Аргументы конструктора должны передаваться только в качестве ключевых аргументов. blocked_domains — последовательность доменных имён, от которых мы никогда не принимаем и не возвращаем файлы cookie. allowed_domains, если не None, — это последовательность доменных имён, для которых мы принимаем и возвращаем файлы cookie. Для всех остальных аргументов см. документацию объектов CookiePolicy и DefaultCookiePolicy.

DefaultCookiePolicy реализует стандартные правила принятия/отклонения файлов cookie Netscape и RFC 2965. По умолчанию файлы cookie RFC 2109 (т. е. файлы cookie, полученные в заголовке Set-Cookie с атрибутом версии файла cookie равным 1) обрабатываются в соответствии с правилами RFC 2965. Однако, если обработка RFC 2965 выключена или rfc2109_as_netscape True, файлы cookie RFC 2109 «сводятся» экземпляром CookieJar к файлам cookie Netscape, устанавливая атрибут version экземпляра Cookie в 0. DefaultCookiePolicy также предоставляет некоторые параметры для настройки политики.

class http.cookiejar.Cookie

Этот класс представляет файлы cookie Netscape, RFC 2109 и RFC 2965. Не ожидается, что пользователи http.cookiejar будут создавать свои собственные экземпляры Cookie. Вместо этого, при необходимости, вызовите make_cookies() для экземпляра CookieJar.

См. также

Module urllib.request

Открытие URL-адресов с автоматической обработкой файлов cookie.

Module http.cookies

Классы HTTP-файлов cookie, в основном полезные для кода на стороне сервера. Модули http.cookiejar и http.cookies не зависят друг от друга.

https://curl.haxx.se/rfc/cookie_spec.html

Спецификация исходного протокола файлов cookie Netscape. Хотя это по-прежнему доминирующий протокол, «протокол файлов cookie Netscape», реализованный всеми основными браузерами (и http.cookiejar), лишь отдаленно напоминает протокол, описанный в cookie_spec.html.

RFC 2109 - Механизм управления состоянием HTTP

Устарел RFC 2965. Использует Set-Cookie с версией=1.

RFC 2965 - Механизм управления состоянием HTTP

Протокол Netscape с исправленными ошибками. Использует Set-Cookie2 вместо Set-Cookie. Не широко используется.

http://kristol.org/cookie/errata.html

Незавершенные исправления для RFC 2965.

RFC 2964 - Использование управления состоянием HTTP

Объекты CookieJar и FileCookieJar

CookieJar объекты поддерживают протокол итератора для итерирования по содержащимся объектам Cookie.

CookieJar имеет следующие методы:

CookieJar.add_cookie_header(request)

Добавить корректный заголовок Cookie к запросу request.

Если политика разрешает (т.е. атрибуты rfc2965 и hide_cookie2 экземпляра CookieJar’s CookiePolicy истинны и ложны соответственно), также добавляется заголовок Cookie2, если необходимо.

Объект request (обычно экземпляр urllib.request.Request) должен поддерживать методы get_full_url(), get_host(), get_type(), unverifiable(), has_header(), get_header(), header_items(), add_unredirected_header() и атрибут origin_req_host, как документировано в urllib.request.

Изменено в версии 3.3: объект request требует атрибута origin_req_host. Зависимость от устаревшего метода get_origin_req_host() была удалена.

CookieJar.extract_cookies(response, request)

Извлечь куки из HTTP response и сохранить их в CookieJar, если это разрешено политикой.

CookieJar будет искать разрешенные заголовки Set-Cookie и Set-Cookie2 в аргументе response и сохранять куки соответственно (в зависимости от одобрения метода CookiePolicy.set_ok()).

Объект response (обычно результат вызова urllib.request.urlopen() или аналогичного) должен поддерживать метод info(), который возвращает экземпляр email.message.Message.

Объект request (обычно экземпляр urllib.request.Request) должен поддерживать методы get_full_url(), get_host(), unverifiable(), и атрибут origin_req_host, как документировано в urllib.request. Запрос используется для установки значений по умолчанию для атрибутов куки, а также для проверки разрешения установки куки.

Изменено в версии 3.3: объект request требует атрибута origin_req_host. Зависимость от устаревшего метода get_origin_req_host() была удалена.

CookieJar.set_policy(policy)

Установить экземпляр CookiePolicy для использования.

CookieJar.make_cookies(response, request)

Возвращает последовательность объектов Cookie, извлеченных из объекта response.

См. документацию для extract_cookies() для интерфейсов, необходимых для аргументов response и request.

CookieJar.set_cookie_if_ok(cookie, request)

Установить Cookie, если политика разрешает это сделать.

CookieJar.set_cookie(cookie)

Установить Cookie, без проверки с политикой, чтобы определить, нужно ли его устанавливать.

CookieJar.clear([domain[, path[, name]]])

Очистить некоторые куки.

Если вызвана без аргументов, очищаются все куки. Если задан один аргумент, удаляются только куки, принадлежащие данному домену. Если заданы два аргумента, удаляются куки, принадлежащие указанному домену и пути URL. Если заданы три аргумента, удаляется куки с указанным доменом, путем и именем.

Возбуждает KeyError, если соответствующего куки нет.

CookieJar.clear_session_cookies()

Удалить все куки сеанса.

Удаляет все содержащиеся куки, у которых атрибут discard имеет значение true (обычно потому, что у них отсутствовал атрибут куки max-age или expires, или был явный атрибут куки discard). Для интерактивных браузеров конец сеанса обычно соответствует закрытию окна браузера.

Обратите внимание, что метод save() не сохранит куки сеанса, если вы не укажете обратное, передав в качестве аргумента ignore_discard значение true.

FileCookieJar реализует следующие дополнительные методы:

FileCookieJar.save(filename=None, ignore_discard=False, ignore_expires=False)

Сохранить куки в файл.

Этот базовый класс возбуждает NotImplementedError. Подклассы могут оставить этот метод нереализованным.

filename — имя файла, в котором нужно сохранить куки. Если filename не указан, используется self.filename, (по умолчанию значение, переданное в конструктор, если таковое имеется); если self.filename равно None, возбуждается ValueError.

ignore_discard: сохранить даже куки, заданные для удаления. ignore_expires: сохранить даже куки, которые истекли.

Файл перезаписывается, если он уже существует, тем самым удаляя все содержащиеся в нём куки. Сохранённые куки можно восстановить позже, используя методы load() или revert().

FileCookieJar.load(filename=None, ignore_discard=False, ignore_expires=False)

Загрузить куки из файла.

Старые куки сохраняются, если их не перезаписывают загруженные новые.

Аргументы такие же, как у save().

Указанный файл должен быть в формате, понятном для класса, в противном случае возбуждается LoadError. Также может быть возбуждено OSError, например, если файла не существует.

Изменено в версии 3.3: IOError раньше возбуждался, теперь он является псевдонимом OSError.

FileCookieJar.revert(filename=None, ignore_discard=False, ignore_expires=False)

Очистить все куки и перезагрузить куки из сохранённого файла.

revert() может возбудить те же исключения, что и load(). При возникновении ошибки состояние объекта не изменится.

FileCookieJar экземпляры имеют следующие общедоступные атрибуты:

FileCookieJar.filename

Имя файла по умолчанию, в котором хранятся куки. Этот атрибут можно изменять.

FileCookieJar.delayload

Если True, куки загружаются лениво из файла. Этот атрибут изменять не следует. Это лишь подсказка, так как это влияет только на производительность, а не на поведение (если куки на диске меняются). Объект CookieJar может игнорировать его. Ни один из классов FileCookieJar, включенных в стандартную библиотеку, не загружает куки лениво.

Подклассы FileCookieJar и взаимодействие с веб-браузерами

Ниже представлены подклассы CookieJar, предназначенные для чтения и записи.

class http.cookiejar.MozillaCookieJar(filename, delayload=None, policy=None)

Класс FileCookieJar, который может загружать и сохранять куки на диск в формате файлов Mozilla cookies.txt (который также используется браузерами Lynx и Netscape).

Примечание

Этот класс теряет информацию о куки **RFC 2965**, а также о более новых или нестандартных атрибутах куки, таких как port.

Предупреждение

Перед сохранением сделайте резервную копию своих куки, если их потеря/повреждение может быть неудобна (есть некоторые тонкости, которые могут привести к небольшим изменениям в файле при многократном загрузке/сохранении).

Также обратите внимание, что куки, сохраненные во время работы Mozilla, будут перезаписаны Mozilla.

class http.cookiejar.LWPCookieJar(filename, delayload=None, policy=None)

Класс FileCookieJar, который может загружать и сохранять куки на диск в формате, совместимом с библиотекой libwww-perl Set-Cookie3 . Это удобно, если вы хотите хранить куки в человекочитаемом файле.

Объекты политики куки

Объекты, реализующие интерфейс CookiePolicy, имеют следующие методы:

CookiePolicy.set_ok(cookie, request)

Возвращает булево значение, указывающее, следует ли принять куки от сервера.

cookie — экземпляр Cookie. request — объект, реализующий интерфейс, определенный в документации для CookieJar.extract_cookies().

CookiePolicy.return_ok(cookie, request)

Возвращает булево значение, указывающее, следует ли вернуть куки серверу.

cookie — экземпляр Cookie. request — объект, реализующий интерфейс, определенный в документации для CookieJar.add_cookie_header().

CookiePolicy.domain_return_ok(domain, request)

Возвращает False, если куки не должны быть возвращены, учитывая домен куки.

Этот метод является оптимизацией. Он устраняет необходимость проверки каждого куки с определенным доменом (что может потребовать чтения многих файлов). Возвращение true из domain_return_ok() и path_return_ok() оставляет всю работу return_ok().

Если domain_return_ok() возвращает true для домена куки, вызывается path_return_ok() для пути куки. В противном случае, path_return_ok() и return_ok() никогда не вызываются для этого домена куки. Если path_return_ok() возвращает true, return_ok() вызывается с объектом Cookie для полной проверки. В противном случае, return_ok() никогда не вызывается для этого пути куки.

Обратите внимание, что domain_return_ok() вызывается для каждого домена cookie, а не только для домена request. Например, функция может быть вызвана как с ".example.com", так и с "www.example.com", если домен запроса равен "www.example.com". То же самое касается path_return_ok().

Аргумент request соответствует документации для return_ok().

CookiePolicy.path_return_ok(path, request)

Возвращает False, если куки не должны быть возвращены, учитывая путь куки.

См. документацию для domain_return_ok().

Помимо реализации методов выше, реализации интерфейса CookiePolicy также должны предоставить следующие атрибуты, указывающие, какие протоколы следует использовать и как. Все эти атрибуты могут быть назначены.

CookiePolicy.netscape

Реализовать протокол Netscape.

CookiePolicy.rfc2965

Реализовать протокол **RFC 2965**.

CookiePolicy.hide_cookie2

Не добавлять заголовок Cookie2 в запросы (наличие этого заголовка указывает серверу, что мы понимаем куки **RFC 2965**).

Наиболее полезный способ определения класса CookiePolicy — это наследование от DefaultCookiePolicy и переопределение некоторых или всех методов выше. Сам CookiePolicy может использоваться в качестве «нулевой политики», позволяя устанавливать и получать любые куки (это маловероятно, что будет полезно).

Объекты политики куки по умолчанию

Реализует стандартные правила для принятия и возврата куки.

Обеспечивает поддержку куки **RFC 2965** и Netscape. Обработка RFC 2965 отключена по умолчанию.

Самый простой способ предоставить собственную политику — переопределить этот класс и вызвать его методы в ваших переопределённых реализациях, прежде чем добавлять свои дополнительные проверки:

import http.cookiejar
class MyCookiePolicy(http.cookiejar.DefaultCookiePolicy):
    def set_ok(self, cookie, request):
        if not http.cookiejar.DefaultCookiePolicy.set_ok(self, cookie, request):
            return False
        if i_dont_want_to_store_this_cookie(cookie):
            return False
        return True

В дополнение к функциям, необходимым для реализации интерфейса CookiePolicy, этот класс позволяет блокировать и разрешать домены установки и получения куки. Также есть несколько переключателей строгости, которые позволяют немного ужесточить довольно свободные правила протокола Netscape (в ущерб блокированию некоторых безобидных куки).

Предоставляется чёрный и белый список доменов (оба отключены по умолчанию). Только домены, отсутствующие в чёрном списке и присутствующие в белом списке (если белый список активен), участвуют в установке и возврате куки. Используйте аргумент конструктора blocked_domains и методы blocked_domains() и set_blocked_domains() (и соответствующие аргументы и методы для allowed_domains). Если вы установили белый список, вы можете его отключить, установив его в None.

Домены в чёрном или белом списках, которые не начинаются с точки, должны быть равны домену куки для сопоставления. Например, "example.com" соответствует записи в чёрном списке "example.com", но "www.example.com" не соответствует. Домены, начинающиеся с точки, сопоставляются с более специфическими доменами. Например, оба "www.example.com" и "www.coyote.example.com" соответствуют ".example.com" (но сам "example.com" не соответствует). IP-адреса являются исключением и должны точно совпадать. Например, если blocked_domains содержит "192.168.1.2" и ".168.1.2", 192.168.1.2 заблокирован, но 193.168.1.2 нет.

DefaultCookiePolicy реализует следующие дополнительные методы:

DefaultCookiePolicy.blocked_domains()

Возвращает последовательность заблокированных доменов (в виде кортежа).

DefaultCookiePolicy.set_blocked_domains(blocked_domains)

Устанавливает последовательность заблокированных доменов.

DefaultCookiePolicy.is_blocked(domain)

Возвращает, находится ли domain в чёрном списке для установки или получения куки.

END_OF_DOCUMENT_MARKER ```
DefaultCookiePolicy.allowed_domains()

Возвращает None, или последовательность разрешённых доменов (в виде кортежа).

DefaultCookiePolicy.set_allowed_domains(allowed_domains)

Устанавливает последовательность разрешённых доменов или None.

DefaultCookiePolicy.is_not_allowed(domain)

Возвращает значение, указывающее, запрещён ли домен domain для установки или получения куки.

DefaultCookiePolicy экземпляры имеют следующие атрибуты, которые все инициализируются из аргументов конструктора с одноимёнными именами и к которым можно обращаться.

DefaultCookiePolicy.rfc2109_as_netscape

Если True, запрашивает, чтобы экземпляр CookieJar понижал версию куки RFC 2109 (т.е. куки, полученные в заголовке Set-Cookie с атрибутом версии cookie равным 1) до куки Netscape, установив атрибут версии экземпляра Cookie в 0. Значение по умолчанию — None, в этом случае куки RFC 2109 понижаются, если и только если обработка RFC 2965 отключена. Таким образом, куки RFC 2109 по умолчанию понижаются.

Общие флаги жёсткости:

DefaultCookiePolicy.strict_domain

Не разрешает сайтам устанавливать двухкомпонентные домены с доменными зонами страны, например .co.uk, .gov.uk, .co.nz. И т.д. Это далеко не идеально и не гарантирует работоспособности!

RFC 2965 флаги жёсткости протокола:

DefaultCookiePolicy.strict_rfc2965_unverifiable

Следуйте правилам RFC 2965 для непроверяемых транзакций (обычно непроверяемой транзакцией является та, которая является результатом перенаправления или запроса изображения, размещённого на другом сайте). Если это значение равно false, куки никогда не блокируются на основе проверяемости.

Флаги жёсткости протокола Netscape:

DefaultCookiePolicy.strict_ns_unverifiable

Применяйте правила RFC 2965 для непроверяемых транзакций даже для куки Netscape.

DefaultCookiePolicy.strict_ns_domain

Флаги, определяющие, насколько строго следует соблюдать правила соответствия домена для куки Netscape. Допустимые значения см. ниже.

DefaultCookiePolicy.strict_ns_set_initial_dollar

Игнорировать куки в заголовках Set-Cookie, имена которых начинаются с '$'.

DefaultCookiePolicy.strict_ns_set_path

Не разрешать установку куки, путь которой не соответствует запрошенному URI.

strict_ns_domain — это набор флагов. Его значение формируется путём побитового объединения (например, DomainStrictNoDots|DomainStrictNonDomain означает, что оба флага установлены).

DefaultCookiePolicy.DomainStrictNoDots

При установке куки «префикс хоста» не должен содержать точки (например, www.foo.bar.com не может установить куки для .bar.com, потому что www.foo содержит точку).

DefaultCookiePolicy.DomainStrictNonDomain

Куки, которые явно не указали атрибут куки domain, могут быть возвращены только в домен, равный домену, который установил куки (например, spam.example.com не получит куки от example.com, у которых отсутствовал атрибут куки domain).

DefaultCookiePolicy.DomainRFC2965Match

При установке куки требуется полное соответствие домену согласно RFC 2965.

Следующие атрибуты предоставлены для удобства и представляют собой наиболее полезные комбинации вышеуказанных флагов:

DefaultCookiePolicy.DomainLiberal

Эквивалентно 0 (т.е. все вышеперечисленные флаги жёсткости домена Netscape отключены).

DefaultCookiePolicy.DomainStrict

Эквивалентно DomainStrictNoDots|DomainStrictNonDomain.

Объекты куки

Cookie экземпляры имеют атрибуты Python, примерно соответствующие стандартным атрибутам куки, указанным в различных стандартах куки. Соответствие не является взаимно однозначным, поскольку существуют сложные правила для присвоения значений по умолчанию, поскольку атрибуты куки max-age и expires содержат эквивалентную информацию, и поскольку куки RFC 2109 могут быть «снижены» модулем http.cookiejar с версии 1 до версии 0 (куки Netscape).

Присваивание этих атрибутов не должно быть необходимым, за исключением редких случаев в методе CookiePolicy. Класс не гарантирует внутреннюю согласованность, поэтому вы должны понимать, что вы делаете, если это сделаете.

Cookie.version

Целое число или None. Куки Netscape имеют version 0. RFC 2965 и RFC 2109 куки имеют атрибут куки version равный 1. Однако обратите внимание, что модуль http.cookiejar может «снижать» куки RFC 2109 до куки Netscape, в этом случае version равно 0.

Cookie.name

Имя куки (строка).

Cookie.value

Значение куки (строка) или None.

Cookie.port

Строка, представляющая порт или набор портов (например, «80» или «80,8080»), или None.

Cookie.path

Путь куки (строка, например, '/acme/rocket_launchers').

Cookie.secure

True если куки должна быть возвращена только по защищённому соединению.

Cookie.expires

Дата истечения срока действия в секундах с начала эпохи, или None. См. также метод is_expired().

Cookie.discard

True если это куки сессии.

Cookie.comment

Строка комментария от сервера, поясняющая функцию этой куки, или None.

Cookie.comment_url

URL ссылки на комментарий от сервера, поясняющий функцию этой куки, или None.

Cookie.rfc2109

True если эта куки была получена как куки RFC 2109 (т.е. куки была получена в заголовке Set-Cookie, а атрибут версии куки в этом заголовке был равен 1). Этот атрибут предоставляется, потому что модуль http.cookiejar может «снижать» куки RFC 2109 до куки Netscape, в этом случае version равно 0.

END_OF_DOCUMENT_MARKER
Cookie.port_specified

True если порт или набор портов были явно указаны сервером (в заголовке Set-Cookie / Set-Cookie2).

Cookie.domain_specified

True если домен был явно указан сервером.

Cookie.domain_initial_dot

True если домен, явно указанный сервером, начинался с точки ('.').

Файлы cookie могут иметь дополнительные нестандартные атрибуты. К ним можно получить доступ, используя следующие методы:

Cookie.has_nonstandard_attr(name)

Возвращает True если файл cookie имеет указанный атрибут.

Cookie.get_nonstandard_attr(name, default=None)

Если файл cookie имеет указанный атрибут, возвращает его значение. В противном случае возвращает default.

Cookie.set_nonstandard_attr(name, value)

Устанавливает значение указанного атрибута файла cookie.

Класс Cookie также определяет следующий метод:

Cookie.is_expired(now=None)

True если время жизни файла cookie истекло. Если задано значение now (в секундах с начала эпохи), возвращает, истек ли срок действия файла cookie в указанное время.

Примеры

Первый пример демонстрирует наиболее распространенное использование http.cookiejar:

import http.cookiejar, urllib.request
cj = http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

Этот пример демонстрирует, как открыть URL-адрес, используя ваши файлы cookie Netscape, Mozilla или Lynx (предполагается соглашение Unix/Netscape для расположения файла cookie):

import os, http.cookiejar, urllib.request
cj = http.cookiejar.MozillaCookieJar()
cj.load(os.path.join(os.path.expanduser("~"), ".netscape", "cookies.txt"))
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

Следующий пример демонстрирует использование DefaultCookiePolicy. Включите файлы cookie RFC 2965, будьте более строгими относительно доменов при установке и возврате файлов cookie Netscape и заблокируйте некоторые домены от установки файлов cookie или их возврата:

import urllib.request
from http.cookiejar import CookieJar, DefaultCookiePolicy
policy = DefaultCookiePolicy(
    rfc2965=True, strict_ns_domain=Policy.DomainStrict,
    blocked_domains=["ads.net", ".ads.net"])
cj = CookieJar(policy)
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj))
r = opener.open("http://example.com/")

© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.7/library/http.cookiejar.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API