1

In my project I use AWS S3 Bucket for media files. Project contains media_app application, that provide get and post requests to files in remote storage (all requests go through server, so media_app is kinda proxy between frontend and AWS S3.

Today I faced with problem. When I try to get media file from AWS S3, Django correctly download it from remote bucket, save it in /tmp/ dir, get correct response metadata, but response itself is broken: it cause infinite response "in progress" state on frontend side (Tried with Postman and Swagger). "In progress" means "frontend application wait until response will be recieved", but on backend side there is no infinite loop. Django can provide next responses even if I use dev test server (Is is means, that no workers are blocked, cause django test server have only one worker).

Information about request and response (Django Silk): enter image description here

There is a part of my view, that provide image download:

from django.http import Http404, StreamingHttpResponse
from wsgiref.util import FileWrapper

class ImageDetailAPIView(DetailDownloadAPIView):
    queryset = Image.objects.filter(is_soft_deleted=False)\
                            .prefetch_related('thumbnails')
    serializer_class = ImageSerializer
    
    @swagger_auto_schema(responses=image_detail_responses)
    def get(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
        except Http404:
            raise FileNotFoundException
        
        service = ImageDownloadService(instance)
        chunk_size = 8192
        file_path, status_code = service.download()
        if status_code == 200:
            response = StreamingHttpResponse(
                FileWrapper(open(file_path, 'rb'), chunk_size),
                content_type=instance.mime_type
            )
            response['Content-Length'] = instance.size
            response['Content-Disposition'] = "attachment; filename=%s" % instance.file_name
            return response
        raise UnexpectedCaseException(is_for_file=True)

service architecture and code doesn't important, because I've already discover, that it works correctly: image correct identify in AWS and further download to /tmp/downloaded-file.webp. Replace StreamingHttpResponse by FileResponse doesn't work. I've tested it all with images with .png and .webp formats, and it doesn't work anyway.

Dmitriy Lunev
  • 177
  • 2
  • 12

1 Answers1

1

I've solved the issue by using this post (but didn't find any cause of it):

  1. add django.middleware.gzip.GZipMiddleware middleware to MIDDLEWARE project settings variable.
  2. write a subclass for my existing FileWrapper (code below).

FixedFileWrapper:

class FixedFileWrapper(FileWrapper):
    def __iter__(self):
        self.filelike.seek(0)
        return self

Maybe, someone can explain me the reason my issue?

Dmitriy Lunev
  • 177
  • 2
  • 12