Перенаправление nginx x-accel на хранилище gcloud возвращает пустую HTML-страницу
Статья: Я запускаю приложение django (DRF) за прокси-сервером nginx. Медиафайлы хранятся в частном ведре Google Cloud Storage. Приложение Django вместе с nginx размещено в облачном хранилище и имеет все необходимые разрешения для доступа к ведру. (Оно может загружать файлы без проблем). Бэкенд хранилища - библиотека django-storages.
Проблема: Сервер возвращает пустой html.
PS: Я не использую подписанные урлы, так как мое приложение django имеет необходимые разрешения & учетные данные для доступа к ведру. Но я не уверен, достаточно ли этого для потоковой передачи файлов клиенту и в этом ли проблема.
Мой код:
(django storage) settings.py
# STORAGES
# --------------------------------------------------------------
DOMAIN_NAME = env.str("DOMAIN_NAME")
SECRET_PATH = env.str("G_STORAGE_SECRET_PATH")
GS_CREDENTIALS = service_account.Credentials.from_service_account_file(SECRET_PATH)
GS_BUCKET_NAME = env("GS_BUCKET_NAME")
GS_PROJECT_ID = env.str("GS_PROJECT_ID")
GS_EXPIRATION = env.int("GS_EXPIRATION", 28800) # 8 hours
GS_IS_GZIPPED = env.bool("GS_IS_GZIPPED", True)
GS_CUSTOM_ENDPOINT = "https://" + DOMAIN_NAME
GS_QUERYSTRING_AUTH = False
MEDIA_LOCATION = "my_project/media"
STORAGES = {
"default": {
"BACKEND": "storages.backends.gcloud.GoogleCloudStorage",
"OPTIONS": {
"location": MEDIA_LOCATION,
"file_overwrite": True,
},
},
}
MEDIA_URL = f"https://{DOMAIN_NAME}/{GS_BUCKET_NAME}/{MEDIA_LOCATION}/"
urls.py
re_path(
r"^my_project/media/app/users/(?P<user_id>[^/]+)/files/(?P<filename>[^/]+)/$",
gcloud_storage.gcloud_redirect,
name="gcloud_storage_redirect",
),
view.py
def gcloud_redirect(request, user_id, filename):
file_id = filename.split(".")[0]
user_file = get_object_or_404(UserFile, id=file_id)
file_URI = user_file.file
bucket_name = settings.GS_BUCKET_NAME
media_prefix = settings.MEDIA_LOCATION
# Create a response with the X-Accel-Redirect header
response = HttpResponse(status=200)
redirect_url = f"/protected/media/{bucket_name}/{media_prefix}/{file_URI}"
response["X-Accel-Redirect"] = redirect_url
return response
nginx.conf
location /protected/media/ {
internal;
proxy_pass https://storage.cloud.google.com/;
proxy_max_temp_file_size 0;
}
location / {
proxy_pass http://127.0.0.1:$PORT;
proxy_set_header Host $host;
# proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
}
PS: для proxy_pass
я пробовал и https://storage.cloud.google.com/, и https://storage.googleapis.com/, но ни один из них не сработал.
Django генерирует пользовательский url (с моим доменным именем), но когда я делаю запрос к нему, он возвращает пустую html-страницу.
Журналы Google Cloud Run не дали никаких сведений.
Желаемое состояние: Для клиента должен быть открыт мой пользовательский url. Чтобы контролировать доступ к файлам, когда пользователь делает запрос к пользовательскому url для получения файлов, запрос проходит через приложение django, после того как пользователь убедится, что у него есть нужные права, запрос пользователя будет перенаправлен в облачное хранилище с помощью функции x-accel-redirect в nginx, url в строке url остается прежним, но файлы будут передаваться непосредственно из облачного хранилища google.