2015-02-02 15 views
13

Çevremde arama yaptım ve anlayabildiğim kadarıyla POST form istekleri zaten 10MB (http://golang.org/src/net/http/request.go#L721) ile sınırlı. Benim ServeHTTP yönteminde bu azaltılması konusunda gitmek için olsaydıGolang kullanırken formların büyüklüğünü (daha fazla) sınırlaması tavsiye edilir mi?

, bunu düzgün yapmak için nasıl emin değilim. Bunun gibi bir şey deneyebilirim:

r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize) 
err := r.ParseForm() 
if err != nil { 
    //redirect to some error page 
    return 
} 
Ancak hataya geri dönersek bağlantıyı da kapatır mı? Her şeyi okumayı nasıl engellerdim? Bunu buldum: https://stackoverflow.com/a/26393261/2202497, ama ne olursa, eğer içerik uzunluğu ayarlanmamışsa ve okunmanın ortasında, dosyanın çok büyük olduğunu anlıyorum.

benim sunucunun kaynaklarını hogging Bir kişinin önlemeye yönelik bir güvenlik önlemi olarak bu kullanıyorum.

+1

Teklif verme şekliniz iyi görünüyor. Her şeyi okumayacaksınız ya da stdlib'in 10MB sınırı da etkisiz olacak. İçerik Uzunluğu olmayan büyük bir POST, çoğu tarayıcı/kullanıcı aracısı tarafından oluşturulmayacak ve istek üzerine askıya alınması, bunun gerçekleşmesi durumunda makul bir yanıttır. – twotwotwo

+0

Bence bu erken bir optimizasyon. Olağandışı bir trafik aldığınızı fark edinceye kadar, mümkün olduğunca basit bir şekilde bırakmanız gerekir.Tamamlamanız gereken başka öncelikli görevleriniz olduğundan eminim. : P – Populus

+0

@Populus Farkettim. Şu an için fazla endişelenmiyorum. Yine de soruya devam edeceğim. – John

cevap

22

istek gövdesinin boyutunu sınırlamak için doğru yolu önerdiği gibi yapmaktır:

r.Body = http.MaxBytesReader(w, r.Body, MaxFileSize) 
err := r.ParseForm() 
if err != nil { 
// redirect or set error status code. 
return 
} 

MaxBytesReader sınırına ulaşıldığında bir flag on the response ayarlar. Bu bayrak ayarlandığında, sunucu istek gövdesinin kalanını okumaz ve sunucu işleyiciden geri döndüğünde bağlantıyı kapatır.

Kötü niyetli istemciler hakkında endişeleriniz varsa, Server.ReadTimeout, Server.WriteTimeout ve muhtemelen Server.MaxHeaderBytes ayarlamalısınız.

sen, sonra işleyicileri tümü için istek vücut sınırını ayarlamak kök işleyicisi için temsilci seçme önce sınırlayan bir işleyicisi ile kök işleyicisi sarmak isterseniz: çağrılırken

type maxBytesHandler struct { 
    h http.Handler 
    n int64 
} 

func (h *maxBytesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 
    r.Body = http.MaxBytesReader(w, r.Body, h.n) 
    h.h.ServeHTTP(w, r) 
} 

Wrap kök işleyicisi ListenAndServe:

log.Fatal(http.ListenAndServe(":8080", &maxBytesHandler{h:mux, n:4096)) 

veya sunucusunu yapılandırma:

s := http.Server{ 
    Addr: ":8080", 
    Handler: &maxBytesReader{h:mux, n:4096}, 
} 
log.Fatal(s.ListenAndServe()) 

Başka bir cevapta önerildiği gibi bir yamaya gerek yoktur. MaxBytesReader, istek gövdesinin boyutunu sınırlamanın resmi yoludur.

0

Düzenleme: Diğerleri MaxByteReader atıf olarak desteklenen bir yoldur. Varsayılan okuyucunun, maksimum byte okuyucusu için onaylamadan sonra limitreader olması ilginçtir.

Git kaynak koduna yama gönderin ve onu yapılandırılabilir olun! Sonuçta açık kaynaklı bir proje ile çalışıyorsunuz. Http.Request'e bir setter eklemek ve bunun için bazı birim testleri muhtemelen sadece 20 dakikalık bir iştir. Burada sabit kodlanmış bir değere sahip olmak biraz aksak, geri vermek ve düzeltmek :). Gerçekten bu geçersiz gerekiyorsa

Sen elbette kendi ParseForm(r *http.Request) yöntemi uygulayabilir. Go aslında BSD, bu yüzden kütüphaneyi ParseForm'a yapıştırın ve limiti değiştirebilirsin, ama bu biraz çirkin değil mi?