2010-09-29 45 views
42

我似乎得到一個IOError:請求數據讀取錯誤很多,當我做Ajax上傳。例如,每5個文件中至少有3個文件上傳錯誤。IOError:請求數據讀取錯誤

其他人似乎也有同樣的問題。例如。

其他一些意見:

  • 這絕對不是我的Internet連接或瀏覽器的問題。似乎正在所有瀏覽器上發生chrome/FF/opera。

  • 我跑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 上清醒。

  • 這也不是文件大小。我有時可以上傳1個以上的MB文件,但在180 Kb文件上失敗。


回溯

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

回答

7

,你可能會認爲,這是沒有Django的錯誤。

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

有錯誤我自己(但IE Ajax請求而已,沒有任何文件的上傳,只是後數據)。

將增加一個完整的答案,如果我找到如何解決這個問題。

+0

我有完全相同的問題,但我無法修復它。 – Natim 2010-11-05 15:42:07

+0

我也有同樣的問題。這是一個非常小的ajax發佈請求。這裏是一個長長的線程在wsgi列表中:http://osdir.com/ml/django-developers/2011-02/msg00046.html – neves 2011-02-16 03:20:15

+2

希望你能給我們一些提示。 – vmassuchetto 2011-08-02 18:56:00

0

這個問題已經打開了很長時間,並且與較低級別的庫有關。我正在使用boto將文件上傳到S3。我發現的臨時權宜之計是添加一個明確的HTTP套接字超時時間爲10秒。之後我還沒有看到錯誤。您可以通過在服務器上創建一個boto配置來實現這一點:

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

此外請確保該文件可被應用程序讀取。 查看原來的谷歌羣組:https://groups.google.com/forum/#!topic/boto-users/iWtvuECAcn4

13

我也有這個例外。在Apache的錯誤日誌文件我看到這一點:

[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 

版本:

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) 

首先我很困惑,因爲最後一行「未能數據」不適合於Django的代碼「加載發佈數據「。但我想django想寫一個錯誤頁面給客戶端。但客戶端已經取消了tcp連接。現在http 500頁面不能寫入客戶端。

客戶端斷開發送請求後,並獲得響應之前:

  • 用戶關閉瀏覽器或導航到另一頁。
  • 用戶按下了重新加載按鈕。

我看到這個只有POST-請求(不是GET)。如果使用POST,Web服務器至少讀取兩次:首先獲取標題,第二次獲取數據。第二次讀取失敗。

這是很容易複製:

插入一些代碼的第一個訪問request.POST之前,它等待情況發生(當然,沒有中間件time.sleep之前訪問request.POST()):

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

現在做一個大的POST(例如文件上傳)。我不知道Apache緩衝區大小。但是5 MB應該足夠了。當瀏覽器顯示沙漏時,瀏覽到其他頁面。瀏覽器將取消該請求,並且該異常應該在日誌文件中。

這是我的中間件,因爲我不想讓我們的日誌文件上面回溯:

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

我很難嘗試重現您的中間件。我可以註釋掉'if isinstance(...):'條件,然後導致視圖代碼中出現錯誤,並且它會起作用。當我重現IOError時,這個中間件似乎沒有做任何事情:\ – EMiller 2012-02-17 20:14:48

+0

更新:我發現,視圖代碼的行爲就好像上傳的文件沒有被給出,並且只是響應200顯示驗證錯誤消息。 process_exception從不會觸發。 這裏的建議是正確的方法是在日誌記錄層進行篩選:https://code.djangoproject.com/ticket/10046#comment:20 – EMiller 2012-02-17 21:09:58

3

從線程以這樣的:Getting rid of Django IOErrors

擴展由@dlowe爲可能的解決方案Django的1.3,打壓的IOError的關注,我們可以寫出完整的工作示例:

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

通用/ 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

當Content-Type頭被錯誤地設置爲應用程序/ JSON我們看到在上傳到Django的REST框架此錯誤。該帖子實際上是多部分表單數據。當我們刪除不正確的內容類型標題時,錯誤停止。

0

我確認我的網站時,Win8的機器上用IE瀏覽器10.當我從IE測試文件上傳上傳了stucked在1%後+/- 1分鐘,我得到了在服務器日誌的錯誤得到這個錯誤。我剛發現它是由TrendMicro補充引起的。一旦我禁用補碼,上傳發生沒有任何問題。

4

最近發生在我身上。我正在使用django-ajax-uploader,小文件正在成功上傳,但大文件例如使用IOError: request data read error打破100MB。

我檢查了我的Apache配置,發現這些設置RequestReadTimeout header=90 body=90這意味着Allow 90 seconds to receive the request including the headers and 90 seconds for receiving the request body

文件被接收以塊的形式在後臺,這意味着如果文件大小大90秒是不夠的,某些上傳。那麼如何確定請求的最佳值(秒)呢?

所以我已經使用這個設置:

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

定義MinRate解決了這個問題對我來說。上述設置狀態是:如果接收到的數據

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

當客戶端被連續地發送數據(AJAX上傳)是有意義的自動增加超時。有關RequestReadTimeout的更多信息/變體可以找到here

相關問題