2010-09-29 15 views
42

Mi sembra di ottenere un errore IOEr: l'errore di lettura dei dati di richiesta è piuttosto elevato quando eseguo un caricamento Ajax. Ad esempio, su ogni 5 caricamenti di file si verificano errori al 3. 3.IOErrore: errore di lettura dati richiesta

Altre persone sembrano aver avuto lo stesso problema. Per esempio.

Alcune altre osservazioni:

  • E 'sicuramente non la mia connessione internet o un problema di browser. Sembra che stia succedendo su tutti i browser chrome/FF/opera.

  • Io corro 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 su Lucid.

  • Non è anche la dimensione del file. A volte riesco a caricare 1 o più file MB, ma non riesco su 180 Kb file.


Traceback

Traceback (most recent call last): 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

IOError: request data read error 


<WSGIRequest 
GET:<QueryDict: {}>, 
POST:<could not parse>, 
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': '[email protected]_app.com', 
'SERVER_NAME': 'ec2-184-72-79-96.compute-1.amazonaws.com', 
'SERVER_PORT': '443', 
'SERVER_PROTOCOL': 'HTTP/1.1', 
'SERVER_SIGNATURE': '<address>Apache/2.2.14 (Ubuntu) Server at ec2-184-72-79-96.compute-1.amazonaws.com Port 443</address>\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': <mod_wsgi.Log object at 0xb9456860>, 
'wsgi.file_wrapper': <built-in method file_wrapper of mod_wsgi.Adapter object at 0xb936a968>, 
'wsgi.input': <mod_wsgi.Input object at 0xb9720e30>, 
'wsgi.multiprocess': True, 
'wsgi.multithread': False, 
'wsgi.run_once': False, 
'wsgi.url_scheme': 'https', 
'wsgi.version': (1, 0)}> 

risposta

7

come si potrebbe pensare, questo non è un errore di Django.

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

hanno l'errore me stesso (ma le richieste Ajax IE soltanto, nessun caricamento di file, basta inviare dati).

aggiungerà una risposta completa se mai scoprire come risolvere questo problema.

+0

Ho lo stesso identico problema ma non ho potuto ancora risolverlo. – Natim

+0

Ho anche lo stesso problema. È una richiesta post-posta molto piccola. Ecco una lunga discussione nella lista wsgi: http://osdir.com/ml/django-developers/2011-02/msg00046.html – neves

+2

Spero che tu possa darci un po 'di luce. – vmassuchetto

0

Questo problema è stato aperto per un lungo periodo di tempo e ha qualcosa a che fare con le librerie di livello inferiore. Stavo usando boto per caricare file su S3. Un temporaneo stopgap che ho trovato è stato quello di aggiungere un timeout socket HTTP esplicito di 10 secondi. Dopo non ho visto l'errore. Si può fare con la creazione di una configurazione boto sul server:

#/etc/boto.cfg 
[Boto] 
http_socket_timeout=10 

anche assicurarsi che il file è leggibile dal app. Vedere il mio post originale su google group: https://groups.google.com/forum/#!topic/boto-users/iWtvuECAcn4

13

Anche questa eccezione. Nella errore di file di log di Apache vedo questo:

[Wed Aug 17 08:30:45 2011] [error] [client 10.114.48.206] (70014)End of file found: mod_wsgi (pid=9722): Unable to get bucket brigade for request., 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): Exception occurred processing WSGI script '/home/modwork_egs_p/modwork_egs/apache/django_wsgi.py'. 
[Wed Aug 17 08:30:45 2011] [error] [client 10.114.48.206] IOError: failed to write data 

Versioni:

apache2-prefork-2.2.15-3.7.x86_64 
apache2-mod_wsgi-3.3-1.8.x86_64 WSGIDaemonProcess with 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) 

Prima ero confuso, perché l'ultima riga "non è riuscito a scrittura dei dati" non si adatta al codice Django " carica dati post ". Ma immagino che Django voglia scrivere una pagina di errore al client. Ma il client ha annullato la connessione TCP. E ora la pagina http 500 non può essere scritta sul client.

