2008-11-11 14 views
11

Senden Webbrowser die Dateigröße im HTTP-Header beim Hochladen einer Datei auf den Server? Und wenn das der Fall ist, ist es dann möglich, die Datei nur durch Lesen der Kopfzeile abzulehnen und nicht auf den Abschluss des gesamten Upload-Prozesses zu warten?Größe der hochgeladenen Datei

Antwort

11

http://www.faqs.org/rfcs/rfc1867.html

HTTP-Clients sind ermutigt Content-Length für die gesamte Datei-Eingabe zu liefern, so dass ein ausgelasteten Server, wenn die vorgeschlagene Dateidaten zu groß erkennen könnte, ist maßen

verarbeitet zu werden

Die Inhaltslänge ist jedoch nicht erforderlich, Sie können sich also nicht darauf verlassen. Ein Angreifer kann auch eine falsche Inhaltslänge fälschen.

Zum Lesen der Datei Inhalt ist die einzige zuverlässige Möglichkeit. Wenn die Inhaltslänge jedoch vorhanden und zu groß ist, wäre es vernünftig, die Verbindung zu schließen.

Auch der Inhalt wird als Multipart gesendet, so dass die meisten modernen Frameworks es zuerst decodieren. Das bedeutet, dass Sie den Datei-Byte-Stream erst dann erhalten, wenn das Framework fertig ist, was bedeuten kann, "bis die gesamte Datei hochgeladen wurde".

1
  1. Ich bin mir nicht sicher, aber Sie sollten nicht wirklich etwas im Header gesandt vertrauen, da es vom Benutzer gefälscht werden könnte.

  2. Es hängt davon ab, wie der Server funktioniert. Zum Beispiel in PHP wird Ihr Skript nicht ausgeführt, bis der Datei-Upload abgeschlossen ist, so dass dies nicht möglich wäre.

2

BEARBEITEN: Bevor Sie zu weit gehen, sollten Sie diese andere Antwort überprüfen, die sich auf die Apache-Konfiguration stützt: Using jQuery, Restricting File Size Before Uploading. Die folgende Beschreibung ist nur nützlich, wenn Sie noch mehr benutzerdefinierte Feedbacks benötigen.

Ja, Sie können einige Informationen im Voraus erhalten, bevor Sie das Hochladen der gesamten Datei zulassen.

Hier ist ein Beispiel von Kopf aus einem Formular mit dem enctype="multipart/form-data" Attribute kommen:

POST/HTTP/1.1 
Host: 127.0.0.1:8000 
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.3) Gecko/2008092414 Firefox/3.0.3 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-us,en;q=0.7,fr-be;q=0.3 
Accept-Encoding: gzip,deflate 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 
Keep-Alive: 300 
Connection: keep-alive 
Content-Type: multipart/form-data; boundary=---------------------------886261531333586100294758961 
Content-Length: 135361 

-----------------------------886261531333586100294758961 
Content-Disposition: form-data; name=""; filename="IMG_1132.jpg" 
Content-Type: image/jpeg 

(data starts here and ends with -----------------------------886261531333586100294758961) 

Sie haben den Content-Length im Header, und zusätzlich gibt es den Content-Type im Header der Datei Teils (Jede Datei hat ihren eigenen Header, was der Zweck der mehrteiligen Codierung ist). Beachten Sie, dass es die Verantwortung des Browsers ist, einen relevanten Inhaltstyp durch Erraten des Dateityps festzulegen. Sie können es nicht garantieren, aber es sollte ziemlich zuverlässig sein für eine frühe Zurückweisung (Sie sollten jedoch die ganze Datei überprüfen, wenn sie vollständig verfügbar ist).

Jetzt gibt es eine Frage. Ich habe Bilddateien so gefiltert, nicht auf die Größe, sondern auf den Inhaltstyp; aber wie Sie die Anfrage so schnell wie möglich stoppen möchten, das gleiche Problem entsteht: der Browser erhält nur Ihre Antwort, sobald die gesamte Anfrage gesendet wird, einschließlich Formularinhalt und damit hochgeladenen Dateien.

Wenn Sie den bereitgestellten Inhalt nicht möchten und den Upload stoppen, haben Sie keine andere Wahl, als den Socket brutal zu schließen. Der Benutzer sieht nur eine verwirrende Nachricht "Verbindung zurückgesetzt durch Peer". Und das ist scheiße, aber es ist von Design.

So möchten Sie diese Methode nur in Fällen von Hintergrund asynchron Kontrollen verwenden (mit einem Timer, der das Dateifeld überprüft). Also musste ich diesen Hack:

  • ich Jquery verwenden, mir zu sagen, ob die Datei Feld
  • Wenn eine neue Datei gewählt wird, deaktivieren alle anderen Dateifelder auf der gleichen Form bekommen nur, dass man sich geändert hat .
  • Senden Sie die Datei asynchron (jQuery kann es für Sie tun, es verwendet einen versteckten Rahmen)
  • Server-Seite, überprüfen Sie die Kopfzeile (Content-Länge, Content-Typ, ...), schneiden Sie die Verbindung so bald wie du hast, was du brauchst.
  • eine Session-Variable telling Gesetzt, wenn die Datei OK war oder nicht.
  • -Client-Seite, wie die Datei in einen Rahmen hochgeladen bekommt man nicht einmal jede Art von Rückmeldung, wenn die Verbindung geschlossen ist. Ihre einzige Alternative ist ein Timer.
  • Client-side, ein Timer fragt der Server einen Status für die hochgeladene Datei zu erhalten. Serverseitig haben Sie diese Sitzungsvariable eingestellt und senden sie an den Browser zurück.
  • Der Client hat den Statuscode; rendern Sie es in Ihr Formular: Fehlermeldung, grünes Häkchen/rotes X, was auch immer. Setzen Sie das Dateifeld zurück oder deaktivieren Sie das Formular, Sie entscheiden. Vergessen Sie nicht, andere Dateifelder erneut zu aktivieren.

ziemlich chaotisch, nicht wahr? Wenn einer von euch eine bessere Alternative hat, bin ich ganz Ohr.

Verwandte Themen