42 Stimmen

IOError: Fehler beim Lesen der Anforderungsdaten

Ich scheine häufig einen IOError zu bekommen: Anforderungsdatenlesefehler, wenn ich einen Ajax-Upload mache. Zum Beispiel tritt bei mindestens 3 von 5 Datei-Uploads ein Fehler auf.

Andere Leute scheinen dasselbe Problem gehabt zu haben. z.B.

Einige andere Beobachtungen:

  • Es liegt definitiv nicht an meiner Internetverbindung oder einem Browserproblem. Es scheint in allen Browsern chrome/FF/opera zu passieren.

  • Ich verwende Django 1.1.1 Apache/2.2.14 (Ubuntu) mod_ssl/2.2.14 OpenSSL/0.9.8k mod_wsgi/2.8 Python/2.6.5 auf Lucid.

  • Es liegt auch nicht an der Dateigröße. Manchmal kann ich 1+ MB Dateien hochladen, aber bei 180 KB Dateien scheitern.


Aufrufliste

Aufrufliste (letzter Aufruf zuerst):

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/core/handlers/base.py", Zeile 98, in get_response
    response = middleware_method(request, e)

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/core/handlers/base.py", Zeile 92, in get_response
    response = callback(request, *callback_args, **callback_kwargs)

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/contrib/auth/decorators.py", Zeile 78, in __call__
    return self.view_func(request, *args, **kwargs)

  Datei "/home/ubuntu/webapps/anonymous_app/app/do_work/views/__init__.py", Zeile 391, in some_form_ajax_upload
    f = request.FILES.get('file_upload')

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/core/handlers/wsgi.py", Zeile 187, in _get_files
    self._load_post_and_files()

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/core/handlers/wsgi.py", Zeile 137, in _load_post_and_files
    self._post, self._files = self.parse_file_upload(self.META, self.environ['wsgi.input'])

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/__init__.py", Zeile 124, in parse_file_upload
    return parser.parse()

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 133, in parse
    for item_type, meta_data, field_stream in Parser(stream, self._boundary):

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 606, in __iter__
    for sub_stream in boundarystream:

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 420, in next
    return LazyStream(BoundaryIter(self._stream, self._boundary))

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 446, in __init__
    unused_char = self._stream.read(1)

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 299, in read
    out = ''.join(parts())

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 292, in parts
    chunk = self.next()

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 314, in next
    output = self._producer.next()

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 375, in next
    data = self.flo.read(self.chunk_size)

  Datei "/home/ubuntu/.virtualenvs/anonymous_app/lib/python2.6/site-packages/django/http/multipartparser.py", Zeile 405, in read
    return self._file.read(num_bytes)

IOError: Anforderungsdatenlesefehler

,
POST:,
COOKIES:{'__utma': '168279989.1688771210.1285773436.1285773436.1285773436.1',
 '__utmb': '168279989.20.10.1285773436',
 '__utmc': '168279989',
 '__utmz': '168279989.1285773436.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
 'beta': 'True',
 'sessionid': 'b1ecf92f2bba13e1885d07803e10aa03',
 'timezone_offset': '-330'},
