DRF request with chunked transfer encoding

Hello! I need to use a 3rd party client that sends files using a chunked transfer encoding to a DRF route of my Django app. I tried to set up a custom parser, but the stream is always None. It works without a problem when I send a file without chunked encoding. When looking at the source code of DRF it seems that chunked requests are not supported as the stream is set to None when no Content-Length is provided (which is the case in chunked encoding). Is there some workaround, or can I find an example somewhere of how to read a chunked data stream from a request?

copy-pasting this from an old project (3.2), I hope it helps!


MIDDLEWARE = [
    # you might want to experiment with the order of the middleware, 
    # depending on what's going on in your app
...
    'this_is_a_module.middlewares.ChunkedTransferMiddleware',
...
]

from django.utils.deprecation import MiddlewareMixin

class ChunkedTransferMiddleware(MiddlewareMixin):
    def process_request(self, request):
        if 'HTTP_TRANSFER_ENCODING' in request.META and request.META['HTTP_TRANSFER_ENCODING'] == 'chunked':
            try:
                # assemble chunks into the complete stream
                request._body = b''
                while True:
                    chunk_size = int(request.readline(), 16)  # read the size of the chunk
                    if chunk_size == 0:
                        break  # Last chunk
                    request._body += request.read(chunk_size)  # read the chunk
                    request.read(2)  # read the trailing '\r\n'
                request._read_started = False
            except Exception as e:
                raise ValueError("Failed to read chunked request: {}".format(str(e)))


from rest_framework.parsers import BaseParser

class RawDataParser(BaseParser):
    """
    Plain text parser.
    """
    media_type = 'application/octet-stream'

    def parse(self, stream, media_type=None, parser_context=None):
        return stream.body


from rest_framework.views import APIView
from your_app.parsers import RawDataParser

class ThisIsAview(APIView):
    parser_classes = (RawDataParser,)

    def post(self, request, *args, **kwargs):
        # bunch of things here 
        data = request.data
        return Response({'status': 'received', 'data': data})

That looks pretty cool. I never thought about putting it in a middleware. I will try it out. Thanks a lot!