среда, 3 марта 2021 г.

Модули в Golang: прокси модуля, протокол GOPROXY

Прокси модуля - это HTTP-сервер, который может отвечать на GET запросы для путей, указанных ниже. Запросы не имеют параметров запроса и не требуются определенные заголовки, поэтому даже сайт, обслуживающий фиксированную файловую систему (включая URL-адрес file://), может быть прокси модуля.

Успешные ответы HTTP должны иметь код состояния 200 (ОК). Выполняются перенаправления (3xx). Ответы с кодами состояния 4xx и 5xx обрабатываются как ошибки. Коды ошибок 404 (Not Found) и 410 (Gone) указывают на то, что запрошенный модуль или версия недоступны на прокси-сервере, но могут быть найдены в другом месте. Сообщения об ошибках должны иметь тип содержимого text/plain с кодировкой utf-8 или us-ascii.

Команду go можно настроить для связи с прокси-серверами или серверами управления версиями с помощью переменной среды GOPROXY, которая принимает список URL-адресов прокси. Список может включать ключевые слова direct или off. Элементы списка могут быть разделены запятыми (,) или вертикальными чертами (|), которые определяют поведение при возникновении ошибки. Когда за URL-адресом следует запятая, команда go возвращается к более поздним источникам только после ответа 404 (Not Found) или 410 (Gone). Когда за URL-адресом следует вертикальная черта, команда go возвращается к более поздним источникам после любой ошибки, включая ошибки, не относящиеся к HTTP, такие как таймауты. Такое поведение обработки ошибок позволяет прокси-серверу действовать как привратник (gatekeeper) для неизвестных модулей. Например, прокси-сервер может ответить с ошибкой 403 (Forbidden) для модулей, не включенных в утвержденный список.

Ниже указаны запросы, на которые должен отвечать прокси-сервер модуля. Для каждого пути $base - это часть пути URL-адреса прокси, $module - это путь к модулю, а $version - это версия. Например, если URL-адрес прокси - https://example.com/mod, и клиент запрашивает файл go.mod для модуля golang.org/x/text в версии v0.3.2, клиент отправит GET запрос https://example.com/mod/golang.org/x/text/@v/v0.3.2.mod.

Чтобы избежать неоднозначности при обслуживании из файловых систем без учета регистра, элементы $module и $version кодируются с учетом регистра, заменяя каждую прописную букву восклицательным знаком, за которым следует соответствующая строчная буква. Это позволяет хранить на диске модули example.com/M и example.com/m, поскольку первый кодируется как example.com/!m.

Путь $base/$module/@v/list

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

Путь $base/$module/@v/$version.info

Возвращает метаданные в формате JSON о конкретной версии модуля. Ответ должен быть объектом JSON, который соответствует структуре данных Go ниже:

type Info struct {
    Version string    // строка версии
    Time    time.Time // время коммита
}

Поле Version является обязательным и должно содержать действительную каноническую версию. $version в пути запроса не обязательно должна быть той же или даже действительной версией; эта конечная точка может использоваться для поиска версий для имен веток или идентификаторов ревизий. Однако, если $version является канонической версией с основной версией, совместимой с $module, поле Version в успешном ответе должно быть таким же.

Поле Time не является обязательным. Если присутствует, это должна быть строка в формате RFC 3339. Он указывает время, когда версия была создана.

В будущем могут быть добавлены другие поля, поэтому другие имена зарезервированы.

Путь $base/$module/@v/$version.mod

Возвращает файл go.mod для конкретной версии модуля. Если у модуля нет файла go.mod в запрошенной версии, должен быть возвращен файл, содержащий только оператор модуля с запрошенным путем к модулю. В противном случае необходимо вернуть исходный немодифицированный файл go.mod.

Путь $base/$module/@v/$version.zip

Возвращает zip-файл, с содержимым определенной версии модуля.

Путь $base/$module/@latest

Возвращает метаданные в формате JSON о последней известной версии модуля в том же формате, что и $base/$module/@v/$version.info. Последняя версия должна быть той версией модуля, которую команда go должна использовать, если $base/$module/@v/list пуст или указанная версия не подходит. Эта конечная точка является необязательной, и прокси-серверы модулей не требуются для ее реализации.

При разрешении последней (latest) версии модуля команда go запросит $base/$module/@v/list, а затем, если подходящие версии не найдены, $base/$module/@latest. Команда go отдает предпочтение в следующем порядке: семантически самая высокая версия релиза, семантически самая высокая предварительная версия и хронологически самая последняя псевдоверсия. В Go 1.12 и ранее команда go считала псевдоверсии в $base/$module/@v/list предварительными версиями, но это уже не так, начиная с Go 1.13.

Прокси-сервер модуля всегда должен обслуживать одно и то же содержимое для успешных ответов на запросы $base/$module/$version.mod и $base/$module/$version.zip. Этот контент криптографически аутентифицируется с использованием файлов go.sum и, по умолчанию, базы данных контрольных сумм.

Команда go кеширует большую часть содержимого, загружаемого с прокси-серверов модуля, в свой кеш модуля в $GOPATH/pkg/mod/cache/download. Даже при загрузке напрямую из систем контроля версий команда go синтезирует явно info, mod и zip файлы и сохраняет их в этом каталоге, как если бы они были загружены непосредственно с прокси-сервера. Макет кеша такой же, как и пространство URL-адресов прокси, поэтому обслуживание $GOPATH/pkg/mod/cache/download на (или копирование на) https://example.com/proxy позволит пользователям получать доступ к версиям кешированных модулей, установив GOPROXY на https://example.com/proxy.


Читайте также:


Комментариев нет:

Отправить комментарий