META:{'CONTENT_LENGTH': '188575',
 'CONTENT_TYPE': 'multipart/form-data; boundary=---------------------------57602381214905740261171925981',
 'DOCUMENT_ROOT': '/htdocs',
 'GATEWAY_INTERFACE': 'CGI/1.1',
 'HTTPS': '1',
 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
 'HTTP_ACCEPT_CHARSET': 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
 'HTTP_ACCEPT_ENCODING': 'gzip,deflate',
 'HTTP_ACCEPT_LANGUAGE': 'en-us,en;q=0.5',
 'HTTP_CONNECTION': 'keep-alive',
 'HTTP_COOKIE': 'beta=True; __utma=168279989.1688771210.1285773436.1285773436.1285773436.1; __utmb=168279989.20.10.1285773436; __utmc=168279989; __utmz=168279989.1285773436.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); sessionid=b1ecf92f2bba13e1885d07803e10aa03; timezone_offset=-330',
 'HTTP_HOST': 'xxxxxx.compute-1.amazonaws.com',
 'HTTP_KEEP_ALIVE': '115',
 'HTTP_REFERER': 'https://ec2-184-72-79-96.compute-1.amazonaws.com/do-my-somees/enter/some-documents/',
 'HTTP_USER_AGENT': 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.10) Gecko/20100915 Ubuntu/10.04 (lucid) Firefox/3.6.10',
 'PATH': '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/X11R6/bin',
 'PATH_INFO': u'/do-my-somees/enter/some-documents/ajax-upload/Other-some-Document/',
 'PATH_TRANSLATED': '/home/ubuntu/webapps/anonymous_app/settings/apache/qa.wsgi.py/do-my-somees/enter/some-documents/ajax-upload/Other-some-Document/',
 'QUERY_STRING': '',
 'REMOTE_ADDR': '',
 'REMOTE_PORT': '15561',
 'REQUEST_METHOD': 'POST',
 'REQUEST_URI': '/do-my-somees/enter/some-documents/ajax-upload/Other-some-Document/',
 'SCRIPT_FILENAME': '/home/ubuntu/webapps/anonymous_app/settings/apache/qa.wsgi.py',
 'SCRIPT_NAME': u'',
 'SERVER_ADDR': '10.196.142.182',
 'SERVER_ADMIN': 'dev@anonymous_app.com',
 'SERVER_NAME': 'ec2-184-72-79-96.compute-1.amazonaws.com',
 'SERVER_PORT': '443',
 'SERVER_PROTOCOL': 'HTTP/1.1',
 'SERVER_SIGNATURE': 'Apache/2.2.14 (Ubuntu) Server at ec2-184-72-79-96.compute-1.amazonaws.com Port 443\n',
 'SERVER_SOFTWARE': 'Apache/2.2.14 (Ubuntu)',
 'SSL_TLS_SNI': 'ec2-184-72-79-96.compute-1.amazonaws.com',
 'mod_wsgi.application_group': 'qa.anonymous_app.com|',
 'mod_wsgi.callable_object': 'application',
 'mod_wsgi.listener_host': '',
 'mod_wsgi.listener_port': '443',
 'mod_wsgi.process_group': '',
 'mod_wsgi.reload_mechanism': '0',
 'mod_wsgi.script_reloading': '1',
 'mod_wsgi.version': (2, 8),
 'wsgi.errors': ,
 'wsgi.file_wrapper': ,
 'wsgi.input': ,
 'wsgi.multiprocess': True,
 'wsgi.multithread': False,
 'wsgi.run_once': False,
 'wsgi.url_scheme': 'https',
 'wsgi.version': (1, 0)}>

13voto

guettli Punkte 23426

Ich erhalte auch diese Ausnahme. Im Apache-Fehlerprotokoll sehe ich Folgendes:

[Wed Aug 17 08:30:45 2011] [error] [client 10.114.48.206] (70014)Ende der Datei gefunden: mod_wsgi (pid=9722): Kann Schüttgutleitung für Anforderung nicht erhalten., referer: https://egs-work/modwork/beleg/188074/edit/
[Wed Aug 17 08:30:45 2011] [error] [client 10.114.48.206] mod_wsgi (pid=3572): bei der Verarbeitung des WSGI-Skripts '/home/modwork_egs_p/modwork_egs/apache/django_wsgi.py' ist eine Ausnahme aufgetreten.
[Wed Aug 17 08:30:45 2011] [error] [client 10.114.48.206] IOError: Schreibvorgang fehlgeschlagen

Versionen:

apache2-prefork-2.2.15-3.7.x86_64
apache2-mod_wsgi-3.3-1.8.x86_64 WSGIDaemonProcess mit Threads=1
mod_ssl/2.2.15
Linux egs-work 2.6.34.8-0.2-default #1 SMP 2011-04-06 18:11:26 +0200 x86_64 x86_64 x86_64 GNU/Linux
openSUSE 11.3 (x86_64)

Zuerst war ich verwirrt, weil die letzte Zeile "Schreibvorgang fehlgeschlagen" nicht zum Django-Code "Daten laden" passt. Aber ich vermute, dass Django eine Fehlerseite an den Client schreiben möchte. Aber der Client hat die TCP-Verbindung abgebrochen. Und jetzt kann die HTTP-500-Seite nicht an den Client geschrieben werden.

Der Client hat die Verbindung getrennt, nachdem er die Anforderung gesendet hat, aber bevor er die Antwort erhalten hat:

  • Der Benutzer hat den Browser geschlossen oder ist auf eine andere Seite navigiert.
  • Der Benutzer hat die Seite neu geladen.

Ich habe dies nur bei POST-Anfragen (nicht bei GET) gesehen. Wenn POST verwendet wird, liest der Webserver mindestens zweimal: Erstens, um die Header zu erhalten, und zweitens, um die Daten zu erhalten. Das zweite Lesen schlägt fehl.

