24

Django に HTTP バイト範囲の既存の実装はありますか? つまり、クライアントが Range: ヘッダーを送信すると、Django アプリがそれを受け入れて、HTTP "206 Partial Content" 応答で応答するようにします。

ゼロから何かを書くこともできますが、誰かがすでにこれを行っているのでしょうか?

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

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

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

4

4 に答える 4

11

Django 1.11 以降で動作するはずの基本的なミドルウェア コードを次に示します。単一の範囲のみを処理しますが、個人的に必要なのはそれだけです。

import os

from django.utils.deprecation import MiddlewareMixin


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',
]
于 2016-03-10T21:50:03.617 に答える
10

関連する 2 つの機能リクエストがあります (1 つは未解決で、もう 1 つは最初のリクエストの複製です)。

どちらの問題も、 Google グループのディスカッションに基づいています。

チケットは、アーキテクチャ上の問題と、これが本当に Django がサポートすべきものであるかどうかについてのコンセンサスがないため、 「ハング」状態にあります。ほとんどの場合、Web サーバーはバイト サービスを提供できるためです。

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

フォークを試すか、ソリューションを独自のベースとして使用できます。

参考までに、ここで別の試みが行われました。まだ完了していませんが、レビューするのに役立ちます。


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

于 2014-12-26T21:30:11.717 に答える
0

テストでこれが必要なだけで、 (チャンクなどの他の多くの利点がある)nginx前に実行することを気にしない場合は、http/server/locationに追加できます。たとえば、ビデオをシークできるようにするためにこれを必要とする Chrome などの問題 (設定により) など。djangoproxy_force_ranges on;video.currentTime

于 2021-01-20T03:38:07.640 に答える