Il client disconnessi dopo l'invio della richiesta, e prima di ottenere la risposta:

  • l'utente ha chiuso il browser o navigato ad un'altra pagina.
  • L'utente ha premuto il pulsante di ricarica.

Ho visto questo solo con POST-Requests (non GET). Se viene utilizzato il POST, il server web ne legge almeno due volte: prima per ottenere le intestazioni, il secondo per ottenere i dati. La seconda lettura fallisce.

E 'facile da riprodurre:

inserire del codice che attende prima del primo accesso alla request.POST accade (essere sicuri, che nessun middleware accede request.POST prima time.sleep()):

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

Ora eseguire un grande POST (ad es. Caricamento di file). Non conosco la dimensione del buffer Apache. Ma 5 MB dovrebbero essere sufficienti. Quando il browser mostra la clessidra, vai a un'altra pagina. Il browser annullerà la richiesta e l'eccezione dovrebbe essere nel file di registro.

Questo è il mio Middleware, dal momento che non voglio ottenere il traceback sopra nei nostri file di log:

class HandleExceptionMiddleware: 

    def process_exception(self, request, exception): 
     if isinstance(exception, IOError) and 'request data read error' in unicode(exception): 
      logging.info('%s %s: %s: Request was canceled by the client.' % (
        request.build_absolute_uri(), request.user, exception)) 
      return HttpResponseServerError() 
+0

Ho difficoltà a provare a riprodurre il middleware. Posso commentare la condizione 'if isinstance (...):', quindi causare un errore nel codice vista e funziona bene. Quando riproduco l'errore IOError questo middleware non sembra fare nulla: \ – EMiller

+0

Aggiornamento: quello che ho trovato è che il codice della vista si comporta come se il file caricato non fosse mai stato dato, e risponde con 200 mostrando un messaggio di errore di validazione. L'eccezione process_exception non viene mai attivata. Il suggerimento è che l'approccio corretto consiste nel filtrare il livello di registrazione: https://code.djangoproject.com/ticket/10046#comment:20 – EMiller

3

Prendendo questo dal thread: Getting rid of Django IOErrors

Estendere la possibile soluzione per @dlowe per Django 1.3, per sopprimere l'IOError nella preoccupazione, possiamo scrivere l'esempio di lavoro completo come:

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, 
     }, 
    } 
} 

comune/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 
5

Stavamo vedendo questo errore su arrivi a Django Resto quadro quando l'intestazione Content-Type è stato erroneamente impostato su application/json. Il post era in realtà formato di dati multipart. Gli errori si sono interrotti quando abbiamo rimosso l'intestazione del tipo di contenuto errata.

0

ho ottenuto questo errore durante la convalida mio sito su una macchina Win8 con IE 10. Quando ho provato caricamento di file da IE l'upload è stato stucked il 1% e dopo +/- 1 minuto ho ottenuto l'errore sul log del server. Ho appena scoperto che è stato causato dal complemento TrendMicro. Una volta disabilitato il complemento, il caricamento è avvenuto senza problemi.

4

Questo mi è successo di recente. Stavo usando django-ajax-uploader e piccoli file si stavano caricando con successo ma file di grandi dimensioni, ad es. 100MB stavano rompendo in mezzo con IOError: request data read error.

Ho controllato la configurazione di Apache e ho trovato queste impostazioni RequestReadTimeout header=90 body=90 che significa Allow 90 seconds to receive the request including the headers and 90 seconds for receiving the request body.

Il file viene ricevuto in blocchi al backend, il che significa che se le dimensioni del file sono grandi, 90 secondi non sono sufficienti per alcuni caricamenti. Quindi, come determinare il valore migliore (secondi) per le richieste?

Così ho usato questa impostazione:

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

Definizione del MinRate risolve il problema per me. Gli stati di cui sopra impostazione che:

Allow at least 90 seconds to receive the request body. If the client sends data, increase the timeout by 1 second for every 500 bytes received

Come il client invia i dati in modo continuo (upload Ajax) ha senso per aumentare automaticamente il timeout se la ricezione dei dati. Ulteriori informazioni/variazioni su RequestReadTimeout possono essere trovate here.

Problemi correlati