統計 - Djangoのバイト範囲




大阪 プログラミング インターン (2)

DjangoにHTTPバイト範囲の実装がありますか? つまり、クライアントがRange:ヘッダーを送信するときに、私はDjangoアプリケーションがそれを受け入れ、HTTP "206 Partial Content"応答で返信したいと思っています。

私はゼロから何かを書くことができましたが、確かに誰かがこれをやっていますか?

これにはさまざまな部分があります。

  1. Rangeヘッダーの解析と正常性チェック
  2. 実際に範囲を生成する
  3. 応答で単一の範囲を返すサポート
  4. 1つの応答で複数の範囲を返すことをサポートし、適切にMIMEエンコードされる

確かに少なくとも(1)と(4)はどこかでライブラリをサポートしていますか?


コンテンツの範囲についての3つの概観

あなたの状況によって適切なものを選んでください。

1.すべての動的ビューと静的ファイルをサポートする

WhiteNoiseはグローバル設定をサポートするミドルウェアを提供します。

2.静的ファイルのみをサポートする

Nginxは静的ファイルとメディアファイルをサポートできます。

uWSGIとnginxを使ってDjangoとWebサーバーを設定する方法の詳細を参照してください。 ビューによっては、静的ファイルやメディアファイルにリダイレクトする必要がある場合は、「 answer 」を参照してください。

3.特定の動的ビューのみをサポートする

Django Ranged Responseはコンテンツ範囲の応答をサポートします。 必要なすべてのビューに対してこの応答を使用します。 このビューは、音声合成、ビデオジェネレータなどのメディアAPI用に設計されています。

宣言:私はDjango Ranged Responseの貢献者です。 しかし、私はWhiteNoiseを使うのが最も簡単だと思います。


Django 1.8+で動作するはずの基本的なミドルウェアコードです。 単一の範囲だけを処理しますが、それは私が個人的に必要とするものです。

import os

try:
    from django.utils.deprecation import MiddlewareMixin
except ImportError:  # django < 1.10
    MiddlewareMixin = object


class RangesMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        if response.status_code != 200 or not hasattr(response, 'file_to_stream'):
            return response
        http_range = request.META.get('HTTP_RANGE')
        if not (http_range and http_range.startswith('bytes=') and http_range.count('-') == 1):
            return response
        if_range = request.META.get('HTTP_IF_RANGE')
        if if_range and if_range != response.get('Last-Modified') and if_range != response.get('ETag'):
            return response
        f = response.file_to_stream
        statobj = os.fstat(f.fileno())
        start, end = http_range.split('=')[1].split('-')
        if not start:  # requesting the last N bytes
            start = max(0, statobj.st_size - int(end))
            end = ''
        start, end = int(start or 0), int(end or statobj.st_size - 1)
        assert 0 <= start < statobj.st_size, (start, statobj.st_size)
        end = min(end, statobj.st_size - 1)
        f.seek(start)
        old_read = f.read
        f.read = lambda n: old_read(min(n, end + 1 - f.tell()))
        response.status_code = 206
        response['Content-Length'] = end + 1 - start
        response['Content-Range'] = 'bytes %d-%d/%d' % (start, end, statobj.st_size)
        return response

settings.pyようにインストールしてください:

MIDDLEWARE_CLASSES = [
    'path.to.RangesMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
]




http-headers