ユーザーがファイルをzipとしてダウンロードできる自作のWebベースのファイルシステムがあります。ただし、実稼働システムに存在しないローカル ボックスでの開発中に問題が見つかりました。
Linux では、これは問題ではありません (ローカルの開発ボックスは Windows システムです)。
次のコードがあります
algo = CipherType('AES-256', 'CBC')
decrypt = DecryptCipher(algo, cur_share.key[:32], cur_share.key[-16:])
file = open(settings.STORAGE_ROOT + 'f_' + str(cur_file.id), 'rb')
temp_file = open(temp_file_path, 'wb+')
data = file.read(settings.READ_SIZE)
while data:
dec_data = decrypt.update(data)
temp_file.write(dec_data)
data = file.read(settings.READ_SIZE)
# Takes a dump right here!
# error in cipher operation (wrong final block length)
final_data = decrypt.finish()
temp_file.write(final_data)
file.close()
temp_file.close()
上記のコードはファイルを開き、(現在のファイル共有のキーを使用して) ファイルを復号化し、一時的な場所に書き込みます (後で zip ファイルに詰め込みます)。
私の問題はfile = open(settings.STORAGE_ROOT + 'f_' + str(cur_file.id), 'rb')
オンラインです。ファイルを指定しないと、Windowsはバイナリファイルについてメトリックトンを気にするため'rb'
、データ読み取りループでファイルが読み取られません。ただし、何らかの理由で、私もそれに書き込んでいるためtemp_file
、ファイルの最後まで完全に読み取ることはありません... b の後に a + を追加しない限り'rb+'
。
コードをfile = open(settings.STORAGE_ROOT + 'f_' + str(cur_file.id), 'rb+')
すべて変更すると、必要に応じて機能し、コードはバイナリファイル全体を正常にスクレイピングして復号化します。プラスを追加しないと失敗し、ファイル全体を読み取ることができません...
コードの別のセクション (個々のファイルをダウンロードするため) を読み取ります (OS に関係なく問題なく動作します)。
algo = CipherType('AES-256', 'CBC')
decrypt = DecryptCipher(algo, cur_share.key[:32], cur_share.key[-16:])
file = open(settings.STORAGE_ROOT + 'f_' + str(cur_file.id), 'rb')
filename = smart_str(cur_file.name, errors='replace')
response = HttpResponse(mimetype='application/octet-stream')
response['Content-Disposition'] = 'attachment; filename="' + filename + '"'
data = file.read(settings.READ_SIZE)
while data:
dec_data = decrypt.update(data)
response.write(dec_data)
data = file.read(settings.READ_SIZE)
# no dumps to be taken when finishing up the decrypt process...
final_data = decrypt.finish()
temp_file.write(final_data)
file.close()
temp_file.close()
明確化
ファイル全体が読み取られなかったために、暗号化エラーが発生した可能性があります。たとえば、一度に64*1024
バイト単位で読み込む 500MB のファイルがあります。Windowsで指定しないb
と、ループを2回循環し、くだらないデータを返します(pythonは、バイナリファイルではなく文字列ファイルとやり取りしていると考えているため)。
指定するb
と、ファイルを完全に読み込むのに 10 ~ 15 秒かかりますが、それは正常に行われ、コードは正常に完了します。
ソースファイルから読み込むときに (最初の例のように) 同時に別のファイルに書き込んでいる場合、指定しないと、どちらがrb+
指定されていない場合と同じ動作が表示さb
れ、ファイルからいくつかのセグメントのみが読み取られます。ハンドルを閉じて先に進む前に、不完全なファイルになってしまい、復号化に失敗します。