統計 Djangoのバイト範囲




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

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',
]

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

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

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

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

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


関連する2つの機能リクエスト(1つは開いていて、もう1つは最初のものの複製です)です。

どちらの問題もGoogle Groupの議論に基づいています

このチケットは、建築上の懸念や、これが実際にDjangoがサポートすべきものであるかどうかについてのコンセンサスがないため、 「ぶら下がった」状態にあります。 ほとんどの場合、Webサーバーはバイトサービスが可能です。

まだ実装に興味がある場合は、 StreamingHttpResponseを使用して応答をチャンクで返すための特別なRangedFileReaderクラスを実装して送信された未審査のパッチがありますHTTP_RANGEヘッダーの解析とサニティチェックがあります:

フォークを試したり、自分のベースとしてソリューションを使用することができます。

参考にして、 hereもう一つの試みがhereました。それは完了していませんでしたが、検討するのに役立つことがあります。

Rangeヘッダーを解析するには、以下を参照してください。


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

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

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

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

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

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

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

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

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

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





http-headers