Джанго как S3 прокси - PullRequest
       24

Джанго как S3 прокси

4 голосов
/ 14 апреля 2010

Я расширил ModelAdmin с помощью настраиваемого поля «Загрузить файл», которое представляет собой ссылку на URL в моем проекте Django, например:

http://www.myproject.com/downloads/1

Там я хочу передать файл, который хранится в S3-корзине. Файлы в корзине недоступны для публичного чтения, и пользователь может не иметь прямого доступа к нему. Теперь я хочу

  • избегать загрузки файла в память сервера (это файлы multi-gb)
  • не иметь временных файлов на сервере

Идеальным решением было бы позволить django выступать в роли прокси-сервера, который передает потоки S3 напрямую пользователю. Я использую boto, но не нашел возможности для потоковой передачи фрагментов. Есть идеи?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 18 мая 2010

Вместо того, чтобы проксировать, почему бы просто не перенаправить?

Используйте представление django по адресу www.myproject.com/downloads/1 для предоставления HTTP-перенаправления на URL-адрес хранилища S3 - можно создавать аутентифицированные URL-адреса с ограниченным временем, например, смотри здесь http://docs.amazonwebservices.com/AmazonS3/2006-03-01/dev/

Затем клиент загружает файл непосредственно с S3, но его содержимое остается безопасным, и доступ должен осуществляться через ваше приложение Django

0 голосов
/ 14 марта 2019

Да, вы можете использовать Django в качестве прокси для потоковой передачи ваших файлов S3 пользователю.

  1. Создайте стандартную ссылку S3 для вашего файла.
  2. Используйте библиотеку requests для извлечения файла в потоковом режиме.
  3. Используйте Django для подачи необработанного потока пользователю.
import requests, boto3
from django.views.generic import View
from django.http.response import HttpResponse

class MediaDownloadView(View):

    def get(self, request, *args, **kwargs):
        s3 = boto3.resource(
            service_name='s3', aws_access_key_id='XXX_AWS_ACCESS_KEY_ID',
            aws_secret_access_key='XXX_AWS_ACCESS_KEY',
        )
        url = s3.meta.client.generate_presigned_url(
            ClientMethod="get_object", ExpiresIn=3600,
            Params={
                "Bucket": 'XXX_BUCKET_NAME',
                "Key": 'XXX_OBJECT_KEY',
            },
        )
        r = requests.get(url=url, stream=True)
        r.raise_for_status()
        response = HttpResponse(r.raw, content_type='audio/mp3')
        response['Content-Disposition'] = 'inline; filename=music.mp3'
        return response
...