Es ist einfach zu reproduzieren:

Fügen Sie einige Code ein, der vor dem ersten Zugriff auf request.POST wartet (stellen Sie sicher, dass kein Middleware vor time.sleep() auf request.POST zugreift):

def edit(request):
    import time
    time.sleep(3)
    #.....

Führen Sie nun einen großen POST durch (z. B. Datei-Upload) durch. Ich kenne die Puffergröße von Apache nicht. Aber 5 MB sollten ausreichen. Wenn der Browser den Sanduhrzeiger zeigt, navigieren Sie zu einer anderen Seite. Der Browser wird die Anfrage abbrechen, und die Ausnahme sollte im Protokoll sein.

Das ist mein Middleware, da ich den obigen Traceback nicht in unseren Protokolldateien haben möchte:

class HandleExceptionMiddleware:

    def process_exception(self, request, exception):
        if isinstance(exception, IOError) und 'Fehler beim Lesen von Anforderungsdaten' in unicode(exception):
            logging.info('%s %s: %s: Anforderung wurde vom Client abgebrochen.' % (
                    request.build_absolute_uri(), request.user, exception))
            return HttpResponseServerError()

8voto

fetzig Punkte 1598

Wie Sie vielleicht denken, handelt es sich nicht um einen Django-Fehler.

sehen Sie https://groups.google.com/group/django-users/browse_thread/thread/946936f69c012d96

habe den Fehler selbst (aber nur IE-Ajax-Anfragen, kein Datei-Upload, nur Postdaten).

wenn ich herausfinde, wie man das behebt, werde ich eine vollständige Antwort hinzufügen.

5voto

user2275915 Punkte 59

Wir sahen diesen Fehler beim Hochladen in das Django Rest Framework, wenn der Inhaltstyp-Header fälschlicherweise auf application/json gesetzt war. Der Beitrag war tatsächlich Mehrfachformulardaten. Die Fehler hörten auf, als wir den falschen Inhaltstyp-Header entfernten.

5voto

Aamir Rind Punkte 36855

Dies ist mir kürzlich passiert. Ich habe django-ajax-uploader verwendet und kleine Dateien wurden erfolgreich hochgeladen, aber große Dateien, z.B. 100 MB, brachen zwischendurch mit IOError: Anforderungsdatenlesefehler ab.

Ich habe meine Apache-Konfiguration überprüft und diese Einstellung gefunden RequestReadTimeout header=90 body=90, was bedeutet 90 Sekunden für den Empfang der Anforderung einschließlich der Header und 90 Sekunden für den Empfang des Anforderungskörpers zulassen.

Die Datei wird in Chunks auf der Backend-Seite empfangen, das bedeutet, wenn die Dateigröße groß ist, reichen 90 Sekunden für einige Uploads nicht aus. Wie also den besten Wert (Sekunden) für die Anfragen bestimmen?

Daher habe ich diese Einstellung verwendet:

RequestReadTimeout header=90,MinRate=500 body=90,MinRate=500

Das Definieren des MinRate hat das Problem für mich gelöst. Die obige Einstellung besagt:

Erlaube mindestens 90 Sekunden für den Empfang des Anforderungskörpers. Wenn der Client Daten sendet, erhöhe den Timeout um 1 Sekunde für jede empfangene 500 Bytes

Da der Client kontinuierlich Daten sendet (Ajax-Upload), macht es Sinn, den Timeout automatisch zu erhöhen, wenn Daten empfangen werden. Weitere Informationen/Varianten zum RequestReadTimeout finden sich hier.

4voto

Übernehmen aus dem Thread: Django IOErrors loswerden

Die mögliche Lösung von @dlowe für Django 1.3 erweitern, um das IOError zu unterdrücken, können wir das vollständige funktionierende Beispiel wie folgt schreiben:

settings.py

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'supress_unreadable_post': {
            '()': 'common.logging.SuppressUnreadablePost',
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'filters': ['supress_unreadable_post'],
        }
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'level': 'ERROR',
            'propagate': True,
        },
    }
}

common/logging.py

import sys, traceback

class SuppressUnreadablePost(object):
    def filter(self, record):
        _, exception, tb = sys.exc_info()
        if isinstance(exception, IOError):
            for _, _, function, _ in traceback.extract_tb(tb):
                if function == '_get_raw_post_data':
                    return False
        return True

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X