1

ダウンロード可能な保護されたファイルを提供するために、NginxとDjangoを一緒にプレイさせようとしています。私はそれを機能させることができません。これが私のNginx構成です:

location ~ ^.*/protected-test/ {
alias /<path-to-my-protected-files-on-server>/;
internal;
}

ファイルを表示するための関連する urls.py:

url(r'^static_files/downloads/protected-test/(?P<filename>.+)$', 'download_or_view',
{'download_dir': '%s%s' % (settings.MEDIA_ROOT, 'downloads/protected-test/'),
'content_disposition_type': 'inline',
'protected': 'True'},
name='protected_files')

私の見解:

def download_or_view(request, content_disposition_type, download_dir, filename=None, protected=False):

'''Allow a file to be downloaded or viewed,based on the request type and
     content disposition value.'''

if request.method == 'POST':
    full_path = '%s%s' % (download_dir, request.POST['filename'])
    short_filename = str(request.POST['filename'])
else:
    full_path = '%s%s' % (download_dir, filename)
    short_filename = str(filename)

serverfile = open(full_path, 'rb')
contenttype, encoding = mimetypes.guess_type(short_filename)
response = HttpResponse(serverfile, mimetype=contenttype)

if protected:
    url = _convert_file_to_url(full_path)
    response['X-Accel-Redirect'] = url.encode('utf-8')

response['Content-Disposition'] = '%s; filename="%s"' % (content_disposition_type, smart_str(short_filename))
response['Content-Length'] = os.stat(full_path).st_size

return response

設定ファイルに 2 つの値があります。

NGINX_ROOT = (os.path.join(MEDIA_ROOT, 'downloads/protected-test'))
NGINX_URL = '/protected-test'

_convert_file_to_url() は完全なファイル パスを取得し、上記の 2 つの設定値を使用して、Nginx が許可する (と思っていた) URL に変換します。

<domain-name>/protected-test/<filename>

したがって、アクセスしようとすると:

<domain-name>/static_files/downloads/protected-test/<filename>

私のブラウザ ウィンドウでは、許可されません (404)。良い。

しかし、許可したいフォームのダウンロードからそのURLにアクセスしようとすると、ブラウザで次のようにリダイレクトされます。

<domain-name>/protected-test/<filename>

それも404です。

私は非常に多くの異なる構成を試しましたが、今では脳が痛いです。:-)

open() でファイルを読み取らず、Nginx に提供させるべきですか? その行を削除すると、恐ろしいゼロバイトのファイルが返されます。リダイレクトされた URL でまだ 404 が返されるのはなぜですか??

4

1 に答える 1

2

open() でファイルを読み取らないようにする必要があります。

そのとおりです。スクリプトでファイルを開くべきではありません。ファイルが存在する場所をNginxに伝え、ファイルを開いて提供するだけです。

適切なヘッダーを設定した後、空の応答を返したいだけだと思います

return HttpResponse('', mimetype=contenttype)

PHP では、次のようにして Nginx アクセル リダイレクトをセットアップします。

//Set content type and caching headers
//...
header("X-Accel-Redirect: ".$filenameToProxy);
exit(0);

つまり、ヘッダーを設定した直後に終了します。

継続する 404 問題については、Nginx conf にエラーがある可能性がありますが、確認のために残りを投稿する必要があります。外部 URL は次のようになります。

static_files/downloads/protected-test/(?P<filename>.+)$

これは以下で照合されます:

location ~ ^.*/protected-test/ {
    alias /<path-to-my-protected-files-on-server>/;
    internal;
}

404を与えます。

protected-test外部 URL と内部 URL の両方で同じ単語を使用する必要はありません (そして非常に混乱します) 。そうしないことをお勧めします。つまり、外部 URL を次のようにします。

/static_files/downloads/(?P<filename>.+)$

次に、内部ロケーション ブロックを次のようにします。

location ~ ^/protected-test {
    alias /<path-to-my-protected-files-on-server>;
    internal;
}

次に、x-accel-redirect ヘッダーをセットアップするときに、2 つの間で切り替えます。

external_path = "/static_files/downloads";
nginx_path = "/protected-test";
filenameToProxy = str_replace(external_path, nginx_path, full_path);
header("X-Accel-Redirect: ".$filenameToProxy);

protected-testリクエストの両側に単語を配置するのではなく。

于 2013-04-19T22:17:31.837 に答える