Чем urllib.request отличается от curl или httpx по поведению? Получение 401 в запросе к Реестру контейнеров Google - PullRequest
0 голосов
/ 27 мая 2020

В настоящее время я работаю над кодом для взаимодействия с изображениями в реестре контейнеров Google. У меня есть рабочий код с использованием простого curl и httpx. Я пытаюсь создать пакет без сторонних зависимостей. Меня интересует конкретная конечная точка, из которой я получаю успешный ответ в curl и httpx, но 401 Unauthorized с использованием urllib.request.

Сценарий bash, демонстрирующий то, что я пытаюсь достичь, выглядит следующим образом . Он извлекает токен доступа из API реестра, затем использует этот токен, чтобы убедиться, что API действительно работает с версией 2, и пытается получить доступ к определенной конфигурации изображения Docker. Боюсь, что для проверки вам потребуется доступ к частному изображению GCR и дайджест для одного из тегов.

#!/usr/bin/env bash

set -eu

token=$(gcloud auth print-access-token)
image=...
digest=sha256:...

get_token() {
    curl -sSL \
        -G \
        --http1.1 \
        -H "Authorization: Bearer ${token}" \
        -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
        --data-urlencode "scope=repository:$1:pull" \
        --data-urlencode "service=gcr.io" \
        "https://gcr.io/v2/token" | jq -r '.token'
}

echo "---"
echo "Retrieving access token."
access_token=$(get_token ${image})

echo
echo "---"
echo "Testing version 2 capability with access token."
curl -sSL \
    --http1.1 \
    -o /dev/null \
    -w "%{http_code}" \
    -H "Authorization: Bearer ${access_token}" \
    -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
    https://gcr.io/v2/

echo
echo "---"
echo "Retrieving image configuration with access token."
curl -vL \
    --http1.1 \
    -o /dev/null \
    -w "%{http_code}" \
    -H "Authorization: Bearer ${access_token}" \
    -H "Accept: application/vnd.docker.distribution.manifest.v2+json" \
    "https://gcr.io/v2/${image}/blobs/${digest}"

Я дополнительно создал два блокнота Jupyter, демонстрирующих свои решения в httpx и без urllib.request. Httpx работает отлично, в то время как urllib почему-то не выполняет запрос конфигурации изображения. У меня заканчиваются идеи, пытаясь найти разницу. Если вы запустите записную книжку самостоятельно, вы увидите, что вызываемый URL-адрес содержит токен в качестве параметра запроса (это проблема безопасности?). Когда я открываю эту ссылку, я могу успешно загрузить данные самостоятельно. Может быть, urllib по-прежнему передает заголовок авторизации с токеном-носителем, из-за которого последний вызов завершается неудачно с ошибкой 401 Unauthorized?

1 Ответ

0 голосов
/ 28 мая 2020

Я провел небольшое расследование и считаю, что разница в том, что последний вызов "https://gcr.io/v2/${image}/blobs/${digest}" действительно содержит перенаправление. Проверка вызовов curl и httpx показала мне, что оба не включают заголовок Authorization во втором перенаправленном запросе, тогда как в том, как я настроил urllib.request в записной книжке, этот заголовок всегда включен . Немного странно, что это приводит к 401, но теперь я знаю, как это исправить.

Изменить: теперь я могу подтвердить, что, создав экземпляр urllib.request.Request и, в отличие от связанной записной книжки, добавьте заголовок авторизации с методом запроса add_unredirected_header все работает как положено.

...