查看文章 |
关于Webob无法支持flash文件上传问题的记录
2009-10-17 11:09
根据邮件列表中的回复加工 1. 提出问题: 使用webob在处理通过fancyupload上传的文件,发现会系统挂起,但只要先把request.body读出来就没有问题。因此在uliweb中,将原来使用的webob去除,改成了werkzeug来处理了。 2. qiangninghong的试验: 因为limodou反应的这个问题认为是cgi模块有bug导致的,所以很重要。今天晚上稍稍有点时间,写了一个测试程序来验证一下,但是发现似乎没有这样的情况? 测试代码在这里 http://code.google.com/p/hongqnlib/source/browse/ 就是照着 FancyUpload 的 Attach File demo 页面 ( http://digitarald.de/project/fancyupload/3-0/showcase/attach-a-file/ ) 翻译了一下。运行 server.py 后,访问 http://localhost:5002/ ,上传了几个文件,都没有出现挂住的情况啊? 难道是我的这个测试有什么问题?请 limodou 帮忙看看。 3. 我的试验: 我把你的程序改了一下:
1. 使用你的程序的确没有问题,使用我改的程序就有问题 2. 两个差别在于你在调用处理前使用了一个StaticURLParser,而我改后的程序是不使用它,在app中自已处理。这样的目的并不是使用StaticURLParser不行,而是这样的做法其实是在app处理前多了一层处理,那么这层处理会影响后面的处理,掩盖问题的发生。 3. 在我的例子中,只要把# logging.error( repr(request.body))这行的注释去了,程序就正常。 4. 原因就是,只要你想办法在执行request.POST['Filedata']之前执行了象request.body之类的代码,这样会引起对body的整个读取,这时读取是按Content-Length来处理的,并且会放在缓冲区中,因此后续的处理就是从这个缓冲区来的了,因此缓冲区最后有没有回车换行是没有关系的。而使用flash控件上传文件,文件体示例如下: ERROR:root:'------------ei4GI3ei4Ef1Ef1GI3ei4Ij5GI3GI3\r\nContent-Disposition: form-data; name="Filename"\r\n\r\na.c\r\n------------ei4GI3ei4Ef1Ef1GI3ei4Ij5GI3G I3\r\nContent-Disposition: form-data; name="Filedata"; filename="a.c"\r\nContent-Type: application/octet-stream\r\n\r\n#include <stdio.h>\r\n\r\n------------ei4 GI3ei4Ef1Ef1GI3ei4Ij5GI3GI3\r\nContent-Disposition: form-data; name="Upload"\r\n\r\nSubmit Query\r\n------------ei4GI3ei4Ef1Ef1GI3ei4Ij5GI3GI3--' 可以看到,最后是没有\r\n的。这不是浏览器的问题,是flash组件本身的问题,相关的flash的类本身的问题。但其实也不算一个问题,因为cgi的处理是基于multipart的boundary需要以\r\n结束这个假设,但这种假设在某些情况下有问题。相应的cgi的代码如下(从cgi.py中找到的703行):
因此前面的问题就是,如果不先执行request.body,则后面的request.POST['Filedata']会从流中进行读取,而不是缓冲区中,但flash正好又不返回\r\n,因此server在使用readline就停处了,造成挂起,进而引发浏览器的flash控件的超时。 而你的例子使用了StaticURLParser,可能会进行request.body的读取,所以掩盖了这个问题。当然它到底怎么做的,我没有继续深究。因此我改了你的程序,就是为了不让其它的因素干扰,问题就暴露出来了。 |
最近读者: