2012-06-27 11 views
5

Bu bellek kullanıyor çünkü bu read() işlemden gerçekten korkuyorum. Örneğin, kimse 1gb dosya yükleyerek sunucumu DDoS yapabilir, doğru mu?Yüklenen dosyanın boyutlarını toplu halde güvenli bir şekilde nasıl kontrol edilir?

name = request.forms.get('name') 
data = request.files.get('data') 
if name and data.file: 
    raw = data.file.read() # This is dangerous for big files 
    filename = data.filename 
    return "Hello %s! You uploaded %s (%d bytes)." % (name, filename, len(raw)) 

Yüklenen dosya boyutunu almak için güvenli bir çözüm var mı? Bir tahmin dosya boyutunu dosya sisteminden almak olacaktır; request.files.get('data') muhtemelen geçici bir yerde temp dosyasında saklanır?

+0

Apache gibi bir şey altında wsgi ile şişe çalıştırıyorsanız, apache yükleme boyutlarını sınırlayabilir. – jordanm

+1

Şişe mağazaları, bunlardan herhangi birine erişir erişmez, geçici dosyalardaki (veya yeterince küçükse ByteIO arabellekleri) ve yüklenen tüm dosyaları kaydeder. Sunucu, tüm işi yapmadan önce yükleme boyutunu kısıtlamak istiyorsanız, request.content_length için kontrol edin. Her şeyin belleğe uyduğundan emin olmak istiyorsanız, yüklenen dosyaları yanıtında pyfunc tarafından açıklandığı gibi daha küçük parçalarda okuyun/kopyalayın. – defnull

cevap

2

Veri parçalarını tek tek okuyabiliyor musunuz, kontrol edebilir misiniz?

Eğer bu mümkün değilse: Bu mümkün değilse

name = request.forms.get('name') 
data = request.files.get('data') 
raw = "" 
if name and data.file: 
    while True: 
     datachunk = data.file.read(1024) 
     if not datachunk: 
      break 
     raw = raw + datachunk 

    filename = data.filename 
    return "Hello %s! You uploaded %s (%d bytes)." % (name, filename, len(raw)) 

, o zaman da bir dosya okumak istediğiniz kadar büyük bir izleme mekanizması eklemek gerekir ve aşılması durumunda bu işlemi iptal.

Bu, DDOS'un olası yollarından sadece birini nasıl çözer?

+0

Kodunuzu düzeltebilir misiniz? size = kaldırılmalıdır. Bu TypeError üretir: read() hiçbir anahtar kelime bağımsız değişkenleri alır, eğer sadece 1024 belirtilen çalışırsa – holms

+0

@ omsms: Düzeltme için teşekkürler. Geçecek bir argüman olacağını düşündüm. Kod bakmayı deneyin, başka bir şey olarak adlandırılabilir. – pyfunc

-3

Bu ilginç bir sorudur. Normalde, dosya nesnesindeki istatistikleri alırsınız veya boyutu almak için os.path dosyasını kullanırsınız. This question daha önce ele alınmıştır.

Ama bunu yüklenmesi zaman harcamak önce sunucudan istemci tarafı dosya boyutunu anlatmak konusunda soruyor. Bunu yapmanın en iyi yolunun with JavaScript olduğunu düşünüyorum. This question, BottlePy uygulamanıza bazı JavaScript kodunu nasıl alacağınız konusunda size yardımcı olabilir.

Eğer sunucu kodu alabildiği şekilde kullanın JavaScript girişinizi doğrulamak için dosya sınırlar içinde olduğunu. Bunu anladıktan sonra, BottlePy kişilerine doğrudan BaseRequest.files desteğine destek eklemelerini rica ediyorum.

+0

'Ancak, yükleme işlemi için zaman harcamadan önce istemci tarafındaki dosya boyutunun sunucudan nasıl anlatılacağını soruyorsunuz. Bunu yazmayı hatırlamıyorum. Bu alanı, geçerliliği geçiren boyuta değiştirebilir ve 1gb dosyasını iletebilirsiniz. – holms

+0

Oh, belki de yanlış anladım. Dosya boyutunu DDOS'a maruz bırakmadan almak istediğini sanıyordum ... belki de orada bir şey olduğunu düşünüyordum. Bunu yapmanın tek yolu, aslında yüklemeden önce dosya boyutunu kontrol etmektir, aksi halde bu nokta ne olur. Büyük dosya zaten yüklendi, bu yüzden DDOS'u engellemediniz. Diğer seçenek, pyfunc'un önerdiği gibidir, ancak bazı sınırlardan çıkmak için bir kontrol ekliyorsunuz. Son seçenek önerdiğiniz ve geçici dosyadaki istatistikleri aldığınızdır. – ChipJust

+0

@holms "Bu alanı, geçerliliği geçiren boyuta değiştirebilir ve 1gb dosyasını iletirseniz ne olur?" Ben senin amacını anlamıyorum. İstemci tarafı doğrulama kodunu kontrol edersiniz, böylece istediğiniz kadar büyüklüğe izin verebilirsiniz ... – ChipJust

İlgili konular